Realms: 域,Shiro从从Realm获取安全数据(如用户、角色、权限),就是说SecurityManager要验证用户身份,那么它需要从Realm获取相应的用户进行比较以确定用户身份是否合法;也需要从Realm得到用户相应的角色/权限进行验证用户是否能进行操作;可以把Realm看成DataSource,即安全数据源 。
当配置Shiro时,你必须指定至少一个Realm用来进行身份验证和/或授权 。SecurityManager可能配置多个Realms,但至少有一个是必须的 。
文章插图
我们可以通过一个简单的登录来看shiro对权限的控制 。
我们就通过图解来理解一下,然后写个简单的代码
文章插图
上图是对shiro角色权限的设计,
而接下来我们就可以看一下它具体的登录图解了
文章插图
我解释一下这个图 。
1、登陆操作 携带用户名密码给subject,subject调用自己的登陆方法传递用户名和密码给权限管理器,权限管理器将用户名密码传递给开发人员编写的realm的认证方法,realm根据用户名到数据库中查找是否存在该用户,若存在将认证信息存入到session中
/* * 参数1:登陆标识 * 参数2:正确的密码 * 参数3:认证|授权器的名字 */ SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(), this.getClass().getName());
2、权限管理器会自动判断传递的密码与正确密码是否一致3、访问3类资源(页面) 过滤器寻找权限管理器判断该用户是否拥有xxx权限,权限管理器从session中取出认证信息对象,返回给realm,realm判断该用户拥有什么权限,封装到授权信息中返回给权限管理器,权限管理器将判断的结果返回给过滤器
4、访问3类资源(xxx添加需要访问service)(对于过滤器来说属于2类资源),在执行方法时,会到达前置通知(esrvice方法上添加注解@RequiresPermissions(“courier:list”)),权限通知寻找权限管理器判断该用户是否拥有xxx权限,权限管理器从session中取出认证信息对象,返回给realm,realm判断该用户拥有什么权限,封装到授权信息中返回给权限管理器,权限管理器将判断的结果返回给权限通知
其实简单来说 /userAction_login ———->请求先到达权限过滤器shiroFilter,先判断是几类资源
登录属于一类资源直接放行到————>userActon中(userAction中调用执行subject对象(使用入口是一个操作入口对象,里面有登陆方法,登出方法,获取当前对象方法)的登陆方法subject.login方法(携带着用户名,密码)
————>subject对象调用 securityManager的login方法 权限管理器不能判断用户和密码是对的需要
————>ream认证授权器(开发人员编写,判断用户名是否存在,拥有什么权限)————>处理完后把认证信息对象返回给securityManager()如果认证信息没有问题,权限管理器会把认证信息存入session(证明认证登陆过了)
可以自定义一个Realm;
@Service("MyRealm")public class MyRealm extends AuthorizingRealm{ //父类接口Realm@Autowired private UserDao ud;@Autowired private RoleService rs;@Autowired private PermissionService ps; @Override //授权 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {User user = (User) principals.getPrimaryPrincipal();SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();List<Role> roles = rs.findByUser(user);if(roles != null && roles.size() > 0){for (Role role : roles) {info.addRole(role.getKeyword());}}List<Permission> permissions = ps.findByUser(user);if(permissions != null && permissions.size() > 0) {for (Permission permission : permissions) {info.addStringPermission(permission.getKeyword());}}return info; } @Override //认证 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken t) throws AuthenticationException {UsernamePasswordToken token = (UsernamePasswordToken) t;String username = token.getUsername();User user = ud.findByUsername(username);if(user != null){/** 参数1:登陆标识* 参数2:正确的密码* 参数3:认证|授权器的名字*/SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(), this.getClass().getName());//ActionContext.getContext().getSession().put("loginUser", user);return info;} else {return null;}}}
登陆完以后访问页面资源(页面资源属于三类资源需要权限),
推荐阅读
- WiFi大提速!WiFi 6和WiFi 6E详解
- 用 C# 实现一个简单的日志框架
- SpringCloud Gateway详解
- 探索3种顶级「集成框架」Apache、Spring和Mule
- 基于阿里Ant Design构建的高颜值开源管理后台UI框架
- 白梅花茶的功效与禁忌,详解玫瑰花茶的功效
- Python流程控制语句详解
- Spring框架是怎么解决Bean之间的循环依赖的
- Python循环语句代码详解:while、for、break
- 非易失性MRAM基本知识详解