我正在我的控制器中调用一个方法并在其构造函数中命中一个断点。检查 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(...);
}
答案 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和混乱。