WebMvcConfig
package com.bfr.telinksemifourm.manage.config;
import com.bfr.telinksemifourm.manage.interceptor.CommonInterceptor;
import com.bfr.telinksemifourm.manage.service.impl.SystemConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
import java.util.Locale;
/**
* Created by .
* Copyright (c) 2020, All Rights Reserved.
*
*/
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
@Autowired
private CommonInterceptor commonInterceptor;
@Autowired
private SystemConfigService systemConfigService;
// @Value("${local.upload.image}")
// private String LOCAL_UPLOAD_IMAGE;
@Override
protected void addCorsMappings(CorsRegistry registry) {
super.addCorsMappings(registry);
registry.addMapping("/admin/**").allowedHeaders("*").allowedMethods("*").allowedOrigins("*").allowCredentials(false);
}
@Override
protected void addInterceptors(InterceptorRegistry registry) {
// registry.addInterceptor(commonInterceptor)
// .addPathPatterns("/**")
// .excludePathPatterns("/login", "/logout", "/adminlogin", "/common/captcha", "/static/**");
}
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/", "file:///"+systemConfigService.selectByKey("upload_path").getValue());
}
// 配置网站默认语言
@Bean
public LocaleResolver localeResolver() {
SessionLocaleResolver sessionLocaleResolver = new SessionLocaleResolver();
sessionLocaleResolver.setDefaultLocale(Locale.SIMPLIFIED_CHINESE);
return sessionLocaleResolver;
}
}
ShiroConfig
package com.bfr.telinksemifourm.manage.config;
import com.bfr.telinksemifourm.manage.config.realm.MyCredentialsMatcher;
import com.bfr.telinksemifourm.manage.config.realm.MyShiroRealm;
import com.bfr.telinksemifourm.manage.service.ISystemConfigService;
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.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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.servlet.Filter;
import java.util.HashMap;
import java.util.Map;
/**
* Created by .
* Copyright (c) 2020, All Rights Reserved.
*
*/
@Configuration
public class ShiroConfig {
private Logger log = LoggerFactory.getLogger(ShiroConfig.class);
@Autowired
private MyShiroRealm myShiroRealm;
@Autowired
private ISystemConfigService systemConfigService;
@Bean
public ShiroFilterFactoryBean shiroFilter(@Qualifier("securityManager") SecurityManager securityManager) {
log.info("开始配置shiroFilter...");
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
Map<String, Filter> filterMap = shiroFilterFactoryBean.getFilters();
// filterMap.put("myShiroFilter", new MyShiroFilter());
shiroFilterFactoryBean.setFilters(filterMap);
//拦截器.
Map<String, String> map = new HashMap<>();
// 配置不会被拦截的链接 顺序判断 相关静态资源
map.put("/static/**", "anon");
// map.put("/upload/**", "anon");
//配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了
map.put("/admin/logout", "logout");
//<!-- 过滤链定义,从上向下顺序执行,一般将/**放在最为下边 -->:这是一个坑呢,一不小心代码就不好使了;
//<!-- authc:所有url都必须认证通过才可以访问; user: 表示rememberMe后就可以访问 anon:所有url都都可以匿名访问-->
map.put("/statics/**", "user");
map.put("/admin/permission/**", "authc");
map.put("/admin/role/**", "authc");
map.put("/admin/system/**", "authc");
map.put("/admin/admin_user/**", "authc");
map.put("/", "user");
map.put("/index", "user");
map.put("/admin/index", "user");
map.put("/admin/comment/**", "user");
map.put("/admin/sensitive_word/**", "user");
map.put("/admin/tag/**", "user");
map.put("/admin/topic/**", "user");
map.put("/admin/user/**", "user");
// map.put("/adminlogin", "myShiroFilter");
// 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
shiroFilterFactoryBean.setLoginUrl("/login");
// 登录成功后要跳转的链接
shiroFilterFactoryBean.setSuccessUrl("/index");
//未授权界面;
shiroFilterFactoryBean.setUnauthorizedUrl("/login");
shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
// Map<String, Filter> filters = new HashMap<>();
// shiroFilterFactoryBean.setFilters(filters);
return shiroFilterFactoryBean;
}
// 配置加密方式
// 配置了一下,这货就是验证不过,,改成手动验证算了,以后换加密方式也方便
@Bean
public MyCredentialsMatcher myCredentialsMatcher() {
return new MyCredentialsMatcher();
}
// 安全管理器配置
@Bean(name = "securityManager")
public SecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
myShiroRealm.setCredentialsMatcher(myCredentialsMatcher());
securityManager.setRealm(myShiroRealm);
securityManager.setRememberMeManager(rememberMeManager());
return securityManager;
}
//加入注解的使用,不加入这个注解不生效
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(@Qualifier("securityManager")
SecurityManager
securityManager) {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
// 配置记住我功能
@Bean
// @DependsOn("mybatisPlusConfig")
public SimpleCookie rememberMeCookie() {
//这个参数是cookie的名称,对应前端的checkbox的name = rememberMe
SimpleCookie simpleCookie = new SimpleCookie("rememberMe");
// 记住我cookie生效时间 单位秒
int adminRememberMeMaxAge = Integer.parseInt(systemConfigService.selectAllConfig().get
("admin_remember_me_max_age").toString());
simpleCookie.setMaxAge(adminRememberMeMaxAge * 24 * 60 * 60);
return simpleCookie;
}
@Bean
// @DependsOn("mybatisPlusConfig")
public CookieRememberMeManager rememberMeManager() {
//System.out.println("ShiroConfiguration.rememberMeManager()");
CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
cookieRememberMeManager.setCookie(rememberMeCookie());
//rememberMe cookie加密的密钥 建议每个项目都不一样 默认AES算法 密钥长度(128 256 512 位)
// cookieRememberMeManager.setCipherKey(Base64.encode("te-link-semi-forum!".getBytes()));
// ZHANGXIAOHEI_CAT te-link-semi-forum
// 长度必须16位 : https://www.jianshu.com/p/960e5a23a523
cookieRememberMeManager.setCipherKey(Base64.encode("ZHANGXIAOHEI_CAT".getBytes()));
return cookieRememberMeManager;
}
@Bean
public FormAuthenticationFilter formAuthenticationFilter() {
FormAuthenticationFilter formAuthenticationFilter = new FormAuthenticationFilter();
//对应前端的checkbox的name = rememberMe
formAuthenticationFilter.setRememberMeParam("rememberMe");
return formAuthenticationFilter;
}
@Bean
@ConditionalOnMissingBean
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator defaultAAP = new DefaultAdvisorAutoProxyCreator();
defaultAAP.setProxyTargetClass(true);
return defaultAAP;
}
}