同一应用程序中的Web应用程序和Web API身份验证 [英] Web app and web api authentication in same application

查看:119
本文介绍了同一应用程序中的Web应用程序和Web API身份验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Web应用程序MVC,在基于常规Web应用程序Cookie的身份验证中使用auth0.

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

此网络应用程序还具有在应用程序内部使用的webapis.但是我有一个从应用程序外部调用此webapi的要求.因此,我创建了一个restclient并尝试在应用程序中实现jwtbearerauthentication(但仍然存在基于身份验证的cookie).

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).

现在,当我从其他应用程序调用webapi时,它会验证承载令牌没有错误,但是由于基于cookie的身份验证,它会重定向到登录页面.

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.

启动文件:

 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文件:

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
        });
    }

当前从下面的代码创建jwt令牌,并在标题中使用postman进行发布,只是为了检查它是否有效..但是重定向到登录页面.

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);

推荐答案

我怀疑正在发生的事情是您对API的调用包含一个承载令牌,该令牌未通过验证(或者根本没有Authorize令牌),您的API控制器具有一个Authorize属性,由于该调用上没有有效的ClaimsPrincipal,因此该属性抛出401.Auth0AuthenticationProvider对此进行选择,并假定该调用是针对UI的,因此重定向以进行用户身份验证.您可能想在Oauth0Provider中添加一个替代,以捕获OnRedirectToIdP(或类似的东西),检查请求,如果是对API的请求,则自动进行进一步处理并返回未授权. 从您的API中删除所有[授权],然后查看其是否有效.另外,请确保您的启动不需要对所有控制器进行授权. 您可能要删除代码的authn部分(Cookie和Oauth2Provider),然后查看您是否要使用API​​.

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.

这篇关于同一应用程序中的Web应用程序和Web API身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