You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
189 lines
6.3 KiB
189 lines
6.3 KiB
package com.stone.conf.shiro;
|
|
|
|
import com.stone.conf.filter.AjaxPermissionsAuthorizationFilter;
|
|
import com.stone.conf.session.ShiroSessionListener;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
|
|
import org.apache.shiro.codec.Base64;
|
|
import org.apache.shiro.mgt.RememberMeManager;
|
|
import org.apache.shiro.mgt.SecurityManager;
|
|
import org.apache.shiro.session.SessionListener;
|
|
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
|
|
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
|
|
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
|
|
import org.apache.shiro.web.mgt.CookieRememberMeManager;
|
|
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
|
|
import org.apache.shiro.web.servlet.SimpleCookie;
|
|
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
|
|
import org.crazycake.shiro.RedisCacheManager;
|
|
import org.crazycake.shiro.RedisManager;
|
|
import org.crazycake.shiro.RedisSessionDAO;
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
import org.springframework.context.annotation.Bean;
|
|
import org.springframework.context.annotation.Configuration;
|
|
|
|
import javax.servlet.Filter;
|
|
import java.util.ArrayList;
|
|
import java.util.Collection;
|
|
import java.util.LinkedHashMap;
|
|
import java.util.Map;
|
|
|
|
/**
|
|
* shiro 配置核心类
|
|
*
|
|
* @author zhoujl
|
|
* @since 2018-07-05
|
|
*/
|
|
@Slf4j
|
|
@Configuration
|
|
public class ShiroConfig {
|
|
|
|
@Value("${spring.redis.host}")
|
|
private String host;
|
|
@Value("${spring.redis.port}")
|
|
private int port;
|
|
@Value("${spring.redis.timeout}")
|
|
private int timeout;
|
|
|
|
/**
|
|
* cacheManager 缓存 redis实现
|
|
* 使用的是shiro-redis开源插件
|
|
*/
|
|
private RedisCacheManager cacheManager() {
|
|
RedisCacheManager redisCacheManager = new RedisCacheManager();
|
|
redisCacheManager.setRedisManager(redisManager());
|
|
final String CACHE_KEY = "shiro:cache:";
|
|
redisCacheManager.setKeyPrefix(CACHE_KEY);
|
|
// 配置缓存的话要求放在session里面的实体类必须有个id标识
|
|
redisCacheManager.setPrincipalIdFieldName("id");
|
|
return redisCacheManager;
|
|
}
|
|
|
|
/**
|
|
* 配置shiro redisManager
|
|
* 使用的是shiro-redis开源插件
|
|
*/
|
|
private RedisManager redisManager() {
|
|
RedisManager redisManager = new RedisManager();
|
|
redisManager.setHost(host + ":" + port);
|
|
redisManager.setTimeout(timeout);
|
|
return redisManager;
|
|
}
|
|
|
|
/**
|
|
* RedisSessionDAO shiro sessionDao层的实现 通过redis
|
|
* 使用的是shiro-redis开源插件
|
|
*/
|
|
@Bean
|
|
public RedisSessionDAO redisSessionDAO() {
|
|
RedisSessionDAO redisSessionDAO = new RedisSessionDAO();
|
|
redisSessionDAO.setRedisManager(redisManager());
|
|
redisSessionDAO.setSessionIdGenerator(sessionIdGenerator());
|
|
String SESSION_KEY = "shiro:session:";
|
|
redisSessionDAO.setKeyPrefix(SESSION_KEY);
|
|
int EXPIRE = 1800;
|
|
redisSessionDAO.setExpire(EXPIRE);
|
|
return redisSessionDAO;
|
|
}
|
|
|
|
/**
|
|
* SessionID生成器
|
|
*/
|
|
@Bean
|
|
public ShiroSessionIdGenerator sessionIdGenerator(){
|
|
return new ShiroSessionIdGenerator();
|
|
}
|
|
|
|
/**
|
|
* 配置保存sessionId的cookie
|
|
*/
|
|
@Bean("sessionIdCookie")
|
|
public SimpleCookie sessionIdCookie(){
|
|
//这个参数是cookie的名称
|
|
SimpleCookie simpleCookie = new SimpleCookie("sid");
|
|
//setcookie的httponly属性如果设为true的话,会增加对xss防护的安全系数
|
|
simpleCookie.setHttpOnly(true);
|
|
simpleCookie.setPath("/");
|
|
//maxAge=-1表示浏览器关闭时失效此Cookie
|
|
simpleCookie.setMaxAge(-1);
|
|
return simpleCookie;
|
|
}
|
|
|
|
/**
|
|
* 配置session监听
|
|
*/
|
|
@Bean("sessionListener")
|
|
public ShiroSessionListener sessionListener(){
|
|
return new ShiroSessionListener();
|
|
}
|
|
|
|
/**
|
|
* Session Manager
|
|
* 使用的是shiro-redis开源插件
|
|
*/
|
|
@Bean
|
|
public DefaultWebSessionManager sessionManager() {
|
|
DefaultWebSessionManager webSessionManager = new DefaultWebSessionManager();
|
|
Collection<SessionListener> listeners = new ArrayList<>();
|
|
// 配置监听
|
|
listeners.add(sessionListener());
|
|
webSessionManager.setSessionListeners(listeners);
|
|
webSessionManager.setSessionIdCookie(sessionIdCookie());
|
|
webSessionManager.setSessionDAO(redisSessionDAO());
|
|
// 全局会话超时时间(单位毫秒)
|
|
webSessionManager.setGlobalSessionTimeout(30 * 60 * 1000);
|
|
// 是否开启删除无效的session对象 默认为true
|
|
webSessionManager.setDeleteInvalidSessions(true);
|
|
// 是否开启定时调度器进行检测过期session 默认为true
|
|
webSessionManager.setSessionValidationSchedulerEnabled(true);
|
|
// 设置session失效的扫描时间, 清理用户直接关闭浏览器造成的孤立会话 默认为 1个小时
|
|
webSessionManager.setSessionValidationInterval(60 * 1000);
|
|
// 取消url 后面的 JSESSIONID
|
|
webSessionManager.setSessionIdUrlRewritingEnabled(false);
|
|
return webSessionManager;
|
|
}
|
|
|
|
@Bean("shiroFilter")
|
|
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
|
|
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
|
|
shiroFilterFactoryBean.setSecurityManager(securityManager);
|
|
// 拦截器.
|
|
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
|
|
// 配置不会被拦截的链接 顺序判断
|
|
// <!-- 过滤链定义,从上向下顺序执行,一般将/**放在最为下边 -->:这是一个坑呢,一不小心代码就不好使了;
|
|
// 配置swagger访问路径 加载顺序不可改变
|
|
// <!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
|
|
filterChainDefinitionMap.put("/user/login", "anon");
|
|
filterChainDefinitionMap.put("/**", "user");
|
|
// 自定义拦截器
|
|
Map<String, Filter> filtersMap = new LinkedHashMap<>();
|
|
filtersMap.put("user", new AjaxPermissionsAuthorizationFilter());
|
|
shiroFilterFactoryBean.setFilters(filtersMap);
|
|
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
|
|
return shiroFilterFactoryBean;
|
|
}
|
|
|
|
/**
|
|
* 注入 securityManager
|
|
*/
|
|
@Bean(name = "securityManager")
|
|
public SecurityManager securityManager() {
|
|
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
|
|
// 设置realm.
|
|
securityManager.setRealm(myShiroRealm());
|
|
// 自定义缓存实现 使用redis
|
|
securityManager.setCacheManager(cacheManager());
|
|
// 自定义session管理 使用redis
|
|
securityManager.setSessionManager(sessionManager());
|
|
return securityManager;
|
|
}
|
|
|
|
/**
|
|
* 身份验证器
|
|
*/
|
|
@Bean
|
|
public MyShiroRealm myShiroRealm() {
|
|
return new MyShiroRealm();
|
|
}
|
|
|
|
}
|
|
|