【问题标题】:.NET Core Authorize attribute with external JWT authentication microservice?.NET Core Authorize 属性与外部 JWT 身份验证微服务?
【发布时间】:2016-11-02 10:21:19
【问题描述】:

所以我只是有点难以理解 .NET Core [Authorize] 属性。

我有一个正在运行的身份验证服务(比如说authapi.com),当提供有效的身份验证详细信息时,它将返回一个 JWT。当这个 JWT 被返回给它时,它会验证 JWT 并返回一条消息来表明这一点。

所以,我现在正在构建另一个 WebAPI(比如说genericapi.com),它需要对某些操作/控制器进行授权。想法是,JWT 将在请求的标头中传递给 genericapi,然后需要将它们传递给 authapi.com 以验证它们。

我尝试添加一个策略,但它很快变得令人费解,我不得不在所有内容上写 [Authorize(Policy="TokenValid")],而我宁愿只使用默认的 [Authorize] 这样做,因为所有授权都必须点击 authapi .

我将如何从标头获取 JWT 并将其作为 [Authorize] 的标准行为传递给 authapi

请记住:我不想对 genericapi 上的 JWT 做任何事情,所有身份验证都将由 authapi 处理。

【问题讨论】:

    标签: asp.net-web-api authorization asp.net-core jwt microservices


    【解决方案1】:

    据我了解,您不想在genericapi 中使用JwtBearerAuthentication。在这种情况下,您可以为genericapi 编写自定义身份验证中间件(将 jwt 发送到authapi 并对其进行验证,然后设置当前用户)。然后只需使用[Authorize] 属性。

    要编写自定义身份验证中间件,请查看https://stackoverflow.com/a/37415902/5426333

    但是如果可能的话,我不会走你的路。我会将JwtBearerAuthentication 用于genericapi。然后我会使用OnTokenValidated 事件来处理其他验证。

            app.UseJwtBearerAuthentication(new JwtBearerOptions()
            {
                Events = new JwtBearerEvents()
                {
                    OnTokenValidated = (context) =>
                    {
                        // send jwt to auth api
                        // validate it
                        if (!valid)
                        {
                            context.SkipToNextMiddleware();
                        }
                        return Task.FromResult(0);
                    }
                }
            });
    

    【讨论】:

    • 实际上,您已经大致了解了我所追求的,我想我误解了 JwtBearerAuthentication 的作用。我现在再试一次看看。
    【解决方案2】:

    您可以尝试自定义默认JwtBearerAuthenticationMiddleware,为其提供自定义ISecurityTokenValidator。您的用户身份将由中间件自动设置,您可以继续在 MVC 中使用 Authorize 属性:

    class MyTokenValidator : ISecurityTokenValidator
    {
        public string AuthenticationScheme { get; }
    
        public MyTokenValidator(string authenticationScheme)
        {
            AuthenticationScheme = authenticationScheme;
        }
    
        public bool CanValidateToken => true;
    
        public int MaximumTokenSizeInBytes
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }
    
        public bool CanReadToken(string securityToken) => true;
    
        public ClaimsPrincipal ValidateToken(string securityToken, TokenValidationParameters validationParameters, out SecurityToken validatedToken)
        {
            validatedToken = null;
    
            //your logic here
            var response = GetResponseFromMyAuthServer(securityToken);
            //assuming response will contain info about the user
    
            if(response == null || response.IsError)
                throw new SecurityTokenException("invalid");
    
            //create your identity by generating its claims
            var claims = new[]
            {
                new Claim(ClaimTypes.NameIdentifier, response.UserId),
                new Claim(ClaimTypes.Email, response.Email),
                new Claim(ClaimsIdentity.DefaultNameClaimType, response.UserName),
            };
    
            return new ClaimsPrincipal(new ClaimsIdentity(claims, AuthenticationScheme));
        }
    }
    

    在你的创业课上:

    var options = new JwtBearerOptions();
    options.SecurityTokenValidators.Clear();
    options.SecurityTokenValidators.Add(new MyTokenValidator(options.AuthenticationScheme));
    
    app.UseJwtBearerAuthentication(options);
    
    //the rest of your code here
    app.UseMvc();
    

    您可能需要进一步完善此方法,但这样您可以通过将所有验证委托给远程端点来实现您的需要。

    【讨论】:

      猜你喜欢
      • 2020-07-26
      • 2018-12-03
      • 1970-01-01
      • 2017-09-11
      • 2021-08-13
      • 2016-06-22
      • 2021-05-20
      • 2021-10-27
      • 2017-12-23
      相关资源
      最近更新 更多