最近在做一个项目,前台使用的是angularjs,后台使用的是webapi。webapi不需要登陆,只需要知道方法就能直接访问。之前没有做过权限控制的问题,百度搜到了不少,但是都不能用,只能自己解决了,后来终于找到了一种可以实现的方法,只是不知道好不好,实现方法如下:
1、根据登陆信息(用户名,密码之类的)去数据库查询到用户信息,以及用户所有的权限(权限由在增加用户的时候分配)。
2、建立FormsAuthenticationTicket,并把用户信息保存到缓存中,并返回登陆结果及一个token(唯一标识),userRole是一个需要返回的信息实体类。
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
2,
list[0].USERID,
DateTime.Now,
dateCookieExpires,
false,
new JavaScriptSerializer().Serialize(userRole)-------权限(后面用到)
);
string encTicket = FormsAuthentication.Encrypt(ticket);
HttpRuntime.Cache.Add(userRole.TOKEN, encTicket, null, DateTime.Now.AddDays(7), TimeSpan.Zero, System.Web.Caching.CacheItemPriority.Default, null);------------保存到缓存中,也可以存到数据库
return Json(userRole);
3、把token保存到本地 localStorage.setItem("token",userRole.TOKEN);
4、创建一个全局注入器,每次访问的时候,可以自动在header中带入token
.factory("httpInjector",['$q','$injector',function($q,$injector){
var httpInterceptor = {
'responseError' : function(response) {
// ......
return $q.reject(response);
},
'response' : function(response) {
if (response.status == 21000) {
// console.log('do something...');
}
return response || $q.when(response);
},
'request' : function(config) {
config.headers = config.headers || {};
if (localStorage.token) {
config.headers.token = localStorage.getItem("token");
// config.headers['X-Access-Token'] = $localStorage.token;
};
return config || $q.when(config);
return config;
},
'requestError' : function(config){
// ......
return $q.reject(config);
}
};
return httpInterceptor;
}])
.config(["$ionicConfigProvider",'$httpProvider', function ($ionicConfigProvider,$httpProvider) {
$httpProvider.interceptors.push('httpInjector');
}])
6、创建一个过滤器TestFilter,继承AuthorizationFilterAttribute,重写方法
public override void OnAuthorization(HttpActionContext actionContext)-------重写授权方法 {
if (HttpContext.Current.Request.Headers["token"] != null)
{
string token = HttpContext.Current.Request.Headers["token"].ToString();---------获取前台传过来的token if (HttpRuntime.Cache.Get(token) != null)
{
------------根据token到缓存中取出用户信息。
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(HttpRuntime.Cache.Get(token).ToString());
if (ticket != null)
{
USER_ROLE userRole = new JavaScriptSerializer().Deserialize
string[] roles = new string[] { };--------取出用户权限组成数据
IIdentity identity = new FormsIdentity(ticket);-------------标识用户的身份验证的类型
IPrincipal principal = new GenericPrincipal(identity, roles); ---------当前用户标识 HttpContext.Current.User = principal;----------- 为当前 HTTP 请求设置安全信息。
}
}
}
}
7、把自定义的过滤器注册到webapiconfig中,注册后每次webapi请求会先经过过滤器
config.Filters.Add(new TestFilter());
8、方法或控制器上添加权限限制 [Authorize(Roles = "TEST")]
到此完成,没有此权限的用户就无法访问此方法。
为什么要返回token到前台,然后把用户信息保存到缓存中呢?是因为对于webapi来说,每次的访问都是一个新的请求,
之前的登陆信息在下次访问的时候就请求不到了,cookie和session也访问不到,所以信息保存到了缓存中(保存到数据库也可以但是请求太频繁)。根据token,找到对应的用户信息,取出用户信息后赋给当前请求用户,当前用户才有访问权限。
原文链接:https://blog.csdn.net/jeb222222/article/details/80581331