布式shiro权限验证 二

234 阅读2分钟

这是我参与更文挑战的第19天,活动详情查看: 更文挑战

立个Flag每天写点东西,坚持下去。

分布式shiro权限验证

前篇文章:juejin.cn/post/697663…

本文介绍项目中如何应用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: gitee.com/tg_seahorse…

或分支 gitee.com/tg_seahorse…

paw-authorize-shiro

paw-authorize-shiro-sky

paw-demos-gateway

思考:如何将shiro相关内容提取到一个公共服务,其他页面服务只需要引入此公共服务即可实现shiro权限验证。