gpt4 book ai didi

c# - 运行除 [Authorize] 注释之外的其他逻辑

转载 作者:行者123 更新时间:2023-12-04 14:12:52 25 4
gpt4 key购买 nike

我正在使用 Microsoft.AspNetCore.Authentication.JwtBearer System.IdentityModel.Tokens.Jwt 用于我的 .NET Core 项目。
每当我生成一个新 token 时,我都会将其存储到数据库中。当用户退出时,我将其从数据库中删除以使其无效(我还通过作业从数据库中删除了过期的)。当用户尝试访问受 [Authorize] 保护的路由时注释我想检查该 token 是否存在于数据库中。如果没有,我发送 401。
在我的 Startup 中 Configure我正在调用的方法 app.UseAuthentication()并在 ConfigureServices我为 [Authorize] 设置验证的方法注释(我试图对其进行评论以显示我想要实现的目标)

services
.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(jwtBearerOptions =>
{
byte[] symmetricKey = Convert.FromBase64String("secretFromConfig");
SymmetricSecurityKey symmetricSecurityKey = new SymmetricSecurityKey(symmetricKey);

jwtBearerOptions.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuerSigningKey = true,
ValidateLifetime = true,
ValidateIssuer = false,
ValidateAudience = false,
IssuerSigningKey = symmetricSecurityKey,
};

jwtBearerOptions.Events = new JwtBearerEvents()
{
OnTokenValidated = tokenValidatedContext =>
{
// inject my database repository
ITokensRepository tokensRepository = tokenValidatedContext.HttpContext.RequestServices.GetRequiredService<ITokensRepository>();
JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();

// convert the token to a string
string token = tokenHandler.WriteToken(tokenValidatedContext.SecurityToken);

// read the username from the token payload
Claim usernameClaim = tokenValidatedContext.Principal.Claims.FirstOrDefault(claim => claim.Type == "username");

// assign if exists
string username = usernameClaim?.Value;

// fetch token from database
object tokenInfo = await tokensRepository.GetUserTokenAsync(token, username);

if (tokenInfo == null)
{
// return a 401 if token doesn't exist in database
tokenValidatedContext.Fail("Invalid token.");
// return new UnauthorizedResult();
}
else
{
tokenValidatedContext.Success();

// controller methods can fetch it from here later on
tokenValidatedContext.HttpContext.Items["username"] = username;
}

return Task.CompletedTask;
}
};
});
当我尝试制作 OnTokenValidated 时存储库调用的回调异步我收到错误消息

Return type is 'void'


我该如何解决?回调必须是异步的,因为我正在访问数据库。任何帮助将不胜感激!

最佳答案

我相信这样做的更好方法之一是向您的授权添加策略。 (类似于如果要创建 claim 政策的处理方式)
如果您只想要某个授权标签的策略
Startup.cs

 services.AddAuthorization(authorizationOptions =>
{
authorizationOptions.AddPolicy(
"MustHaveTokenInDb",
policyBuilder =>
{
//add any other policy requirements here too including ones by default
//eg policyBuilder.RequireAuthenticatedUser();
policyBuilder.AddRequirements(
new MustHaveTokenInDbRequirement());
});
//only if you want to register as the default policy
authorizationOptions.DefaultPolicy = authorizationOptions.GetPolicy("MustHaveTokenInDb");
});
然后在授权
您使用的标签
[Authorize("MustHaveTokenInDB")]
您可以设置一个默认策略,允许您像往常一样使用 Authorize 标签
authorizationOptions.DefaultPolicy = authorizationOptions.GetPolicy("MustHaveTokenInDb");
您的需求类别
public class MustHaveTokenInDbRequirement : IAuthorizationRequirement
{
public MustHaveTokenInDbRequirement ()
{
}
}
处理程序类
 public class MustHaveTokenInDbHandler : AuthorizationHandler<MustHaveTokenInDbRequirement >
{

public MustHaveTokenInDbHandler ()
{
//your dependency injections
}

protected override Task HandleRequirementAsync(
AuthorizationHandlerContext context,
MustHaveTokenInDbRequirement requirement)
{
//your logic
if (noTokenInDb)
{
context.Fail();
return Task.CompletedTask;
}


// has token in db
context.Succeed(requirement);
return Task.CompletedTask;
}
}
在您的配置服务中,您需要注册它:
services.AddScoped<IAuthorizationHandler, MustHaveTokenInDbHandler>();

关于c# - 运行除 [Authorize] 注释之外的其他逻辑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62947768/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com