NET CORE WEB 中自定义简洁的身份认证,适用于webapi, MVC 等各种 net core 场景
我们的项目从.net framework 转到 net core webapi,不想改太多代码,特别是身份认证,之前是直接在 QueryString 中传输 token 来认证,各个 action 上有个自定义的 CheckLogin 标签,要改成的 JWT 认证体系,工作量巨大,于是想到利用过滤器来实现自定义的身份认证过程。
先建一个空的 Attribute,不用任何功能,有这个 Attribute 的 Action 表示都需要认证
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class LoginCheckAttribute : Attribute
{
}
然后建一个 IActionFilter
public class AuthFilter : IActionFilter
{
private const string UnauthorizedMessage = "授权失效或过期,请重新登录。";
public void OnActionExecuting(ActionExecutingContext context)
{
var controllerInfo = context.ActionDescriptor as ControllerActionDescriptor;
var needcheck = controllerInfo?.EndpointMetadata.Any(_ => _.GetType() == typeof(LoginCheckAttribute)) ?? false;
if (needcheck)
{
var token = context.HttpContext.Request.Query["token"].ToString();
ApiResult<object>? result = null;
if (string.IsNullOrEmpty(token))
{
result = new() { Code = 888, Message = UnauthorizedMessage };
}
else
{
var uinfo = Factory.SessionAccess.GetUserByToken(token);//根据token得到用户信息
if (uinfo == null)
{
result = new() { Code = 888, Message = UnauthorizedMessage };
}
else
{
if (uinfo.State != (int)AdminState.enable)
{
result = new() { Code = 888, Message = "账号无法使用" };
}
else
context.HttpContext.Items["user"] = uinfo;//用户信息存在会话中,供业务逻辑中调用
}
}
if(result != null)
{
context.Result = new UnauthorizedObjectResult(result);
}
}
}
public void OnActionExecuted(ActionExecutedContext context)
{
}
}
然后在 program.cs 中加入过滤器:
builder.Services.AddControllers().AddMvcOptions(options => options.Filters.Insert(0, new AuthFilter()));
业务逻辑中需要用到用户信息的地方这样获取:
public UserDetails? UserInfo
{
get
{
if (MyHttpContext.Current == null) return null;
if(MyHttpContext.Current.Items.TryGetValue("user", out var value))
{
return value as UserDetails;
}
return null;
}
}