import com.website.company.ServletClass.ShiroSessionListener;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.SessionListener;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
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.RedisManager;
import org.crazycake.shiro.RedisSessionDAO;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
/**
* Shiro 配置类
*
* @author cws
*/
@Configuration
public class ShiroConfig {
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private int port;
@Value("${spring.redis.password}")
private String password;
@Value("${spring.redis.timeout}")
private int timeout;
/**
* session 管理对象
*
* @return DefaultWebSessionManager
*/
@Bean
public DefaultWebSessionManager sessionManager() {
DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
Collection<SessionListener> listeners = new ArrayList<>();
listeners.add(new ShiroSessionListener());
// 设置session超时时间,单位为毫秒
sessionManager.setGlobalSessionTimeout(1800);
sessionManager.setSessionListeners(listeners);
sessionManager.setSessionDAO(redisSessionDAO());
sessionManager.setSessionIdUrlRewritingEnabled(false);
return sessionManager;
}
@Bean
public SecurityManager securityManager(ShiroRealm shiroRealm) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
// 配置 SecurityManager,并注入 shiroRealm
securityManager.setRealm(shiroRealm);
// 配置 rememberMeCookie
securityManager.setRememberMeManager(rememberMeManager());
return securityManager;
}
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
// 设置 securityManager
shiroFilterFactoryBean.setSecurityManager(securityManager);
// 登录的 url
shiroFilterFactoryBean.setLoginUrl("/api/user/login");
// 登录成功后跳转的 url
shiroFilterFactoryBean.setSuccessUrl("/index");
// 未授权 url 弹回主页 设置没有授权的页面
shiroFilterFactoryBean.setUnauthorizedUrl("/");
LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
// 设置免认证 url
String[] anonUrls = StringUtils.splitByWholeSeparatorPreserveAllTokens("/,/druid/**," +
"/getIndexNews," +
"/static/**," +
"/area," +
"/sitemap," +
"/index," +
"/app," +
"/functionMoblie," +
"/functionShowMoreAjax," +
"/functionClass," +
"/function/**," +
"/about," +
"/patentAjax," +
"/search/**," +
"/searchNews," +
"/product/**," +
"/newsDetail," +
"/newsList," +
"/newsLists," +
"/newsListPage," +
"/message/**," +
"/rss.xml," +
"/sitemap.xml," +
//关于swagger的配置
"/swagger-ui.html/**," +
"/swagger-resources/**," +
"/v2/api-docs/**," +
"/webjars/**," +
"/swagger-resources/configuration/ui/**," +
"/swagger-resources/configuration/security/**," +
"/getToken," +
"/robots.txt," +
"/patentList," +
"/yjv0lnjjCD.txt," +
"/404", ",");
for (String url : anonUrls) {
filterChainDefinitionMap.put(url, "anon");
}
// 配置退出过滤器,其中具体的退出代码 Shiro已经替我们实现了
filterChainDefinitionMap.put("/logout", "logout");
// 除上以外所有 url都必须认证通过才可以访问,未通过认证自动访问 LoginUrl
filterChainDefinitionMap.put("/**", "user");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
@Bean(name = "lifecycleBeanPostProcessor")
public static LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
// shiro 生命周期处理器
return new LifecycleBeanPostProcessor();
}
/**
* shiro 中配置 redis 缓存
*
* @return RedisManager
*/
private RedisManager redisManager() {
RedisManager redisManager = new RedisManager();
// 缓存时间,单位为秒
//redisManager.setExpire(febsProperties.getShiro().getExpireIn()); // removed from shiro-redis v3.1.0 api
redisManager.setHost(host);
redisManager.setPort(port);
if (StringUtils.isNotBlank(password)) {
redisManager.setPassword(password);
}
redisManager.setTimeout(timeout);
return redisManager;
}
/**
* rememberMe cookie 效果是重开浏览器后无需重新登录
*
* @return SimpleCookie
*/
private SimpleCookie rememberMeCookie() {
// 设置 cookie 名称,对应 login.html 页面的 <input type="checkbox" name="rememberMe"/>
SimpleCookie cookie = new SimpleCookie("rememberMe");
// 设置 cookie 的过期时间,单位为秒,这里为一天
cookie.setMaxAge(86400);
return cookie;
}
/**
* cookie管理对象
*
* @return CookieRememberMeManager
*/
private CookieRememberMeManager rememberMeManager() {
CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
cookieRememberMeManager.setCookie(rememberMeCookie());
// rememberMe cookie 加密的密钥
cookieRememberMeManager.setCipherKey(Base64.decode("4AvVhmFLUs0KTA3Kprsdag=="));
return cookieRememberMeManager;
}
/**
* DefaultAdvisorAutoProxyCreator 和 AuthorizationAttributeSourceAdvisor 用于开启 shiro 注解的使用
* 如 @RequiresAuthentication, @RequiresUser, @RequiresPermissions 等
*
* @return DefaultAdvisorAutoProxyCreator
*/
@Bean
@DependsOn({"lifecycleBeanPostProcessor"})
public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
advisorAutoProxyCreator.setProxyTargetClass(true);
return advisorAutoProxyCreator;
}
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
@Bean
public RedisSessionDAO redisSessionDAO() {
RedisSessionDAO redisSessionDAO = new RedisSessionDAO();
redisSessionDAO.setRedisManager(redisManager());
return redisSessionDAO;
}
}