网站首页 网站源码
using Dpz.Core.EnumLibrary;
using Dpz.Core.Service.RepositoryService;
using Microsoft.AspNetCore.Authentication;
namespace Dpz.Core.Auth.Middleware;
/// <summary>
/// SecurityStamp验证中间件
/// 用于在密码修改后自动登出其他浏览器的会话
/// </summary>
public class SecurityStampValidationMiddleware(
RequestDelegate next,
ILogger<SecurityStampValidationMiddleware> logger
)
{
public async Task InvokeAsync(HttpContext context, IUserSecurityService userSecurityService)
{
// 只对已认证的用户进行验证
if (context.User.Identity?.IsAuthenticated == true)
{
var account = context.User.NameIdentifier;
var claimKey = context.User.FindFirst("Key")?.Value;
if (!string.IsNullOrEmpty(account) && !string.IsNullOrEmpty(claimKey))
{
try
{
// 使用新的UserSecurityService验证SecurityStamp,获取详细的验证结果
var validationResult =
await userSecurityService.ValidateUserSecurityStampDetailedAsync(
account,
claimKey
);
// 根据不同的验证结果进行处理
if (validationResult != UserSecurityValidationResult.Valid)
{
logger.LogInformation(
"用户 {Account} 的验证失败,原因:{Reason}",
account,
validationResult
);
// 登出用户
await context.SignOutAsync();
// 根据不同的失败原因,重定向到不同的错误页面
var redirectUrl = validationResult switch
{
UserSecurityValidationResult.UserDisabled =>
"/sign-in?msg=account-disabled",
UserSecurityValidationResult.SecurityStampInvalid =>
"/sign-in?msg=security-stamp-expired",
UserSecurityValidationResult.UserNotFound =>
"/sign-in?msg=user-not-found",
_ => "/sign-in?msg=auth-error",
};
context.Response.Redirect(redirectUrl);
return;
}
}
catch (Exception ex)
{
logger.LogError(ex, "验证用户 {Account} 的SecurityStamp时发生错误", account);
}
}
}
await next(context);
}
}
/// <summary>
/// SecurityStamp验证中间件扩展方法
/// </summary>
public static class SecurityStampValidationMiddlewareExtensions
{
public static IApplicationBuilder UseSecurityStampValidation(this IApplicationBuilder builder)
{
return builder.UseMiddleware<SecurityStampValidationMiddleware>();
}
}
上述代码实现了一个名为 SecurityStampValidationMiddleware 的中间件,用于在 ASP.NET Core 应用程序中验证用户的安全戳(Security Stamp)。其主要功能是确保在用户密码被修改或账户安全状态发生变化时,自动登出其他会话。这是为了增强安全性,防止未授权的访问。
中间件构造函数:
SecurityStampValidationMiddleware 类的构造函数接受一个 RequestDelegate 和一个 ILogger 实例。RequestDelegate 用于调用下一个中间件,ILogger 用于记录日志。InvokeAsync 方法:
context.User.Identity?.IsAuthenticated)。account)和安全戳(claimKey)的值。安全戳验证:
account 和 claimKey 都不为空,调用 IUserSecurityService 的 ValidateUserSecurityStampAsync 方法来验证安全戳。登出操作:
context.SignOutAsync() 方法登出用户。msg=security-stamp-expired),提示用户安全戳已过期。异常处理:
中间件扩展方法:
SecurityStampValidationMiddlewareExtensions 类提供了一个扩展方法 UseSecurityStampValidation,用于将中间件添加到 ASP.NET Core 的请求处理管道中。这个中间件的主要目的是在用户的安全戳失效时,自动登出用户并引导他们重新登录,从而提高应用程序的安全性。它确保了用户在密码更改后不会继续保持登录状态,防止潜在的安全风险。
