同一应用程序中的Web应用程序和Web api身份验证

时间:2016-09-28 06:47:50

标签: asp.net-web-api owin auth0

我有一个网络应用程序MVC,使用auth0 owin常规基于Web应用程序cookie的身份验证。

此Web应用程序还具有在应用程序内部使用的webapis。但是,我需要从应用程序外部调用此webapis。所以我创建了一个restclient并试图在应用程序中实现jwtbearerauthentication(但是基于身份验证的cookie仍然存在)。

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

启动文件:

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

     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发布,以检查它是否有效..但重定向到登录页面。

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

1 个答案:

答案 0 :(得分:0)

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