Web app and web api authentication in same application

断了今生、忘了曾经 提交于 2019-12-24 00:47:16

问题


I have a web app MVC,using auth0 owin regular web app cookie based authentication.

This web app also has webapis which is used internally in the application. However i have a requirement to call this webapis from outside the application. So i created a restclient and tried to implement jwtbearerauthentication in application (but cookie based on authentication still in place).

Now when i call the webapi from other application it validates the bearer token gives no error however it redirects to login page due to cookie based authentication.

startup file:

 public partial class Startup
{
    private IPlatform platform;
    public void ConfigureAuth(IAppBuilder app, IPlatform p, IContainer container)
    {
        platform = p;


        // Enable the application to use a cookie to store information for the signed in user
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/Account/Login"),
            ExpireTimeSpan = System.TimeSpan.FromDays(2),
            SlidingExpiration = true
        });

        // Use a cookie to temporarily store information about a user logging in with a third party login provider
        app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
        var provider = new Auth0.Owin.Auth0AuthenticationProvider
        {
            OnReturnEndpoint = (context) =>
            {
                // xsrf validation
                if (context.Request.Query["state"] != null && context.Request.Query["state"].Contains("xsrf="))
                {
                    var state = HttpUtility.ParseQueryString(context.Request.Query["state"]);
                    AntiForgery.Validate(context.Request.Cookies["__RequestVerificationToken"], state["xsrf"]);
                }

                return System.Threading.Tasks.Task.FromResult(0);
            },
            OnAuthenticated = (context) =>
            {
                var identity = context.Identity;
                //Add claims
                var authenticationManager = container.Resolve<IAuthenticationManager>();
                authenticationManager.AddClaims(identity);

                if (context.Request.Query["state"] != null)
                {
                    authenticationManager.AddReturnUrlInClaims(identity, context.Request.Query["state"]);
                }

                return System.Threading.Tasks.Task.FromResult(0);
            }
        };

        var issuer = "https://" + ConfigurationManager.AppSettings["auth0:Domain"] + "/";
        var audience = ConfigurationManager.AppSettings["auth0:ClientId"];
        var secret = TextEncodings.Base64.Encode(TextEncodings.Base64Url.Decode(ConfigurationManager.AppSettings["auth0:ClientSecret"]));
        app.UseJwtBearerAuthentication(
            new JwtBearerAuthenticationOptions
            {
                AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Active,
                AllowedAudiences = new[] { audience },
                IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[]
                {
                    new SymmetricKeyIssuerSecurityTokenProvider(issuer, secret)
                }
            });

        app.UseAuth0Authentication(
            clientId: platform.ServerRole.GetConfigurationSettingValue("auth0:ClientId"),
            clientSecret: platform.ServerRole.GetConfigurationSettingValue("auth0:ClientSecret"),
            domain: platform.ServerRole.GetConfigurationSettingValue("auth0:Domain"),
            provider: provider);
    }
}

webapiconfig file:

     public static void Register(HttpConfiguration config)
    {

        // Web API routes
        config.MapHttpAttributeRoutes();
        config.Routes.MapHttpRoute("DefaultApi", "api/{controller}/{id}", new {id = RouteParameter.Optional});
        config.Filters.Add(new AuthorizeAttribute());
        ODataConfig.Setup(config);

        var clientID = WebConfigurationManager.AppSettings["auth0:ClientId"];
        var clientSecret = WebConfigurationManager.AppSettings["auth0:ClientSecret"];

        config.MessageHandlers.Add(new JsonWebTokenValidationHandler()
        {
            Audience = clientID,
            SymmetricKey = clientSecret
        });
    }

Currently creating the jwt token from below code and posting using postman in header just to check if it works.. but redirects to login page.

  string token = JWT.Encode(payload, secretKey, JwsAlgorithm.HS256);

回答1:


I suspect what's happening is that your call to the API has a bearer token which fails validation (or there is no Authorize token at all), your API controller has an Authorize attribute, which, since there is no valid ClaimsPrincipal on the call throws 401. Auth0AuthenticationProvider picks that and assumes the call was to UI so redirects for user authentication. You may want to add an override in the Oauth0Provider to trap OnRedirectToIdP (or something like that), inspect the request and if it is to API, abot further handling and return Unauthorized. Remove any [Authorize] from your API and see whether it works then. Also make sure your startup does not require Authorize for all controllers. You may want to remove the authn part of your code (cookie and Oauth2Provider) and see whether you are getting to the API then.



来源:https://stackoverflow.com/questions/39739936/web-app-and-web-api-authentication-in-same-application

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!