package com.foen.security;
import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.code.kaptcha.util.Config;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.SecurityManager;
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.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Properties;
/**
* shiro权限配置工厂类
* Created by foen
*/
@Configuration
@EnableTransactionManagement
public class ShiroConfiguration {
private final Log logger = LogFactory.getLog(ShiroConfiguration.class);
@Bean(name = "myShiroRealm")
public FoenShiroRealm myShiroRealm(){
FoenShiroRealm realm = new FoenShiroRealm();
//前台输入的为mD5加密的
// HashedCredentialsMatcher md5 = new HashedCredentialsMatcher("MD5");
//加密码算法
realm.setCredentialsMatcher(hashedCredentialsMatcher());
return realm;
}
/**
* 加密码算法
* @return HashedCredentialsMatcher
*/
@Bean(name="hashedCredentialsMatcher")
public HashedCredentialsMatcher hashedCredentialsMatcher(){
HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
hashedCredentialsMatcher.setHashAlgorithmName("md5");//加密算法
// hashedCredentialsMatcher.setHashIterations(2);//散列的次数
return hashedCredentialsMatcher;
}
@Bean(name = "lifecycleBeanPostProcessor")
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor(){
return new LifecycleBeanPostProcessor();
}
@Bean
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator(){
DefaultAdvisorAutoProxyCreator creator = new DefaultAdvisorAutoProxyCreator();
creator.setProxyTargetClass(true);
return creator;
}
/**
*
* @param realm
* @return
*/
@Bean(name = "securityManager")
public SecurityManager securityManager(FoenShiroRealm realm){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setSessionManager(new StatelessSessionManager());//自定义,重写StatelessSessionManager类
//设置realm,多个realm可以用securityManager.setRealms();
securityManager.setRealm(realm);
//配置记住我
//securityManager.setRememberMeManager(cookieRememberMeManager());
//设置认证策略
//ModularRealmAuthenticator authenticator = new ModularRealmAuthenticator();
//authenticator.setAuthenticationStrategy(new AtLeastOneSuccessfulStrategy());
//securityManager.setAuthenticator(authenticator);
//注入缓存管理器
//securityManager.setCacheManager(ehCacheManager());
return securityManager;
}
/**
* 开户shiro aop注解支持(controller注解:RequiresPermisssions("userInfo:add"):权限表:userinfo:view)
* @param securityManager
* @return AuthorizationAttributeSourceAdvisor
*/
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
advisor.setSecurityManager(securityManager);
return advisor;
}
/**
* shirofilter,使用springboot时name可以随设置,不需要context设置,
* 定义shiro工厂类
* 1.定义ShiroFilterFactoryBean
* 2.设置SecurityManager
* 3.配置拦截器
* 4.返回ShiroFilterFactoryBean
*/
@Bean(name = "shiroFilter")
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager){
ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
factoryBean.setSecurityManager(securityManager);
factoryBean.setLoginUrl("/login");
factoryBean.setSuccessUrl("/index");
factoryBean.setUnauthorizedUrl("/403");
loadShiroFilterChain(factoryBean);
return factoryBean;
}
@Bean
public ShiroDialect shiroDialect() {
return new ShiroDialect();
}
/**
* 加载ShiroFilter权限控制规则
* 这块代码是负责拦截的
* 也就是说,如果当前登陆的人,不符合访问某个url的访问权限条件的,直接给他弹开
* 也就是分配谁能访问谁
*
*/
private void loadShiroFilterChain(ShiroFilterFactoryBean factoryBean) {
Map<String, String> filterChainMap = new LinkedHashMap<String, String>();
Map<String, String> filterChainMapTemp = new LinkedHashMap<String, String>();
filterChainMap.put("/login", "anon");
filterChainMap.put("/login/check", "anon");
filterChainMap.put("/login/crmCheck", "anon");
filterChainMap.put("/403", "anon");
filterChainMap.put("/assets/**", "anon");
filterChainMap.put("/layui/**", "anon");
filterChainMap.put("/js/**", "anon");
filterChainMap.put("/prism/**", "anon");
filterChainMap.put("/upload/**", "anon");
//给SpringBootAdmin开启权限
filterChainMap.put("/monitor/**", "anon");
filterChainMap.put("/api/**", "anon");
filterChainMap.put("/health/**", "anon");
filterChainMap.put("/favicon.icon", "anon");
filterChainMap.put("/crm/crmLogin", "anon");
//权限分配
filterChainMap.put("/admin/**", "authc");
filterChainMap.put("/role/**", "authc");
filterChainMap.put("/user/**", "authc");
filterChainMap.put("/dict/**", "authc");
filterChainMap.put("/aop/**", "authc");
filterChainMap.put("/car/**", "authc");
filterChainMap.put("/menu/**", "authc");
filterChainMap.put("/crm/**", "authc");
//行为分配
filterChainMap.put("/notice/notice_create", "authc");
filterChainMap.put("/notice/notice_send", "authc");
//登出的过滤器(自定义退出/logout)
filterChainMap.put("/logout", "anon");
//配置记住我,认证通过才可以访问
filterChainMap.put("/index","user");
filterChainMap.put("/main","user");
filterChainMap.put("/**", "authc");
filterChainMapTemp.put("/**","anon");
factoryBean.setFilterChainDefinitionMap(filterChainMapTemp);
}
/**
* 1.配置Cookie对象
* 记住我的cookie:rememberMe
* @return SimpleCookie rememberMeCookie
*/
@Bean
public SimpleCookie rememberMeCookie() {
SimpleCookie simpleCookie = new SimpleCookie("rememberMe");
//simpleCookie.setHttpOnly(true);
//单位(秒)1天
simpleCookie.setMaxAge(60*60*24);
return simpleCookie;
}
/**
* 2.配置cookie管理对象
* @return CookieRememberMeManager
*/
@Bean
public CookieRememberMeManager cookieRememberMeManager() {
CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
cookieRememberMeManager.setCookie(rememberMeCookie());
return cookieRememberMeManager;
}
/**
* 注入Ehcache缓存
*/
/**
* 验证码生成器
* @return
*/
@Bean
public DefaultKaptcha producer(){
logger.info("==> ShiroConfiguration captchaProducer()");
DefaultKaptcha r = new DefaultKaptcha();
Properties properties = new Properties();
properties.put("kaptcha.border","yes");
//边框颜色,默认:color.BLACK
properties.put("kaptcha.border.color","105,179,90");
properties.put("kaptcha.textproducer.font.color","blue");
//验证码样式引擎,默:WaterRipple
properties.put("kaptcha.obscurificator.impl","com.google.code.kaptcha.impl.ShadowGimpy");
properties.put("kaptcha.image.width","145");
properties.put("kaptcha.image.height","45");
properties.put("kaptcha.textproducer.font.size","45");
//存放session 中的key
properties.put("kaptcha.session.key","code");
//产生字符长度
properties.put("kaptcha.textproducer.char.length","4");
properties.put("kaptcha.textproducer.font.names","宋体,楷休,微软雅黑");
Config config = new Config(properties);
r.setConfig(config);
return r;
}
}