就目前来说,系统基本上都采用的是JWT方式来进行验证,所以,我在这里把JWT的实现给弄一遍,具体原理什么的,我不详细写了,百度一堆原理,话止于此,开始!!
导包
首先,导包,在这里,我就只是导入JWT这一个包即可,因为我们是自定义JWT属性吗,所以就只需要这一个,当然,我是做完再写的文档,如果不对,那我也没办法
实体准备
新建一些我们后面需要的实体属性 AuthInfo.cs
public class AuthInfo
{
//模拟JWT的payload
public string UserName { get; set; }
public List<string> Roles { get; set; }
public bool IsAdmin { get; set; }
/// <summary>
/// 过期时间
/// </summary>
public string ExpirationTime { get; set; }
}
下面这个是我们用来进行token的加密和解密的方法
public class Secretkey
{
/// <summary>
/// 加密
/// </summary>
/// <param name="info"></param>
/// <param name="secret"></param>
/// <returns></returns>
public static string Enc_SecKey(AuthInfo info, string secret)
{
IJwtAlgorithm algorithm = new HMACSHA256Algorithm();
IJsonSerializer serializer = new JsonNetSerializer();
IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder);
var token = encoder.Encode(info, secret);
return token;
}
/// <summary>
/// 解密
/// </summary>
/// <param name="token"></param>
/// <param name="secret"></param>
/// <returns></returns>
public static AuthInfo Dec_SecKey(string token, string secret)
{
//secret需要加密
JWT.IJsonSerializer serializer = new JsonNetSerializer();
IDateTimeProvider provider = new UtcDateTimeProvider();
IJwtValidator validator = new JwtValidator(serializer, provider);
IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
IJwtAlgorithm algorithm = new HMACSHA256Algorithm();
IJwtDecoder decoder = new JwtDecoder(serializer, validator, urlEncoder, algorithm);
var authInfo = decoder.DecodeToObject<AuthInfo>(token, secret, verify: true);
return authInfo;
}
}
自定义过滤属性
在添加完这些之后,我们就可以新建一个AuthAttribute通过继承和实现Attribute,IAuthorizationFilter,代码如下
public class AuthAttribute : Attribute, IAuthorizationFilter
{
public void OnAuthorization(AuthorizationFilterContext context)
{
// 在这里执行您的自定义授权逻辑
if (!IsAuthorized(context))
{
// 如果未通过授权,返回 403 Forbidden
context.Result = new ContentResult
{
StatusCode = StatusCodes.Status401Unauthorized,
ContentType = "application/json",
Content = JsonConvert.SerializeObject(new { message = "Unauthorized:认证失败" }) // 或者使用其他序列化方式
};
}
return;
}
private bool IsAuthorized(AuthorizationFilterContext context)
{
//获取token
var authHeader = from t in context.HttpContext.Request.Headers
where t.Key == "auth" || t.Key == "Auth"
select t.Value.FirstOrDefault();
//验证token是否为空
if (authHeader != null)
{
string token = authHeader.FirstOrDefault();
if (!string.IsNullOrEmpty(token))
{
try
{
string secret = "SecretKey" + DateTime.Now.ToString("yyyyMMdd");//口令加密秘钥(应该写到配置文件中)
var authInfo = Secretkey.Dec_SecKey(token, secret);
if (authInfo != null)
{
DateTime ExpDate = Convert.ToDateTime(authInfo.ExpirationTime).AddHours(24);
//验证token是否超时,这里设置的过期时间为两小时
if (ExpDate < DateTime.Now && !string.IsNullOrEmpty(authInfo.ExpirationTime))
{
return false;
}
else
{
context.HttpContext.GetRouteData().Values.Add("authinfo", authInfo);
return true;
}
}
return false;
}
catch (Exception ex)
{
return false;
}
}
}
return false;
}
}
然后,没有然后啦!这就可以正常使用了,对自己控制器中的方法添加[Auth]即可进行约束,如下
由此可以看出,这就已经可以对未登录的进行限制了