shiro-spring-boot-web-starter 1.6.0版本[SpringBoot微服务框架]
提前说好,说我缺文件的,一般那是不中要的

ShiroFreshService

/*** 初始化权限 -> 拿全部权限** @param :* @return: java.util.Map<java.lang.String, java.lang.String>*/Map<String, String> loadFilterChainDefinitionMap();/*** 重新构建权限过滤器* 一般在修改了用户角色、用户等信息时,需要再次调用该方法*/void reCreateFilterChains(ShiroFilterFactoryBean shiroFilterFactoryBean);

ShiroFreshServiceImpl

@Slf4j
@Service
public class ShiroFreshServiceImpl implements ShiroFreshService {@Autowiredprivate RoleMenuService roleMenuService;@Autowiredprivate ConfigProperties configProperties;private static ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();private static Lock writeLock = readWriteLock.writeLock();@Overridepublic Map<String, String> loadFilterChainDefinitionMap() {Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();filterChainDefinitionMap.put("/validcaptcha", "anon");//验证验证码filterChainDefinitionMap.put("/validate", "anon");filterChainDefinitionMap.put("/login", "anon");filterChainDefinitionMap.put("/logout", "anon");filterChainDefinitionMap.put("/css/** ", "anon");filterChainDefinitionMap.put("/image/**", "anon");filterChainDefinitionMap.put("/js/**", "anon");filterChainDefinitionMap.put("/error/**", "anon");filterChainDefinitionMap.put("/plugins/**", "anon");filterChainDefinitionMap.put("/favicon.ico", "anon");filterChainDefinitionMap.put("/401", "anon");filterChainDefinitionMap.put("/403", "anon");filterChainDefinitionMap.put("/404", "anon");filterChainDefinitionMap.put("/500", "anon");List<UrlRoleVo> urlRoleVoList = roleMenuService.findAllUrlRolesList();String roleCode = configProperties.getAdminRoleCode();if (CollectionUtils.isNotEmpty(urlRoleVoList)) {urlRoleVoList.forEach(ur -> filterChainDefinitionMap.put(ur.url(), "roles[" + ur.role().toUpperCase() + "," + roleCode + "]"));}//对所有用户认证filterChainDefinitionMap.put("/**", "authc");return filterChainDefinitionMap;}@Overridepublic void reCreateFilterChains(ShiroFilterFactoryBean shiroFilterFactoryBean) {writeLock.lock();try {AbstractShiroFilter shiroFilter = null;try {shiroFilter = (AbstractShiroFilter) shiroFilterFactoryBean.getObject();} catch (Exception e) {log.error("ShiroFreshServiceImpl刷新权限异常", e);throw new HdapException(GET_SHIRO_FILTER);}PathMatchingFilterChainResolver filterChainResolver = (PathMatchingFilterChainResolver) shiroFilter.getFilterChainResolver();DefaultFilterChainManager filterChainManager = (DefaultFilterChainManager) filterChainResolver.getFilterChainManager();//加载数据Map<String, String> filterChainDefinitionMap = loadFilterChainDefinitionMap();// 清空老的权限控制filterChainManager.getFilterChains().clear();shiroFilterFactoryBean.getFilterChainDefinitionMap().clear();shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);// 重新构建生成for (Map.Entry<String, String> filterChainDefinition : filterChainDefinitionMap.entrySet()) {filterChainManager.createChain(filterChainDefinition.getKey(), filterChainDefinition.getValue());}} finally {writeLock.unlock();}}
}

Config

/*** 参考【仅作参考】* 1. https://blog.csdn.net/New_Yao/article/details/100769385* 2. https://www.cnblogs.com/zhengqing/p/11603824.html* *.https://shiro.apache.org/spring-boot.html*/
@Slf4j
@Configuration
public class SysUserSecurityConfig {@Value("${server.servlet.session.timeout}")@DurationUnit(ChronoUnit.SECONDS)private Duration timeout = Duration.ofMinutes(30L);@Autowiredprivate ShiroFreshService shiroFreshService;/*** 设置用于匹配密码的CredentialsMatcher* SHA-256** @return*/@Beanpublic HashedCredentialsMatcher credentialsMatcher() {HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();// 散列算法,这里使用更安全的sha256算法credentialsMatcher.setHashAlgorithmName(Sha256Hash.ALGORITHM_NAME);// 散列迭代次数credentialsMatcher.setHashIterations(1024);return credentialsMatcher;}/*** 配置自定义Realm** @return*/@Beanpublic SysUserRealm sysUserRealm() {SysUserRealm sysUserRealm = new SysUserRealm();// 配置使用哈希密码匹配sysUserRealm.setCredentialsMatcher(credentialsMatcher());// 启用身份验证缓存,即缓存AuthenticationInfo信息,默认falsesysUserRealm.setAuthenticationCachingEnabled(true);// 启用授权缓存,即缓存AuthorizationInfo信息,默认false,一旦配置了缓存管理器,授权缓存默认开启sysUserRealm.setAuthorizationCachingEnabled(true);return sysUserRealm;}/*** 内存中的缓存管理器** @return*/@Beanprotected CacheManager cacheManager() {return new MemoryConstrainedCacheManager();}/*** 配置会话管理器,设定会话超时及保存** @return*/@Bean("sessionManager")public SessionManager sessionManager() {DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();//全局会话超时时间(单位毫秒),默认30分钟sessionManager.setGlobalSessionTimeout(timeout.getSeconds() * 1000);//是否开启删除无效的session对象  默认为truesessionManager.setDeleteInvalidSessions(true);//是否开启定时调度器进行检测过期session 默认为truesessionManager.setSessionValidationSchedulerEnabled(true);//设置session失效的扫描时间, 清理用户直接关闭浏览器造成的孤立会话 默认为 1个小时//设置该属性 就不需要设置 ExecutorServiceSessionValidationScheduler 底层也是默认自动调用ExecutorServiceSessionValidationScheduler//暂时设置为 5秒 用来测试// sessionManager.setSessionValidationInterval(5000);//禁用URL会话重写sessionManager.setSessionIdUrlRewritingEnabled(false);return sessionManager;}/*** 安全控制中心** @return*/@Bean("securityManager")public SessionsSecurityManager securityManager() {DefaultWebSecurityManager defaultSecurityManager = new DefaultWebSecurityManager();//配置自定义RealmdefaultSecurityManager.setRealm(sysUserRealm());//内存中的缓存管理器defaultSecurityManager.setCacheManager(cacheManager());//配置会话管理器,设定会话超时及保存defaultSecurityManager.setSessionManager(sessionManager());return defaultSecurityManager;}/*** 配置Filter过滤器** @return*/@Beanpublic ShiroFilterFactoryBean shiroFilterFactoryBean() {ShiroFilterFactoryBean filterFactoryBean = new ShiroFilterFactoryBean();// 必须设置SecuritManagerfilterFactoryBean.setSecurityManager(securityManager());//用户未登录时跳转的请求路径filterFactoryBean.setLoginUrl(SysRoute.REDIRECT_LOGIN);//用户未登录成功跳转的请求路径filterFactoryBean.setSuccessUrl("/");//用户没有访问权限时跳转的请求路径filterFactoryBean.setUnauthorizedUrl("/401");Map<String, Filter> filters = new LinkedHashMap();//配置拦截器,实现无权限返回(过滤器制定)filters.put("authc", new MyFormAuthenticationFilter());filters.put("roles", new MyRolesAuthorizationFilter());filterFactoryBean.setFilters(filters);Map<String, String> filterChainDefinitionMap = shiroFreshService.loadFilterChainDefinitionMap();filterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);return filterFactoryBean;}}

realm

@Slf4j
public class SysUserRealm extends AuthorizingRealm {@Autowiredprivate UserService userService;@Autowiredprivate EmpService empService;@Autowiredprivate ConfigProperties configProperties;/*** 认证*/@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) {String username = (String) authenticationToken.getPrincipal();log.info("#SHIRO#认证" + username);SysUser sysUser = userService.getSysUserOneByUsername(username);if (ObjectUtils.isNotEmpty(sysUser)) {//status 用户状态,0,离职,1:正常,2:禁用switch (sysUser.status()) {case 0:throw new UserStatusException(new ErrCode(10001, "用户离职状态,禁止登录"));case 2:throw new UserStatusException(new ErrCode(10002, "用户锁定状态,禁止登录"));default:break;}return new SimpleAuthenticationInfo(username, sysUser.password(), ByteSource.Util.bytes(username), getName());}throw new UnknownAccountException("用户名或密码不存在");}/*** 授权信息*/@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {log.info("#SHIRO#授权");if (principalCollection == null) {throw new AuthorizationException("用户凭证不能为空");}SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();String username = (String) getAvailablePrincipal(principalCollection);//登录用户角色Set<String> roles = new HashSet<>();List<String> roleCodeList = empService.getRoleCodeListByUsername(username);if (CollectionUtils.isNotEmpty(roleCodeList)) {roles.addAll(roleCodeList.stream().map(String::toUpperCase).collect(Collectors.toSet()));}SysUser sysUser = userService.getSysUserOneByUsername(username);if (ObjectUtils.isNotEmpty(sysUser) && configProperties.getAdminId().equals(sysUser.id())) {roles.add(configProperties.getAdminRoleCode());}info.setRoles(roles);return info;}/*** 自定义方法:清除所有 授权缓存*/public void clearAllCachedAuthorizationInfo() {getAuthorizationCache().clear();}}

MyFormAuthenticationFilter

/*** Name: 需要登录认证* Description:* User: bambo* Date: 2020-07-16* Time: 16:12*/
@Slf4j
public class MyFormAuthenticationFilter extends FormAuthenticationFilter {/*** @param request* @param response* @return true-继续往下执行,false-该filter过滤器已经处理,不继续执行其他过滤器* @throws IOException*/@Overrideprotected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws IOException {log.info("#SHIRO#认证处理(1),onAccessDenied:MyFormAuthenticationFilter");Subject subject = this.getSubject(request, response);if (subject.getPrincipal() == null) {log.info("#SHIRO#认证处理(2-1),凭证丢失【重新登录】:MyFormAuthenticationFilter");if (AjaxBoolUtil.isAjax((HttpServletRequest) request)) {response.setCharacterEncoding(AjaxBoolUtil.CHARACTER_ENCODING);response.setContentType(AjaxBoolUtil.CONTENT_TYPE);response.getWriter().write(GsonUtil.toString(Result.right("请重新登录!")));} else {((HttpServletResponse) response).sendRedirect(SysRoute.LOGIN_LOGIN);}} else {log.info("#SHIRO#认证处理(2-2),未经认证【401】:MyFormAuthenticationFilter");if (AjaxBoolUtil.isAjax((HttpServletRequest) request)) {response.setCharacterEncoding(AjaxBoolUtil.CHARACTER_ENCODING);response.setContentType(AjaxBoolUtil.CONTENT_TYPE);response.getWriter().write(GsonUtil.toString(Result.right("未经认证!")));} else {WebUtils.toHttp(response).sendError(401);}}return false;}}

MyRolesAuthorizationFilter

@Slf4j
public class MyRolesAuthorizationFilter extends AuthorizationFilter {@Overridepublic boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue)throws IOException {log.info("#SHIRO#授权效验(1):MyRolesAuthorizationFilter");final Subject subject = getSubject(request, response);if (subject.getPrincipal() == null) {return false;}final String[] rolesArray = (String[]) mappedValue;if (rolesArray == null || rolesArray.length == 0) {log.info("#SHIRO#(2-1),无指定角色时,无需检查,允许访问:MyRolesAuthorizationFilter");return true;}for (String roleName : rolesArray) {if (subject.hasRole(roleName)) {log.info("#SHIRO#(2-2),有匹配角色,允许访问:MyRolesAuthorizationFilter");return true;}}log.info("#SHIRO#未经授权(3),无授权:MyRolesAuthorizationFilter");return false;}@Overridepublic boolean onAccessDenied(ServletRequest request, ServletResponse response) throws IOException {log.info("#SHIRO#授权处理(1),onAccessDenied:MyRolesAuthorizationFilter");Subject subject = this.getSubject(request, response);if (subject.getPrincipal() == null) {log.info("#SHIRO#授权处理(2-1),凭证丢失【重新登录】:MyRolesAuthorizationFilter");if (AjaxBoolUtil.isAjax((HttpServletRequest) request)) {response.setCharacterEncoding(AjaxBoolUtil.CHARACTER_ENCODING);response.setContentType(AjaxBoolUtil.CONTENT_TYPE);response.getWriter().write(GsonUtil.toString(Result.right("请重新登录!")));} else {((HttpServletResponse) response).sendRedirect(SysRoute.LOGIN_LOGIN);}} else {log.info("#SHIRO#授权处理(2-2),未经授权【403】:MyRolesAuthorizationFilter");if (AjaxBoolUtil.isAjax((HttpServletRequest) request)) {response.setCharacterEncoding(AjaxBoolUtil.CHARACTER_ENCODING);response.setContentType(AjaxBoolUtil.CONTENT_TYPE);response.getWriter().write(GsonUtil.toString(Result.right("未经授权!")));} else {WebUtils.toHttp(response).sendError(403);}}return false;}
}

Sha256PasswordHelper

public class Sha256PasswordHelper {public static String encryption(String username, String pwd) {return new Sha256Hash(pwd, username, 1024).toString();}
}

ShiroBeanLifecycleConfig

@Configuration
public class ShiroBeanLifecycleConfig {/*** 安全框架shiro的bean生命周期* LifecycleBeanPostProcessor将Initializable和Destroyable的实现类统一在其内部自动分别调用了Initializable.init()和Destroyable.destroy()方法,* 从而达到管理shiro bean生命周期的目的。** @return*/@Bean("lifecycleBeanPostProcessor")public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {return new LifecycleBeanPostProcessor();}/*** APC 自动代理创建器* 扫描上下文,寻找所有的Advistor(通知器),将这些Advisor应用到所有符合切入点的Bean中。所以必须在lifecycleBeanPostProcessor创建之后创建。** @return* @DependsOn({"lifecycleBeanPostProcessor"}) 保证创建DefaultAdvisorAutoProxyCreator 之前先创建LifecycleBeanPostProcessor 。*/@Bean@DependsOn({"lifecycleBeanPostProcessor"})public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();//使用cglib方式为Action对象创建代理对象[pom.xml如果引入了aop-starter依赖包装,就需要做出更改]advisorAutoProxyCreator.setProxyTargetClass(true);return advisorAutoProxyCreator;}
}

ToolDateUtil

@Slf4j
public class ToolDateUtil {//LocalDate -> Datepublic static Date asDate(LocalDate localDate) {return Date.from(localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());}//LocalDateTime -> Datepublic static Date asDate(LocalDateTime localDateTime) {return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());}//String -> Datepublic static Date asYMDDate(String date) {DateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");try {return fmt.parse(date);} catch (ParseException e) {log.error(e.getMessage(), e);return null;}}//Date -> LocalDatepublic static LocalDate asLocalDate(Date date) {return Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDate();}//Date -> LocalDateTimepublic static LocalDateTime asLocalDateTime(Date date) {return Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDateTime();}//Date -> Stringpublic static String YmdHmToString(Date date) {SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm");return formatter.format(date);}//Date -> Stringpublic static String YmdToString(Date date) {SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");return formatter.format(date);}//String -> Datepublic static Date asMinDate(String ymd) {DateTimeFormatter dtfYMD = DateTimeFormatter.ofPattern("yyyy-MM-dd");LocalDate date = LocalDate.parse(ymd, dtfYMD);return asDate(LocalDateTime.of(date, LocalTime.MIN));}//String -> Datepublic static Date asMaxDate(String ymd) {DateTimeFormatter dtfYMD = DateTimeFormatter.ofPattern("yyyy-MM-dd");LocalDate date = LocalDate.parse(ymd, dtfYMD);return asDate(LocalDateTime.of(date, LocalTime.MAX));}}

调用

 @Autowiredprivate ShiroFilterFactoryBean shiroFilterFactoryBean;shiroFreshService..reCreateFilterChains(shiroFilterFactoryBean)

Shiro在线刷新权限相关推荐

  1. vb6编写用户权限_仅需三行代码,即可让Apache Shiro接管Swagger权限认证

    有很多文章提到,在生产环境中需要关闭Swagger功能,防止系统资源泄露.今天,我结合自己开发过程中的经验,分享一个只需几行代码便可实现让Apache Shiro接管Swagger认证和授权的方法.如 ...

  2. Shiro角色和权限管理

    Shiro角色和权限管理 在resources下创建shiro.ini文件,用于存储数据,也可以将数据存于数据库,这里我采用shiro.ini文件,内容如下: [users] zhangsan=z3, ...

  3. 大众服务器维护是,上海大众ODIS在线刷新操作说明

    镜像服务器(MS2) ·MS2已完成配置: 在使用ODIS执行刷新活动时,保证诊断仪 ·与本地MS2的连接.不知如何配置MS2:请咨询400 166 2886 ·MS2目前存在问题,无法使用: 1. ...

  4. 数据级的权限管理和功能级的权限管理的区别,不使用框架(shiro,springsecurity)做权限设计的思考

    1 数据级的权限管理和功能级的权限管理 引自:http://www.iteye.com/problems/97374 功能级权限,有大有小.大的可以直接包括一个业务模块,小的可以是一个按钮.一般的功能 ...

