您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 项目/工程管理 > 将Shiro作为应用的权限基础三基于注解实现的授权认证过程
授权即访问控制,它将判断用户在应用程序中对资源是否拥有相应的访问权限。如,判断一个用户有查看页面的权限,编辑数据的权限,拥有某一按钮的权限等等。一、用户权限模型为实现一个较为灵活的用户权限数据模型,通常把用户信息单独用一个实体表示,用户权限信息用两个实体表示。用户信息用LoginAccount表示,最简单的用户信息可能只包含用户名loginName及密码password两个属性。实际应用中可能会包含用户是否被禁用,用户信息是否过期等信息。用户权限信息用Role与Permission表示,Role与Permission之间构成多对多关系。Permission可以理解为对一个资源的操作,Role可以简单理解为Permission的集合。用户信息与Role之间构成多对多关系。表示同一个用户可以拥有多个Role,一个Role可以被多个用户所拥有。权限声明及粒度Shiro权限声明通常是使用以冒号分隔的表达式。就像前文所讲,一个权限表达式可以清晰的指定资源类型,允许的操作。同时,Shiro权限表达式支持简单的通配符,可以更加灵活的进行权限设置。下面以实例来说明权限表达式。可查询用户数据User:view可查询或编辑用户数据User:view,edit可对用户数据进行所有操作User:*或user可编辑id为123的用户数据User:edit:123授权处理过程认证通过后接受Shiro授权检查,授权验证时,需要判断当前角色是否拥有该权限。只有授权通过,才可以访问受保护URL对应的资源,否则跳转到“未经授权页面”。如果我们自定义Realm实现,比如我后面的例子中,自定义了ShiroDbRealm类,当访问被@RequiresPermissions注解的方法时,会先执行ShiroDbRealm.doGetAuthorizationInfo()进行授权。@Controller@RequestMapping(value=/user)publicclassUserController{@Resource(name=userService)privateIUserServiceuserService;/***测试权限*只有拥有user:create权限,才能进行注册*@paramuser*@return*/@RequestMapping(value=/register)@ResponseBody@RequiresPermissions(user:create)publicbooleanregister(Useruser){returnuserService.register(user);}二、授权实现Shiro支持三种方式实现授权过程:o编码实现o注解实现oJSPTaglig实现1、基于编码的授权实现1、基于权限对象的实现创建org.apache.shiro.authz.Permission的实例,将该实例对象作为参数传递给Subject.isPermitted()进行验证。PermissionprintPermission=newPrinterPermission(laserjet4400n,print);SubjectcurrentUser=SecurityUtils.getSubject();if(currentUser.isPermitted(printPermission)){//showthePrintbutton}else{//don'tshowthebutton?Greyitout?}2、基于字符串的实现相比笨重的基于对象的实现方式,基于字符串的实现便显得更加简洁。SubjectcurrentUser=SecurityUtils.getSubject();if(currentUser.isPermitted(printer:print:laserjet4400n)){//showthePrintbutton}else{//don'tshowthebutton?Greyitout?}使用冒号分隔的权限表达式是org.apache.shiro.authz.permission.WildcardPermission默认支持的实现方式。这里分别代表了资源类型:操作:资源ID2、基于注解的授权实现Shiro注解支持AspectJ、Spring、Google-Guice等,可根据应用进行不同的配置。相关的注解:@RequiresAuthentication可以用户类/属性/方法,用于表明当前用户需是经过认证的用户。@RequiresAuthenticationpublicvoidupdateAccount(AccountuserAccount){//thismethodwillonlybeinvokedbya//Subjectthatisguaranteedauthenticated...}@RequiresPermissions当前用户需拥有制定权限@RequiresPermissions(account:create)publicvoidcreateAccount(Accountaccount){//thismethodwillonlybeinvokedbyaSubject//thatispermittedtocreateanaccount...}3、基于JSPTAG的授权实现Shiro提供了一套JSP标签库来实现页面级的授权控制。在使用Shiro标签库前,首先需要在JSP引入shiro标签:%@taglibprefix=shirouri=标签:验证当前用户是否属于该角色shiro:hasRolename=administratorahref=admin.jspAdministerthesystem/a/shiro:hasRolehasPermission标签:验证当前用户是否拥有制定权限shiro:hasPermissionname=user:createahref=createUser.jspCreateanewUser/a/shiro:hasPermission三、Shiro授权的内部处理机制1、在应用程序中调用授权验证方法(Subject的isPermitted*或hasRole*等)2、Sbuject会委托应用程序设置的securityManager实例调用相应的isPermitted*或hasRole*方法。3、接下来SecurityManager会委托内置的Authorizer的实例(默认是ModularRealmAuthorizer类的实例,类似认证实例)调用相应的授权方法。4、每一个Realm将检查是否实现了相同的Authorizer接口。然后,将调用Reaml自己的相应的授权验证方法。四、授权代码UserController:处理用户登录后的请求(注册)packageorg.shiro.demo.controller;importjavax.annotation.Resource;importorg.apache.shiro.authz.annotation.RequiresPermissions;importorg.apache.shiro.authz.annotation.RequiresRoles;importorg.springframework.stereotype.Controller;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.bind.annotation.ResponseBody;importorg.shiro.demo.entity.User;importorg.shiro.demo.service.IUserService;@Controller@RequestMapping(value=/user)publicclassUserController{@Resource(name=userService)privateIUserServiceuserService;/***测试权限*只有拥有user:create权限,才能进行注册*@paramuser*@return*/@RequestMapping(value=/register)@ResponseBody@RequiresPermissions(user:create)publicbooleanregister(Useruser){returnuserService.register(user);}/***测试角色*只有拥有administrator角色,才能跳转到register页面*@return*/@RequestMapping(value=/toRegister)@RequiresRoles(administrator)publicStringtoRegister(){return/system/user/register;}}ShiroDbRealm:自定义的指定Shiro验证用户授权的类packageorg.shiro.demo.service.realm;importjava.util.ArrayList;importjava.util.List;importjavax.annotation.Resource;importorg.apache.commons.lang.StringUtils;importorg.apache.shiro.authc.AuthenticationException;importorg.apache.shiro.authc.AuthenticationInfo;importorg.apache.shiro.authc.AuthenticationToken;importorg.apache.shiro.authc.SimpleAuthenticationInfo;importorg.apache.shiro.authc.UsernamePasswordToken;importorg.apache.shiro.authz.AuthorizationException;importorg.apache.shiro.authz.AuthorizationInfo;importorg.apache.shiro.authz.SimpleAuthorizationInfo;importorg.apache.shiro.realm.AuthorizingRealm;importorg.apache.shiro.subject.PrincipalCollection;importorg.shiro.demo.entity.Permission;importorg.shiro.demo.entity.Role;importorg.shiro.demo.entity.User;importorg.shiro.demo.service.IUserService;/***自定义的指定Shiro验证用户登录的类*@authorTCH**/publicclassShiroDbRealmextendsAuthorizingRealm{//@Resource(name=userService)privateIUserServiceuserService;publicvoidsetUserService(IUserServiceuserService){this.userService=userService;}/***为当前登录的Subject授予角色和权限*@see经测试:本例中该方法的调用时机为需授权资源被访问时*@see经测试:并且每次访问需授权资源时都会执行该方法中的逻辑,*这表明本例未启用AuthorizationCache*@seeweb层可以有shiro的缓存,d
本文标题:将Shiro作为应用的权限基础三基于注解实现的授权认证过程
链接地址:https://www.777doc.com/doc-2537805 .html