我正在开发一些blazor应用程序,我不得不使用windows autch,因为它只面向企业用户。所以我有
builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme).AddNegotiate();
我有一些用户控制器负责获取用户名。现在我希望保护整个api,这样用户就不能使用我的api (因为他们是域认证的),只有这个WASM不应该在开发中使用这个api并大摇大摆地使用它。
什么是最好的练习?jwt也是?仅仅是为了api保护而不是纯粹的用户身份验证?
我确实生成了一些jwt
[HttpGet]
[Authorize]
[Route("GetUser")]
public UserModel GetUser()
{
string? login = httpContextAccessor!.HttpContext!.User?.Identity?.Name?.Replace("domain\\", "");
return new UserModel{ UserName=login , JWT = CreateJWT(login)};
}
private string? CreateJWT(string? userName)
{
if (userName == null) return null;
var secretkey = new SymmetricSecurityKey(System.Text.Encoding.UTF8.GetBytes(this.appSettings.JWTSettings!.Secret!));
var credentials = new SigningCredentials(secretkey, SecurityAlgorithms.HmacSha256);
var claims = new[]
{
new Claim(ClaimTypes.Name, userName),
new Claim(JwtRegisteredClaimNames.Sub, userName)
};
var token = new JwtSecurityToken(issuer: "xxx", audience: "xxx", claims: claims, expires: DateTime.Now.AddMinutes(int.Parse(this.appSettings.JWTSettings.ExpireTime!)), signingCredentials: credentials);
return new JwtSecurityTokenHandler().WriteToken(token);
}
}
但是如何强制api也检查这个jwt呢?我试过
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateAudience = true,
ValidAudience = "xxx",
ValidateIssuer = true,
ValidIssuer = "xxx",
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(System.Text.Encoding.UTF8.GetBytes(a.JWTSettings.Secret!))
};
});
但这并没有改变什么。这个应用程序可以有两次builder.Services.AddAuthentication
吗?
如果不是,那么我需要构建一些定制的中间件吗?还是有更好的解决办法?
谢谢和问候
发布于 2022-07-06 08:59:48
好的,对未来的搜索者来说。
//update我创建了一个git,其中我创建了一个示例应用程序,它使用windows auth + authStateProvider + jwt访问.net 6+ swagger中的api,在这里我们还可以运行getuser方法,获取JWT令牌并粘贴作为它的授权。
它不是完美的,而是体面的。这样每个人都能看到可能性
https://github.com/d00lar/BlazorWasmAuthStateProvicerWindowsAuthAndJWT
//旧答复:
为了按照我想要的方式工作,我们需要:
builder.Services.AddAuthentication((options) =>
{
options.DefaultAuthenticateScheme = "JwtBearer";
options.DefaultChallengeScheme = "JwtBearer";
}).AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateAudience = true,
ValidateIssuer = true,
ValidIssuer = builder.Configuration["JWT:Issuer"],
ValidAudience = builder.Configuration["JWT:Issuer"],
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
IssuerSigningKey = new
SymmetricSecurityKey(System.Text.Encoding.UTF8.GetBytes(builder.Configuration["JWT:Key"]))
};
}).AddNegotiate();
然后我又说
builder.Services.AddAuthorization(options =>
{
var defaultAuthorizationPolicyBuilder = new AuthorizationPolicyBuilder(JwtBearerDefaults.AuthenticationScheme);
defaultAuthorizationPolicyBuilder = defaultAuthorizationPolicyBuilder.RequireAuthenticatedUser();
options.DefaultPolicy = defaultAuthorizationPolicyBuilder.Build();
});
和
app.MapControllers().RequireAuthorization();
此添加自动不可见。
[Authorize(AuthenticationSchemes=JwtBearerDefaults.AuthenticationScheme)]
给我所有的控制者
最后,对于生成jwt并需要获取windows用户名的getUser方法,
[Authorize(AuthenticationSchemes = NegotiateDefaults.AuthenticationScheme)]
https://stackoverflow.com/questions/72828251
复制相似问题