  5. MariaDB数据库刷新权限表命令

    当授权或者修改用户权限时,往往不会马上生效的这是因为数据库没有马上去更新权限相关的表,而是在内存中所以一般都会使用更新权限表,来实现马上更新 MariaDB数据库刷新权限表命令 flush privi ...

  6. 大众服务器维护,上海大众ODIS在线刷新操作说明

    镜像服务器(MS2) ·MS2已完成配置: 在使用ODIS执行刷新活动时,保证诊断仪 ·与本地MS2的连接.不知如何配置MS2:请咨询400 166 2886 ·MS2目前存在问题,无法使用: 1. ...

  7. springmvc+spring+mybatis+maven项目集成shiro进行用户权限控制【转】

    项目结构: 1.maven项目的pom中引入shiro所需的jar包依赖关系 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ...

  8. SpringBoot 整合 Shiro 实现动态权限加载更新+ Session 共享 + 单点登录

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 来源: juejin.im/post/5d087d60518825 ...

  9. (2)shiro角色资源权限

    一般在web系统权限设计中,一般分为三个维度,用户,角色,资源,一个用户可以拥有多个角色,比如说可以是老师,也可以是班主任,一个角色也可以拥有多个资源. 比如老师同时拥有查看班级学生和批改作业的资源, ...

