MVC进行jwt认证
1、JWT
1.1 基于 Token 的身份验证方法
使用基于 Token 的身份验证方法,在服务端不需要存储用户的登录记录。大概的流程是这样的:
- 客户端使用用户名跟密码请求登录
- 服务端收到请求,去验证用户名与密码
- 验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端
- 客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里
- 客户端每次向服务端请求资源的时候需要带着服务端签发的 Token
- 服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据
1.2 JWT
JWT 标准的 Token 有三个部分:
- header
- payload
- signature
2、安装JWT.NET
3、使用JWT
3.1 JWT帮助类
-
public class JwtHelper
-
{
-
private string m_Secret = "BFE7E27E-C1F3-41E0-AAD5-7D14AFC6CD2C";
-
public string EncodeJwt(LoginInfo userInfo)
-
{
-
IJwtAlgorithm algorithm = new HMACSHA256Algorithm();
-
IJsonSerializer serializer = new JsonNetSerializer();
-
IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
-
IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder);
-
return encoder.Encode(userInfo, m_Secret);
-
}
-
public LoginInfo DecodeJwt(string token)
-
{
-
IJsonSerializer serializer = new JsonNetSerializer();
-
IDateTimeProvider provider = new UtcDateTimeProvider();
-
IJwtValidator validator = new JwtValidator(serializer, provider);
-
IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
-
IJwtDecoder decoder = new JwtDecoder(serializer, validator, urlEncoder);
-
var userInfo = decoder.DecodeToObject<LoginInfo>(token, m_Secret, verify: true);//token为之前生成的字符串
-
return userInfo;
-
}
-
}
3.2 获取JWT的接口
-
public ActionResult CreateToken(string UserName, string PassWord)
-
{
-
if (string.IsNullOrEmpty(UserName) || string.IsNullOrEmpty(PassWord))
-
throw new Exception("参数为空");
-
JwtResult jwtResult;
-
try
-
{
-
//var param = HttpContext.Request["UserName"];
-
//param = HttpContext.Request["PassWord"];
-
if (!UserName.Equals("test") || !PassWord.Equals("test"))
-
{
-
throw new Exception("用户密码不正确。");
-
}
-
LoginInfo pUserLoginInfo = new LoginInfo() { Name = UserName, Password = PassWord };
-
JwtHelper pHelper = new JwtHelper();
-
string sJwt = pHelper.EncodeJwt(pUserLoginInfo);
-
jwtResult = new JwtResult()
-
{
-
JwtCode = sJwt,
-
StatusCode = "200",
-
Message = "success"
-
};
-
return Json(jwtResult);
-
}
-
catch (Exception ex)
-
{
-
jwtResult = new JwtResult()
-
{
-
JwtCode = "",
-
StatusCode = "403",
-
Message = ex.Message
-
};
-
}
-
return Json(jwtResult);
-
}
3.3 .Net身份认证
AuthorizeAttribute类有两个重要的方法:AuthorizeCore和HandleUnauthorizedRequest。其中AuthorizeCore函数是用来判断一个请求是否通过用户验证,它的返回结果是一个bool。HandleUnauthorizedRequest函数则是在AuthorizeCore返回结果是false时会调用的函数。
AuthorizeAttribute属性置于Action前,在调用Action前会进行验证。
AuthorizeAttribute属性置于Controller类前,在调用Controller中任何Action前会进行验证。
-
public class AppAuthorizeAttribute: AuthorizeAttribute
-
{
-
/// <summary>
-
/// 验证入口
-
/// </summary>
-
/// <param name="filterContext"></param>
-
public override void OnAuthorization(AuthorizationContext filterContext)
-
{
-
base.OnAuthorization(filterContext);
-
}
-
protected override bool AuthorizeCore(HttpContextBase httpContext)
-
{
-
JwtHelper pHelper = new JwtHelper();
-
try
-
{
-
//前端请求api时会将token存放在名为"auth"的请求头中
-
var authHeader = httpContext.Request.Headers["auth"];
-
if (authHeader == null)
-
{
-
httpContext.Response.StatusCode = 403;
-
return false;
-
}
-
var userinfo = pHelper.DecodeJwt(authHeader);
-
if (userinfo != null)
-
return true;
-
httpContext.Response.StatusCode = 403;
-
return false;
-
}
-
catch
-
{
-
httpContext.Response.StatusCode = 403;
-
return false;
-
}
-
}
-
/// <summary>
-
/// 验证失败处理
-
/// </summary>
-
/// <param name="filterContext"></param>
-
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
-
{
-
base.HandleUnauthorizedRequest(filterContext);
-
if (filterContext.HttpContext.Response.StatusCode == 403)
-
{
-
filterContext.Result = new RedirectResult("/Error");
-
filterContext.HttpContext.Response.Redirect("/Home/Error");
-
}
-
}
-
}
3.4 页面请求
-
[AppAuthorize]
-
public class PagingController : Controller
-
{
-
// GET: Home
-
public ActionResult Index()
-
{
-
Models.UserInfo pUser = new Models.UserInfo()
-
{
-
Name = "Test",
-
Age = 18
-
};
-
ViewBag.Name = "Xq_lureker";
-
ViewBag.Age = "18";
-
return View(pUser);
-
}
-
}
3.5 测试
3.5.1 生成Token
3.5.2 不带Token的页面请求
3.5.3 带Token的请求
参考: