代码之家  ›  专栏  ›  技术社区  ›  Tuğçe Arar

.NET核心HttpRequest中间件和AccessToken机制?

  •  1
  • Tuğçe Arar  · 技术社区  · 6 年前

    我真的对生成访问令牌并使用它感到困惑。访问令牌的生成应该放在控制器或中间件中?如果有人向我解释这一点,我将不胜感激。

    2 回复  |  直到 5 年前
        1
  •  2
  •   Navin    6 年前

    首先生成访问令牌、刷新令牌等都应该在 真实授权服务器 有关详细信息 http://authguidance.com

    但通过说,即使我在我的应用程序中也生成了JWT令牌。。。 我就是这样进来的。net core 2.0

    正在启动中。反恐精英

    配置服务

                var securityKey = "asdasdasdasdasdasddsda123123132123123";// your own key
            var key = Encoding.UTF8.GetBytes(securityKey);
    
            var signingKey = new SymmetricSecurityKey(key);
            var tokenValidationParameters = new TokenValidationParameters()
            {
                ValidAudiences = new string[]
                {
                    tokenSetting.Audience
                },
                ValidIssuers = new string[]
                {
                    tokenSetting.Issuer
                },
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = signingKey,
                ClockSkew= TimeSpan.Zero
            };
    
            services.AddAuthentication(options =>
            {
                options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
            })
    
            .AddJwtBearer(options =>
            {
                options.Events = new JwtBearerEvents
                {
                    OnAuthenticationFailed = context =>
                    {
                        context.Response.Headers.Add("x-tokenstatus-header", "fail");// may be not necessary for you
                        return Task.CompletedTask;
                    }
                };
                options.Audience = tokenSetting.Audience;
                options.RequireHttpsMetadata = tokenSetting.RequireHttpsMetadata;
                options.TokenValidationParameters = tokenValidationParameters;
            });
    

    并且在

    配置

            app.UseTokenProvider(); // This is my own middleware
            app.UseAuthentication();
            app.UseMvc();
    

    公共类TokenProviderMiddleware{..}

    public  Task Invoke(HttpContext context, IUserService userService)
            {
    
     if (!IsAuthenticationRequest(context.Request.Path, context.Request.Method)) {
                     return this._next(context);
                }
    
     var securityKey = "asdasdasdasdasdasddsda123123132123123";// your own key
            var key = Encoding.UTF8.GetBytes(securityKey);
    
            var signingKey = new SymmetricSecurityKey(key);
            var signingCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256);
    
      var claimsIdentity = new ClaimsIdentity(listClaims, "Custom");
    
            var securityTokenDescriptor = new SecurityTokenDescriptor()
            {
                Audience = this._tokenSettings.Audience,
                Issuer = this._tokenSettings.Issuer,
                Subject = claimsIdentity,
                SigningCredentials = signingCredentials,
                Expires = DateTime.UtcNow.AddMinutes(20),
    
            };
    
            var tokenHandler = new JwtSecurityTokenHandler();
            var plainToken = tokenHandler.CreateToken(securityTokenDescriptor);
            var signedAndEncodedToken = tokenHandler.WriteToken(plainToken);
    
    // signedAndEncodedToken => contains your token you can do send it as response or anything you want  
    
    }
    
    
    
    private bool IsAuthenticationRequest(string path, string method) {
    
        if (HttpMethods.IsPost(method) &&  path?.IndexOf("/api/login", StringComparison.OrdinalIgnoreCase) >= 0) {
            return true;
        }
        return false;           
    
    
     }
    

    如果您需要对代码进行澄清,请务必告诉我。。

        2
  •  0
  •   ARr0w    6 年前

    这是一个例子,它想帮助你,或者至少给你一个提示,告诉你如何用深入的概念来领导你的工作。但这不太安全,请阅读推荐的方法identity framework。

    您可以使您的访问令牌保持动态(从数据库中调用与请求源中发送的值相匹配的记录),也可以在中间件的Web中对某些令牌进行硬编码。配置文件。

    例如(访问令牌采用Db方法):

    db表定义

    Create table Tokens(
    id int identity(1,1) primary key,
    userId int,
    TokenValue varchar(max),
    IsActive bit
    )
    

    自定义模型:

    public Class Error
    {
      public string ErrMsg {get; set;}
    } 
    
    public Class ReturnData
    {
      public Error ErrorObj {get; set;}
      public string UserName {get; set;}
      public string AccessToken {get; set;}
    }
    public class User
    {
      public int UserId {get; set;}
      public string UserName {get; set;}
      public string Password {get; set;}
    }
    

    在Api控制器中:

    public ReturnData GetData(User Creds)
    {
       ReturnData Data = new ReturnData();
       string Pass = Decrypt(Creds.Password);
       int i = //Code here to get the middle-ware access token from db table token and update token 'IsActive from 0 to 1' from database. 0 = false, 1 = true
       if(i > 0)
       {
         Data.AccessToken = Encrypt(DbTokenValue);
         Data.UserName = Creds.UserName; 
    
       }
       else
       {
         Error err = new  Error();
         err.ErrMsg = "something happened";
         Data.ErrorObj = err; 
       }
        return Data;  
    }
    

    然后将此令牌用于其余API,通过比较db中的令牌来确保其用户相同,并授予执行操作的权限。

    祝你好运