package com.example.ghs.shiro.config;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.mgt.SecurityManager;
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.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@Configuration
@Slf4j
public class ShiroConfig {
//Filter工厂,设置对应的过滤条件和跳转条件
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) throws IOException {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
Map<String, String> map = new HashMap<>();
log.info("项目地址:" + System.getProperty("user.dir"));
//静态资源可匿名访问
map.put("/**/*.ico", "anon");
map.put("/**/*.js", "anon");
map.put("/**/*.css", "anon");
map.put("/**/*.png", "anon");
map.put("/**/*.jpg", "anon");
map.put("/**/*.gif", "anon");
map.put("/**/*.tff", "anon");
map.put("/**/*.woff", "anon");
//登出
map.put("/logout", "logout");
//开启rememberMe功能用user,否则用authc
map.put("/**", "user");
//登录
shiroFilterFactoryBean.setLoginUrl("/login");
//首页
shiroFilterFactoryBean.setSuccessUrl("/index");
//错误页面,认证不通过跳转
shiroFilterFactoryBean.setUnauthorizedUrl("/error");
shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
return shiroFilterFactoryBean;
}
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
/**
* 开启注解式 权限拦截
*
* @return
*/
@Bean
@ConditionalOnMissingBean
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator defaultAAP = new DefaultAdvisorAutoProxyCreator();
defaultAAP.setProxyTargetClass(true);
return defaultAAP;
}
/*将自己的验证方式加入容器*/
@Bean
public CustomRealm myShiroRealm() {
return new CustomRealm();
}
/**
* cookie管理对象
*
* @return
*/
@Bean
public CookieRememberMeManager rememberMeManager() {
CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
cookieRememberMeManager.setCookie(rememberMeCookie());
//rememberMe cookie加密的密钥 建议每个项目都不一样 默认AES算法 密钥长度(128 256 512 位)
cookieRememberMeManager.setCipherKey(Base64.decode("4AvVhmFLUs0KTA3Kprsdag=="));
return cookieRememberMeManager;
}
@Bean
public SimpleCookie rememberMeCookie() {
//这个参数是cookie的名称,对应前端的checkbox的name = rememberMe
SimpleCookie simpleCookie = new SimpleCookie("rememberMe");
//setcookie的httponly属性如果设为true的话,会增加对xss防护的安全系数。它有以下特点:
//setcookie()的第七个参数
//设为true后,只能通过http访问,javascript无法访问
//防止xss读取cookie
simpleCookie.setHttpOnly(true);
simpleCookie.setPath("/");
//记住我cookie生效时间 ,单位秒
simpleCookie.setMaxAge(60 * 60 * 24 * 3);
return simpleCookie;
}
/**
* 去掉shiro登录时url里的JSESSIONID
*
* @return
*/
@Bean
public DefaultWebSessionManager sessionManager() {
DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
// 去掉shiro登录时url里的JSESSIONID
sessionManager.setSessionIdUrlRewritingEnabled(false);
return sessionManager;
}
/*权限管理,配置主要是Realm的管理认证*/
@Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(myShiroRealm());
securityManager.setRememberMeManager(rememberMeManager());
securityManager.setSessionManager(sessionManager());//去掉shiro登录时url里的JSESSIONID
return securityManager;
}
}
@GetMapping({"login","error"})
public ModelAndView login() {
return new ModelAndView("index/login");
}
@GetMapping({"index","/"})
public ModelAndView index() {
return new ModelAndView("index/index");
}