我们希望在微服务环境中实现身份验证。遗憾的是,stackoverflow 中的所有答案都没有回答我的问题。 我们基本上有 3 个系统。
1 个前端 (F)
1 个身份验证服务器 (AS)
1 个微服务器 (MS)
我们希望通过 (F) 进行身份验证以在 AS 中进行身份验证,并希望接收可以访问我们拥有的所有 MS 系统的令牌。然后我们希望使用在 AS 中生成的 Token 从 MS 获取信息。 MS 应该在 AS 中验证这个令牌并收到一个 ok 或类似的东西。
在身份验证服务器中,我们有以下内容:
Startup.cs
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.RequireHttpsMetadata = false;
options.SaveToken = true;
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false
};
});
中间件.cs
public class JwtMiddleware
{
private readonly RequestDelegate _next;
private readonly AppSettings _appSettings;
public JwtMiddleware(RequestDelegate next, IOptions<AppSettings> appSettings)
{
_next = next;
_appSettings = appSettings.Value;
}
public async Task Invoke(HttpContext context, IUserService userService)
{
var token = context.Request.Headers["Authorization"].FirstOrDefault()?.Split(" ").Last();
if (token != null)
attachUserToContext(context, userService, token);
await _next(context);
}
} }
private string GenerateJwtToken(User user)
{
// generate token that is valid for 7 days
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.ASCII.GetBytes(_appSettings.Secret);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new[] { new Claim("id", user.Id.ToString()) }),
Expires = DateTime.UtcNow.AddDays(7),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
};
tokenDescriptor.Audience = "api.ms";
var token = tokenHandler.CreateToken(tokenDescriptor);
return tokenHandler.WriteToken(token);
}
在我们的微服务中:
Startup.cs
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.Authority = $"https://localhost:5004";
options.Audience = $"api.ms";
options.TokenValidationParameters.ValidateLifetime = true;
options.TokenValidationParameters.ClockSkew = TimeSpan.FromMinutes(5);
options.RequireHttpsMetadata = false;
});
services.AddSingleton<IAuthorizationHandler, HasScopeHandler>();
我们知道权限是正确的,它调用了我们 AS 中的中间件。但是 context.headers 总是空的。 我们错过了什么?