一、身份授权流程
首先调用Subject.isPermitted/hasRole接口,委托给SecurityManager. SecurityManager接着会委托给内部组件Authorizer. Authorizer再将其请求委托给我们的Realm去做,Realm才是真正干活的. realm将用户请求的参数封装成权限对象,再从我们重写的doGetAuthorizationInfo方法中获取从数据库中查询到的权限集合. Realm将用户传入的权限对象,与数据库查询出来的权限对象进行比较。如果用户掺入的权限对象在数据库中存在,侧返回true,否则返回false。 前提:进行授权操作的前提,用户必须通过认证。
二、案例
1.首先模拟数据库查询数据
List< String> findRoleByLoginName ( String loginName) ; List< String> findPermissionByLoginName ( String loginName) ;
@Override public List< String> findRoleByLoginName ( String loginName) { List< String> list = Lists. newArrayList ( ) ; list. add ( "admin" ) ; list. add ( "dev" ) ; return list; } @Override public List< String> findPermissionByLoginName ( String loginName) { List< String> list = Lists. newArrayList ( ) ; list. add ( "order.add" ) ; list. add ( "order.insert" ) ; list. add ( "order.delete" ) ; return list; }
2.编写授权,认证的代码在之前的文章里
@Override protected AuthorizationInfo doGetAuthorizationInfo ( PrincipalCollection principalCollection) { String loginName = ( String) principalCollection. getPrimaryPrincipal ( ) ; SecurityServiceImpl service = new SecurityServiceImpl ( ) ; List< String> roles = service. findRoleByLoginName ( loginName) ; List< String> permissions = service. findPermissionByLoginName ( loginName) ; SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo ( ) ; simpleAuthorizationInfo. addRoles ( roles) ; simpleAuthorizationInfo. addStringPermissions ( permissions) ; return simpleAuthorizationInfo; }
IniSecurityManagerFactory factory = new IniSecurityManagerFactory ( "classpath:shiro.ini" ) ; SecurityManager securityManager = factory. getInstance ( ) ; SecurityUtils. setSecurityManager ( securityManager) ; Subject subject = SecurityUtils. getSubject ( ) ; UsernamePasswordToken passwordToken = new UsernamePasswordToken ( "zhangSan" , "123" ) ; subject. login ( passwordToken) ; System. out. println ( "登录结果" + subject. isAuthenticated ( ) ) ; boolean admin = subject. hasRole ( "admin" ) ; System. out. println ( "是否用户管理员角色" + admin) ; try { subject. checkRole ( "coder" ) ; System. out. println ( "当前用户有coder这个角色" ) ; } catch ( AuthorizationException e) { System. out. println ( "当前用户没有coder这个角色" ) ; } System. out. println ( "当前用户是否有查看订单的权限" + subject. isPermitted ( "order:list" ) ) ; try { subject. checkPermission ( "order:update" ) ; System. out. println ( "当前用户有修改权限" ) ; } catch ( AuthorizationException e) { System. out. println ( "当前用户没有修改权限" ) ; }
执行结果