Spring Boot集成Shiro

发布时间:2023-11-22 08:30

前言

一个简单的Spring Boot集成Shiro的demo。

1. 准备

一个Spring Boot项目。

2. 引入依赖

        <!-- shiro -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring-boot-web-starter</artifactId>
            <version>1.8.0</version>
        </dependency>

3. 编码

3.1. 重写realm

public class CustomRealm extends AuthorizingRealm {

    /**
    * 盐值
    */
    private static final String SALT = "as%j#Dw2";
    
    @Resource
    private UserMapper userMapper;
    @Resource
    private UserRoleMapper userRoleMapper;
    @Resource
    private RolePermissionMapper rolePermissionMapper;

    // 通过principals从数据源查询用户权限数据
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        User user = (User) principals.getPrimaryPrincipal();
        List<Role> roleInfos = userRoleMapper.selectRolesByUserId(user.getId());
        List<String> roles = new ArrayList<>();
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        for (Role roleInfo : roleInfos) {
            roles.add(roleInfo.getCode());
            info.addStringPermissions(rolePermissionMapper.selectPermissionsByRoleId(roleInfo.getId()));
        }
        info.addRoles(roles);
        return info;
    }

    // 通过token从数据源查询用户身份验证数据
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        String username = token.getUsername();
        User user = userMapper.selectOne(new QueryWrapper<User>().lambda().eq(User::getUsername, username));
        if (user == null)
            throw new UnknownAccountException();
        return new SimpleAuthenticationInfo(user, user.getPassword(), ByteSource.Util.bytes(SALT), this.getName());
    }
}

3.2. 编写配置类

@Configuration
public class ShiroConfig {

    /**
     * 自定义凭证匹配器
     */
    @Bean
    public HashedCredentialsMatcher hashedCredentialsMatcher() {
        HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
        // 加密方式
        matcher.setHashAlgorithmName(new Md5Hash().getAlgorithmName());
        // 散列迭代次数
        matcher.setHashIterations(7);
        return matcher;
    }

    /**
     * realm
     */
    @Bean
    public Realm realm(@Autowired HashedCredentialsMatcher hashedCredentialsMatcher) {
        CustomRealm realm = new CustomRealm();
        // 设置凭证匹配器
        realm.setCredentialsMatcher(hashedCredentialsMatcher);
        return realm;
    }

    /**
     * 请求过滤链。过滤链与注解方式同一功能的两种实现,相互独立,选其一即可。
     */
    @Bean
    public ShiroFilterChainDefinition shiroFilterChainDefinition() {
        DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition();
        chainDefinition.addPathDefinition("/users", "authc, perms[user:create]");
        return chainDefinition;
    }

    /**
     * 安全管理器
     */
    @Bean
    public DefaultWebSecurityManager defaultWebSecurityManager(Realm realm) {
        return new DefaultWebSecurityManager(realm);
    }

    /**
     * 过滤器工厂bean
     */
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(ShiroFilterChainDefinition chainDefinition, DefaultWebSecurityManager securityManager) {
        ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
        // 设置安全管理器
        factoryBean.setSecurityManager(securityManager);
        // 设置过滤链
        factoryBean.setFilterChainDefinitionMap(chainDefinition.getFilterChainMap());
        // 设置登录页
        factoryBean.setLoginUrl("/login");
        return factoryBean;
    }
}

3.3. 编写功能接口

    @PostMapping
    // @RequiresPermissions("user:create")
    public Result<?> create(@RequestBody CreateUserDTO dto) {
        return userService.create(dto);
    }

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号