  10. shiro 角色与权限的解读

    1.为什么 shiro 有了<角色>后,还要设置<角色权限>呢?(问题) 思考:设置好角色了,那么就代表什么操作都可以执行了吗? 理解:如果上边回答是的话,那么只是<角色 ...

最新文章

  1. PRML-系列二之2.3
  2. 钉钉api 获取 accesstoken_钉钉开放平台第三方 Python SDK,快速实现钉钉API开发
  3. HBase原理和安装
  4. 自动化测试C语言程序,自动化测试程序之一自定义键盘的模拟测试程序(C语言)...
  5. boid模型的Matlab程序,基于Boid模型以及吸引—排斥模型的沙丁鱼集群运动行为模拟...
  6. 我的开源项目:AAC格式分析器
  7. WebService—规范介绍和几种实现WebService的框架介绍
  8. sqlserver200864位下载_SQL Server 2008 官方简体中文正式版
  9. 简单的中文分词系统httpcws
  10. HYSBZ 1406 密码箱
  11. 囍游记----[转_]
  12. All matches were filtered out by modular filtering for argument: mysql-community-server
  13. 两个子组件之间的传值
  14. 你问我答:小匠,如何像你一样,做一个订阅号挣它 100 W?
  15. 架构师之spring------@Autowire注入多泛型实例 can not cast to的问题解决
  16. woo 10到任意进制,任意数值到十进制 之间转换
  17. LED32*32点阵书写屏设计方案
  18. java类名遵从法_程序员必知的Java基础:5条命名规范和8种数据类型归纳
  19. system thread exception not handled
  20. Word行距怎么设置?基础设置,必会的4个方法!

热门文章

  1. 视频流媒体直播系统---------BroadVision WebTV
  2. 全球及中国第三方物流行业竞争格局与十四五运作模式咨询报告2022版
  3. 2018年世界人口排名及国土面积
  4. LED 发光二极管压降
  5. 电器元件——LM7805
  6. c++11总结21——atomic_flag
  7. dlp监控开除员工_说一说DLP的那些事儿
  8. 从罗京、张艺谋看CCTV的知识管理
  9. airflow实现Java定时任务,AirFlow定时调度执行Talend ETL任务
  10. dokcer基础命令-详解