.NET Core HttpRequest中间件和AccessToken机制?

时间:2018-02-19 13:34:35

标签: .net-core jwt access-token asp.net-core-webapi

我对生成访问令牌并使用它感到困惑。访问令牌的生成应该放在Controller还是中间件?我是.NET Core的新手,所以如果有人向我解释,我将不胜感激。

2 个答案:

答案 0 :(得分:2)

首先生成访问令牌,刷新令牌等都应该在真实授权服务器中进行,以获取更多信息 http://authguidance.com

但是说即使我在我的应用程序中也生成了JWT令牌...... 这就是我在.net core 2.0中的表现。

在startup.cs中

ConfigureServices

            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;           


 }

如果您需要澄清代码,请告诉我。

答案 1 :(得分:0)

这是一个例子,它可以帮助您或者至少为您提供一个如何在深入了解情况的情况下如何引导您的工作的提示。但这不太安全,请阅读身份框架,这是推荐的方法。

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

例如(使用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中的令牌来确保它是同一个用户,并授予执行操作的权限。

祝你好运。