一、shiro能干什么事?
shiro 是一个轻量级的权限框架,它相对于Security来说比较简单,能满足我们日常的系统权限要求。
他的主要特性如下:
1.1、身份认证(登录)
1.2、授权(对登录的用户访问接口进行授权)
1.3、数据加密
1.4、Session管理我们的权限信息(将已经登录的用户的权限信息保存在系统中)
1.5、提供默认的过滤器,满足我们的业务需求
二、一个常见的系统使用shiro进行登录以及接口权限验证的完整逻辑(shiro可以有多种用法,在此主要介绍笔者日常用法)
笔者开发中会将shiro与Jwt进行组合使用,进行身份的验证。
1、系统登录
系统有一个全局的拦截器,拦截除不需要拦截请(登录、静态资源等)求之外的所有请求。
登录成功后,用jwt创建一个Token,Token里面包含用户信息以及过期时间等信息,返回前端。
2、系统初始化菜单
初始化菜单请求携带一个Token,这个请求会被系统的拦截器拦截,判断Token是否存在,不存在直接退出到登录页面,如果存在Token,判断当前Token是否准正确并且有效,如果无效,直接退出到登录页面,如果Token有效,则会触发用户查询用户权限信息接口,讲用户的权限信息(List)存入Session中,接下来对比List中的元素与当前访问接口注解的权限信息,如果List中存在当前访问接口中所有的权限信息,则可以访问该方法,否则提示没有权限。
三、shiro核心
3.1、Realm
数据源管理,主要包含两个核心方法
3.1.1、身份验证信息
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
logger.info("————身份认证方法————");
return new SimpleAuthenticationInfo(token, token, "MyRealm");
}
3.1.2、权限信息验证,并将权限信息存入"Session"
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
logger.info("————权限认证————");
//从jwt中解析用户名
return info;
}
3.2、过滤器
@Bean
public ShiroFilterFactoryBean factory(SecurityManager securityManager) {
Map filterChainDefinitionMap = new LinkedHashMap<>();
filterChainDefinitionMap.put("/swagger-ui.html", "anon");
filterChainDefinitionMap.put("/**", "jwt");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
3.3、添加Shiro注解支持,将注解加入Spring Ioc,从而将shiro权限注解加载到Ioc中,提供后期shiro权限校验
@Bean
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new
DefaultAdvisorAutoProxyCreator();
defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
return defaultAdvisorAutoProxyCreator;
}
3.4、SessionManager将shiro进行统一管理,最终注入到Spring的Ioc中
@Bean
public SecurityManager securityManager(ShiroRealm shiroRealm) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
defaultSessionStorageEvaluator.setSessionStorageEnabled(false);
subjectDAO.setSessionStorageEvaluator(defaultSessionStorageEvaluator);
securityManager.setSubjectDAO(subjectDAO);
return securityManager;
}