【Spring-boot】shiro权限控制

  1. 缓存使用redis,自定义ShiroRedisCache、ShiroRedisCacheManager用于存储用户缓存信息

  2. 自定义MyShiroToken继承自AuthenticationToken。用于用户名密码载体进行认证

public class MyShiroToken implements AuthenticationToken {

    private AdminUser adminUser;

    public MyShiroToken(AdminUser adminUser) {
        this.adminUser = adminUser;
    }

    @Override
    public Object getPrincipal() {
        return adminUser.getAccount();
    }

    @Override
    public Object getCredentials() {
        return adminUser.getPswd();
    }
}
  1. MyShiroRealm用户用户登录验证,及权限校验
public class MyShiroRealm extends AuthorizingRealm {
	
	/**
	* 用以支持自定义token
	*/
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof MyShiroToken;
    }

    /**
     * 获取用户权限信息
     *
     * @param principals
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        //加载用户角色权限信息
        authorizationInfo.addRole(adminRole.getName());
        authorizationInfo.addStringPermission(perm);
       
        return authorizationInfo;
    }

    /**
     * 验证用户登录信息
     *
     * @param token
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        MyShiroToken adminUserToken = (MyShiroToken) token;
        //查询用户信息
        AdminUser adminUser;
        if (null == adminUser) {
            throw new CommonException("用户不存在");
        } 
        return new SimpleAuthenticationInfo(adminUserToken.getPrincipal(), adminUserToken.getCredentials(), getName());
            }
        }
    }
}
  1. 自定义登录、权限filter。用户返回json错误信息
  2. shiro配置信息
public class ShiroConfig {
  
    @Bean
    public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);

        Map<String, Filter> filterMap = Maps.newHashMap();
        filterMap.put("myShiroLoginFilter", new MyShiroLoginFilter());
        shiroFilterFactoryBean.setFilters(filterMap);

        //拦截器
        Map<String, String> filterChainDefinitionMap = Maps.newHashMap();
        //<!-- 过滤链定义,从上向下顺序执行,一般将/**放在最为下边 -->:这是一个坑呢,一不小心代码就不好使了;
        //<!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问
        // roles[管理员]
        //
        // -->
        filterChainDefinitionMap.put("/login", "anon");
        //加载系统权限
        loadPermsUrl(filterChainDefinitionMap);

       shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }

    @Bean
    public MyShiroRealm myShiroRealm() {
        return new MyShiroRealm();
    }

    /**
     * 生成DefaultWebSecurityManager bean,并设置我们自定义的Realm
     *
     * @return
     */
    @Bean
    public DefaultWebSecurityManager securityManager(RedisTemplate<Object, Object> template) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        // 配置 rememberMeCookie 查看源码可以知道,这里的rememberMeManager就仅仅是一个赋值,所以先执行
        securityManager.setRememberMeManager(rememberMeManager());
        // 配置 缓存管理类 cacheManager,这个cacheManager必须要在前面执行,因为setRealm 和 setSessionManage都有方法初始化了cachemanager,看下源码就知道了
        securityManager.setCacheManager(cacheManager(template));
        securityManager.setRealm(myShiroRealm());
        // 配置 sessionManager
        securityManager.setSessionManager(sessionManager());
        return securityManager;
    }

    /**
     * cookie管理对象
     *
     * @return CookieRememberMeManager
     */
    private CookieRememberMeManager rememberMeManager() {
        CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
        cookieRememberMeManager.setCookie(rememberMeCookie());
        // rememberMe cookie 加密的密钥
        cookieRememberMeManager.setCipherKey(Base64.decode("test"));
        return cookieRememberMeManager;
    }

    /**
     * rememberMe cookie 效果是重开浏览器后无需重新登录
     *
     * @return SimpleCookie
     */
    private SimpleCookie rememberMeCookie() {
        // 这里的Cookie的默认名称是 CookieRememberMeManager.DEFAULT_REMEMBER_ME_COOKIE_NAME
        SimpleCookie cookie = new SimpleCookie(CookieRememberMeManager.DEFAULT_REMEMBER_ME_COOKIE_NAME);
        // 是否只在https情况下传输
        cookie.setSecure(false);
        // 设置 cookie 的过期时间,单位为秒,这里为一天
        cookie.setMaxAge(24 * 3600);
        return cookie;
    }

    /**
     * session 管理对象
     *
     * @return DefaultWebSessionManager
     */
    private DefaultWebSessionManager sessionManager() {
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
        // 设置session超时时间,单位为毫秒
        sessionManager.setGlobalSessionTimeout(30 * 60 * 1000);
        sessionManager.setSessionIdCookie(new SimpleCookie("session-id"));
        // 网上各种说要自定义sessionDAO 其实完全不必要,shiro自己就自定义了一个,可以直接使用,还有其他的DAO,自行查看源码即可
        sessionManager.setSessionDAO(new EnterpriseCacheSessionDAO());
        return sessionManager;
    }

    private ShiroRedisCacheManager cacheManager(RedisTemplate template) {
        return new ShiroRedisCacheManager(template);
    }
}

参考:
1,https://shiro.apache.org/spring-boot.html
2,https://segmentfault.com/a/1190000013875092
3,https://pushy.site/2018/11/21/spring-shiro/
4,https://blog.csdn.net/u013615903/article/details/78781166
5,https://www.cnblogs.com/yfzhou/p/9813177.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值