webapi框架搭建-安全机制(三)-简单的基于⾓⾊的权限控制
上⼀篇已经完成了“⾝份验证”,如果只是想简单的实现基于⾓⾊的权限管理,我们基本上不⽤写代码,微软已经提供了authorize特性,直接⽤就⾏。有意义的一件事
Authorize特性的使⽤⽅法
配置Authorize
⽐较简单,直接上代码
using System.Collections.Generic;
using System.Net.Http;
using System.Security.Claims;
using System.Web.Http;
using webapi.Common;
ample
理财理念
{
[RoutePrefix("api/curity")]
public class SecurityTestController : ApiController
{
/// <summary>
/// 通过get请求⾥传过来的值⽣成token
/// </summary>
/// <returns></returns>
[Route("token"),HttpGet]
public IHttpActionResult GetToken()
{
var dic=new Dictionary<string,object>();
foreach (var queryNameValuePair in Request.GetQueryNameValuePairs())
孙悟空大闹天宫故事{
dic.Add(queryNameValuePair.Key,queryNameValuePair.Value);
}
var token=new JWTHelper().Encode(dic, "shengyu",30);
return Ok(token);
}
/// <summary>
/// 返回token⾥加密的信息
/// </summary>
/
// <returns></returns>
[Route("GetUrInfoFromToken"),HttpGet]
public IHttpActionResult GetUr()
产品购销合同范本{
var ur = (ClaimsPrincipal)Ur;
握手作文600字
var dic=new Dictionary<string,object>();
foreach (var urClaim in ur.Claims)
{
dic.Add(urClaim.Type,urClaim.Value);
}
return Ok(dic);
}
#region 硬编码的⽅式实现简单的权限控制
/// <summary>
早泄的自我治疗方法/// 只有某种⾓⾊的⽤户才有权限访问
/// </summary>
/// <returns></returns>
[Route("byCode/onlyRoles"), Authorize(Roles = "admin,superAdmin"),HttpGet]
public IHttpActionResult OnlyRoles_SetByCode()
{
return Ok("OnlyRoles_SetByCode,仅管理员能访问");
}
/
// <summary>
/// 只有某⼏个⽤户才有权限访问
/// </summary>
/// <returns></returns>
[Route("byCode/onlyUrs"), Authorize(Urs = "张三,李四"),HttpGet]
public IHttpActionResult OnlyUrs_SetByCode()
{
return Ok("OnlyRoles_SetByCode,仅张三和李四才能访问");
}
#endregion
}
}
Authorize特性有Roles和Urs两个属性,设置这两个属性的值及可以控制哪些⾓⾊/⽤户有权限访问。Authorize特性可以⽤于修饰类或是⽅法,如果整个控制器都要⽤权限控制,则修饰这个控制器类,否则只修饰在某个接⼝上。如果控制器被修饰了但⼜要排除某⼀个action,可⽤AllowAnonymous特性进⾏排除。
获取token
现在获取⼀个token,这个token⾥包含了“⾓⾊为admin”的信息,如下
⽤上⼀篇:⾥的获取token的接⼝获取⼀个role为admin的token
请求需要权限的接⼝
请求需要⾓⾊为admin或是superAdmin的接⼝SecurityTestController.OnlyRoles_SetByCode(),注意将上⼀步⽣成的token放到http request的header⾥
你可尝试在“获取token"步骤⾥⽣成⾮admin⾓⾊的token,那么在这⼀步⾥会出现授权失败的错误,如下图
同样原理,在”获取token"步骤⾥ur设置成“张三”或“李四”时,就可以⽤此token访问SecurityTestController.OnlyUrs_SetByCode()接⼝了。养什么赚钱
在实际开发中,获取token的接⼝(即⽅法SecurityTestController.GetToken())⾥的代码通常写在⽤户登录接⼝⾥,⽤户通过⽤户名和密码登录成功后,接⼝访问⼀个token给客户端,以后客户端的每次接⼝请求都在headers⾥带上这个token。微软提供的默认authorize特性在⼩项⽬和中型的对权限控制没有复杂要求的项⽬⾥已经够⽤了。缺点是项⽬开发前得确定好业务的各种⾓⾊,因为要以“硬编码”的⽅式写在接⼝⽅法上。后期如果要修改⼀个接⼝的所属⾓⾊,只有重新修改代码。
如果要实现更加可控的基于⾓⾊的权限控制,只有⾃⼰写Authorize filter。下⾯介绍如何写⾃⼰的authorize filter。
⾃定义Authorize filter
可通过继承下⾯三个对象之⼀去写⾃⼰的authorize filter
即:AuthorizeAttribute、AuthorizationFilterAttribute、IAuthorizationFilter,三者的关系如下图
我采⽤继承AuthorizeAttribute,并重写IsAuthorized⽅法,代码如下
using System.Net;
using System.Net.Http;
using System.Web.Http;
using System.Web.Http.Controllers;
namespace webapi.Security
{
/// <summary>
/// Role Basic AuthorizeAttribute(基于⾓⾊的授权)
/// </summary>
public class RBAuthorizeAttribute:AuthorizeAttribute
{
protected override bool IsAuthorized(HttpActionContext actionContext)
{
// 下在可替换成⾃⼰的授权逻辑代码
return ba.IsAuthorized(actionContext);
}
protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
{
actionContext.Respon =
actionContext.ControllerContext.Request.CreateErrorRespon(HttpStatusCode.Unauthorized, "未授权");
}
}
}
RBAuthorize特性和Authorize特性⽤法是⼀样的,不再重复。后续的博客⾥会引⼊基于⾓⾊的权限管理的表结构,并在IsAuthorized⽅法⾥写授权逻辑。
>只想一生跟你走歌词