分布式 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 获取及注解权限处理
@Configuration
public 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 权限验证。
评论