分布式 shiro 权限验证
本文介绍项目中如何应用 shiro 做分布权限。
因为 shiro 是基于单服务的,session 共享后,可做多服务。分布式权限,需要使用相同的域名(session 的作用域)。
基本思路,通过统一的登录服务进行登录,通过 iframe 框架进行菜单功能跳转。
构建首页页面结构
header.html
<!DOCTYPE html><html lang="en"><body><div th:fragment="header"> <div>header</div></div>
</body></html>
复制代码
Navigator.html 菜单可通过后台获取数据构建,路径位网关域名的绝对路径,target 到 iframe,此处域名以 localhost 为例。
<!DOCTYPE html><html lang="en"><body><div th:fragment="navigator"> <div>navigator</div> <div> <li><a href="http://localhost:9000/paw-authorize-shiro-api/home" target="mainFrame">a link</a></li> <li><a href="http://localhost:9000/paw-sky-api/index" target="bodyFrame">sky</a></li> </div></div></body></html>
复制代码
最终 index.html 可通过现有的一些前端框架构建 上 header,左菜单栏,右工作栏的美观布局。
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Shiro Session</title>
</head><body><script> // window.location.href='http://172.20.25.8:9000/paw-authorize-shiro-api/home';</script>
<div style="width: 100%;height: 100px"> <div th:include="../templates/header"></div></div>
<div style="display: flex"> <div style="width: 200px;height: 100%"> <div th:include="../templates/navigator"></div> </div>
<div style="width: 1500px;height: 1000px"> <iframe src="home" name="mainFrame" width="100%" height="100%" ></iframe> </div></div></body></html>
复制代码
login 之后跳转到 index.html,之后整个页面框架不变,通过菜单调用相应的微服务,工作区 mainFrame 内容转换。
菜单<li><a href="http://localhost:9000/paw-sky-api/index" target="bodyFrame">sky</a></li>的服务
配置 shiroConfig,登录地址指向登录服务,除登录服务外不需要配置登录页面及 index 页面,login 也交由登录服务处理
shiro: loginUrl: http://localhost:8081/login successUrl: http://localhost:8081/index
复制代码
配置类,进行 session 获取及注解权限处理
@Configurationpublic class ShiroConfig { public ShiroConfig() { }
@Bean public UserRealm userRealm() { UserRealm userRealm = new UserRealm(); userRealm.setCredentialsMatcher(this.credentialsMatcher()); return userRealm; }
@Bean public ShiroFilterChainDefinition shiroFilterChainDefinition() { DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition(); chainDefinition.addPathDefinition("/captcha", "anon"); chainDefinition.addPathDefinition("/logout", "anon"); chainDefinition.addPathDefinition("/layuiadmin/**", "anon"); chainDefinition.addPathDefinition("/druid/**", "anon"); chainDefinition.addPathDefinition("/api/**", "anon"); chainDefinition.addPathDefinition("/login", "anon"); chainDefinition.addPathDefinition("/**", "authc"); return chainDefinition; }
@Bean public HashedCredentialsMatcher credentialsMatcher() { HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher(); credentialsMatcher.setHashAlgorithmName("SHA-256"); credentialsMatcher.setStoredCredentialsHexEncoded(false); credentialsMatcher.setHashIterations(1024); return credentialsMatcher; }
@Bean public SessionsSecurityManager securityManager() { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();// securityManager.setRealm(this.userRealm()); return securityManager; }
复制代码
至此整个分布式页面权限完成。
gitee: https://gitee.com/tg_seahorse/paw-demos/tree/master
或分支 https://gitee.com/tg_seahorse/paw-demos/tree/paw-authorize/
paw-authorize-shiro
paw-authorize-shiro-sky
paw-demos-gateway
思考:如何将 shiro 相关内容提取到一个公共服务,其他页面服务只需要引入此公共服务即可实现 shiro 权限验证。
评论