何时调用控制器时分配的用户身份?

时间:2018-05-09 18:11:53

标签: c# asp.net-core jwt claims-based-identity

我正在我的控制器中调用一个方法并在其构造函数中命中一个断点。检查 User.Claims.First(...)会引发异常,经过仔细调查后发现 User null 。< / p>

这是有道理的,因为控制器无法知道谁是匿名用户调用它。然后我添加标题授权通过 Bearer xxx.yyy.zzz (Postman以及我的Angular应用程序)对其进行评估。令牌是正确的,因为篡改它会导致状态代码 401 Unauthorized

所以,我得出的结论是安全设置有效,策略行为正常(使用对应于缺少所述操作权限的用户的令牌进行调用)。

将令牌文本粘贴到 jwt.io 会提供有关声明的预期详细信息。因此,我得出结论,令牌应该是可读的并且可以解析为应用程序的库。

所以问题是这个。 用户如何实例化(何时,何地,基于什么)控制器?或者,如何谷歌它(我已经尝试了一段时间,但我意识到我在黑暗中笨拙地咆哮着随意的树木。)

令牌以下列方式配备声明。

Claim[] claims =
{
  new Claim(ClaimTypes.Expiration, TokenExpiration.ToString(), ClaimValueTypes.DateTime),
  new Claim(ClaimTypes.Name, userName, ClaimValueTypes.String),
  new Claim(ClaimTypes.Role, member.Privilege + "", ClaimValueTypes.Integer),
  new Claim(ClaimTypes.Version, "0.1", ClaimValueTypes.String),
  new Claim(ClaimTypes.Webpage, "xxx.azurewebsites.net", ClaimValueTypes.String),
  new Claim("NetworkId", member.Network.Id.ToString(), ClaimValueTypes.String),
  new Claim("MemberId", member.Id.ToString(), ClaimValueTypes.String),
  new Claim("Author", "yyy", ClaimValueTypes.String)
};
SymmetricSecurityKey key = new SymmetricSecurityKey(SecurityKey);
SigningCredentials credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

JwtSecurityToken token = new JwtSecurityToken(
  "xxx.azurewebsites.net",
  "xxx.azurewebsites.net",
  claims,
  DateTime.UtcNow,
  TokenExpiration,
  credentials);
string output = new JwtSecurityTokenHandler().WriteToken(token);

修改 启动的设置如下。

services.AddSingleton<IUtilityService, UtilityService>();
services.AddSingleton<IEmailService, EmailService>();
services.AddCors(_ => _.AddPolicy("Open policy", __ => __
  .AllowAnyOrigin()
  .AllowAnyHeader()
  .AllowAnyMethod()));
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
  .AddJwtBearer(_ =>
  {
    _.TokenValidationParameters = new TokenValidationParameters
    {
      ValidateIssuerSigningKey = true,
      ValidateAudience = false,
      ValidateIssuer = false,
      ValidateActor = true,
      ValidateLifetime = true,
      IssuerSigningKey = new SymmetricSecurityKey( ... )
    };
  });
  services.AddAuthorization(_ => _.AddPolicy("Common", __ => ... ));
  services.AddAuthorization(_ => _.AddPolicy("Super", __ => ... ));
  services.AddAuthorization(_ => _.AddPolicy("Admin", __ => ... ));
  services.AddMvc()
    .AddJsonOptions(_ => ...);
  services.AddSwaggerGen(_ => ... );
  services.AddDbContext<Context>(_ => _.UseSqlServer( ... ));

再次修改 配置的设置如下。

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
  if (env.IsDevelopment())
    app.UseDeveloperExceptionPage();

  app.Use(async (context, next) =>
  {
    try { await next(); }
    catch (Exception) { context.Response.StatusCode = ... }
  });

  app.UseCors("Open policy");
  app.UseAuthentication();
  app.UseMvc();
  app.UseSwagger();
  app.UseSwaggerUI(...);
}

1 个答案:

答案 0 :(得分:0)

我通过分析事件管道(如@amy所述)解决了这个问题,并注意到动作调用前面是 OnActionExecuting 方法(shown in the PDF由@sixtosaez提供)。< / p>

public override void OnActionExecuting(ActionExecutingContext context)
{
  Claim claim = User.Claims
    .First(_ => _.Type == "MemberId");
  ...
}

我想也可以通过改变开始中的中间件的注册顺序来开展工作(如@MarkG所提到的那样),但是我对这个到期时间没有信心对于noobness和混乱。