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

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

问题描述

我有一个 Web 应用 MVC,使用 auth0 owin 基于常规 Web 应用 cookie 的身份验证.

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

此网络应用程序还具有在应用程序内部使用的 webapis.但是我需要从应用程序外部调用这个 webapis.所以我创建了一个 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 令牌并在标题中使用邮递员发布只是为了检查它是否有效..但重定向到登录页面.

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 的调用有一个未通过验证的承载令牌(或者根本没有授权令牌),您的 API 控制器有一个 Authorize 属性,由于调用中没有有效的 ClaimsPrincipal 会抛出 401.Auth0AuthenticationProvider 选择该属性并假定调用是对 UI 的,因此重定向以进行用户身份验证.您可能希望在 Oauth0Provider 中添加一个覆盖来捕获 OnRedirectToIdP(或类似的东西),检查请求,如果它是 API,则停止进一步处理并返回 Unauthorized.从您的 API 中删除任何 [Authorize],然后查看它是否有效.还要确保您的启动不需要对所有控制器进行授权.您可能想要删除代码的 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天全站免登陆