修正Shiro过滤器重复加载及加载顺序问题

This commit is contained in:
thinkgem
2018-01-12 22:16:17 +08:00
parent a0c71ce81a
commit 332b5be61f
8 changed files with 125 additions and 121 deletions

View File

@@ -29,31 +29,30 @@ public class LogoutFilter extends org.apache.shiro.web.filter.authc.LogoutFilter
@Override @Override
protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception { protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
return super.preHandle(request, response); try{
// try{ Subject subject = getSubject(request, response);
// Subject subject = getSubject(request, response); String redirectUrl = getRedirectUrl(request, response, subject);
// String redirectUrl = getRedirectUrl(request, response, subject); //try/catch added for SHIRO-298:
// //try/catch added for SHIRO-298: try {
// try { // 记录用户退出日志
// // 记录用户退出日志 LogUtils.saveLog(ServletUtils.getRequest(), "系统退出");
// LogUtils.saveLog(ServletUtils.getRequest(), "系统退出"); // 退出登录
// // 退出登录 subject.logout();
// subject.logout(); } catch (SessionException ise) {
// } catch (SessionException ise) { log.debug("Encountered session exception during logout. This can generally safely be ignored.", ise);
// log.debug("Encountered session exception during logout. This can generally safely be ignored.", ise); }
// }
// // 如果是Ajax请求返回Json字符串。
// // 如果是Ajax请求返回Json字符串。 if (ServletUtils.isAjaxRequest((HttpServletRequest)request)){
// if (ServletUtils.isAjaxRequest((HttpServletRequest)request)){ ServletUtils.renderResult((HttpServletResponse)response, Global.TRUE, "退出成功!");
// ServletUtils.renderResult((HttpServletResponse)response, Global.TRUE, "退出成功!"); return false;
// return false; }
// }
// issueRedirect(request, response, redirectUrl);
// issueRedirect(request, response, redirectUrl); }catch(Exception e){
// }catch(Exception e){ log.debug("Encountered session exception during logout. This can generally safely be ignored.", e);
// log.debug("Encountered session exception during logout. This can generally safely be ignored.", e); }
// } return false;
// return false;
} }
/** /**
@@ -61,12 +60,12 @@ public class LogoutFilter extends org.apache.shiro.web.filter.authc.LogoutFilter
*/ */
@Override @Override
protected String getRedirectUrl(ServletRequest request, ServletResponse response, Subject subject) { protected String getRedirectUrl(ServletRequest request, ServletResponse response, Subject subject) {
String url = Global.getProperty("shiro.logoutUrl");
// 如果配置了登出之后跳转的url并且url不能为 ${adminPath}/logout 否则会造成死循环。
if (StringUtils.isNoneBlank(url) && !url.equals((Global.getAdminPath()+"/logout"))){
return url;
}
return super.getRedirectUrl(request, response, subject); return super.getRedirectUrl(request, response, subject);
// String url = Global.getProperty("shiro.logoutUrl");
// // 如果配置了登出之后跳转的url并且url不能为 ${adminPath}/logout 否则会造成死循环。
// if (StringUtils.isNoneBlank(url) && !url.equals((Global.getAdminPath()+"/logout"))){
// return url;
// }
} }
} }

View File

@@ -17,14 +17,12 @@ public class RolesAuthorizationFilter extends org.apache.shiro.web.filter.authz.
@Override @Override
protected void redirectToLogin(ServletRequest request, ServletResponse response) throws IOException { protected void redirectToLogin(ServletRequest request, ServletResponse response) throws IOException {
super.redirectToLogin(request, response); PermissionsAuthorizationFilter.redirectToDefaultPath(request, response);
// PermissionsAuthorizationFilter.redirectToDefaultPath(request, response);
} }
@Override @Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws IOException { protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws IOException {
return super.onAccessDenied(request, response); return PermissionsAuthorizationFilter.redirectTo403Page(request, response);
// return PermissionsAuthorizationFilter.redirectTo403Page(request, response);
} }
} }

View File

@@ -1,7 +1,7 @@
/** /**
* Copyright (c) 2013-Now http://jeesite.com All rights reserved. * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
*/ */
package com.jeesite.config.spring; package com.jeesite.config.common;
import java.util.Map; import java.util.Map;
@@ -21,7 +21,9 @@ import com.jeesite.common.shiro.cas.CasOutHandler;
import com.jeesite.common.shiro.config.FilterChainDefinitionMap; import com.jeesite.common.shiro.config.FilterChainDefinitionMap;
import com.jeesite.common.shiro.filter.CasAuthenticationFilter; import com.jeesite.common.shiro.filter.CasAuthenticationFilter;
import com.jeesite.common.shiro.filter.FormAuthenticationFilter; import com.jeesite.common.shiro.filter.FormAuthenticationFilter;
import com.jeesite.common.shiro.filter.LogoutFilter;
import com.jeesite.common.shiro.filter.PermissionsAuthorizationFilter; import com.jeesite.common.shiro.filter.PermissionsAuthorizationFilter;
import com.jeesite.common.shiro.filter.RolesAuthorizationFilter;
import com.jeesite.common.shiro.filter.UserFilter; import com.jeesite.common.shiro.filter.UserFilter;
import com.jeesite.common.shiro.realm.AuthorizingRealm; import com.jeesite.common.shiro.realm.AuthorizingRealm;
import com.jeesite.common.shiro.session.SessionDAO; import com.jeesite.common.shiro.session.SessionDAO;
@@ -68,8 +70,7 @@ public class ShiroConfig {
/** /**
* CAS登录过滤器 * CAS登录过滤器
*/ */
@Bean private CasAuthenticationFilter shiroCasFilter(AuthorizingRealm authorizingRealm) {
public CasAuthenticationFilter shiroCasFilter(AuthorizingRealm authorizingRealm) {
CasAuthenticationFilter bean = new CasAuthenticationFilter(); CasAuthenticationFilter bean = new CasAuthenticationFilter();
bean.setAuthorizingRealm(authorizingRealm); bean.setAuthorizingRealm(authorizingRealm);
return bean; return bean;
@@ -78,78 +79,61 @@ public class ShiroConfig {
/** /**
* Form登录过滤器 * Form登录过滤器
*/ */
@Bean private FormAuthenticationFilter shiroAuthcFilter(AuthorizingRealm authorizingRealm) {
public FormAuthenticationFilter shiroAuthcFilter(AuthorizingRealm authorizingRealm) {
FormAuthenticationFilter bean = new FormAuthenticationFilter(); FormAuthenticationFilter bean = new FormAuthenticationFilter();
bean.setAuthorizingRealm(authorizingRealm); bean.setAuthorizingRealm(authorizingRealm);
return bean; return bean;
} }
// /** /**
// * 登出过滤器 * 登出过滤器
// */ */
// @Bean private LogoutFilter shiroLogoutFilter() {
// public LogoutFilter shiroLogoutFilter() { return new LogoutFilter();
// return new LogoutFilter(); }
// }
/** /**
* 权限字符串过滤器 * 权限字符串过滤器
*/ */
@Bean private PermissionsAuthorizationFilter shiroPermsFilter() {
public PermissionsAuthorizationFilter shiroPermsFilter() {
return new PermissionsAuthorizationFilter(); return new PermissionsAuthorizationFilter();
} }
// /** /**
// * 角色权限过滤器 * 角色权限过滤器
// */ */
// @Bean private RolesAuthorizationFilter shiroRolesFilter() {
// public RolesAuthorizationFilter shiroRolesFilter() { return new RolesAuthorizationFilter();
// return new RolesAuthorizationFilter(); }
// }
/** /**
* 用户权限过滤器 * 用户权限过滤器
*/ */
@Bean private UserFilter shiroUserFilter() {
public UserFilter shiroUserFilter() {
return new UserFilter(); return new UserFilter();
} }
/**
* URL过滤定义
*/
@Bean
public FilterChainDefinitionMap shiroFilterChainDefinitionMap() {
FilterChainDefinitionMap bean = new FilterChainDefinitionMap();
bean.setFilterChainDefinitions(Global.getProperty("shiro.filterChainDefinitions"));
bean.setDefaultFilterChainDefinitions(Global.getProperty("shiro.defaultFilterChainDefinitions"));
return bean;
}
/** /**
* Shiro认证过滤器 * Shiro认证过滤器
*/ */
@Bean @Bean
public ShiroFilterFactoryBean shiroFilter(WebSecurityManager securityManager, CasAuthenticationFilter shiroCasFilter, public ShiroFilterFactoryBean shiroFilter(WebSecurityManager securityManager,
FormAuthenticationFilter shiroAuthcFilter, AuthorizingRealm authorizingRealm) {
// LogoutFilter shiroLogoutFilter,
PermissionsAuthorizationFilter shiroPermsFilter,
// RolesAuthorizationFilter shiroRolesFilter,
UserFilter shiroUserFilter, FilterChainDefinitionMap shiroFilterChainDefinitionMap) {
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean(); ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
bean.setSecurityManager(securityManager); bean.setSecurityManager(securityManager);
bean.setLoginUrl(Global.getProperty("shiro.loginUrl")); bean.setLoginUrl(Global.getProperty("shiro.loginUrl"));
bean.setSuccessUrl(Global.getProperty("shiro.successUrl")); bean.setSuccessUrl(Global.getProperty("shiro.successUrl"));
Map<String, Filter> filters = bean.getFilters(); Map<String, Filter> filters = bean.getFilters();
filters.put("cas", shiroCasFilter); filters.put("cas", shiroCasFilter(authorizingRealm));
filters.put("authc", shiroAuthcFilter); filters.put("authc", shiroAuthcFilter(authorizingRealm));
// filters.put("logout", shiroLogoutFilter); filters.put("logout", shiroLogoutFilter());
filters.put("perms", shiroPermsFilter); filters.put("perms", shiroPermsFilter());
// filters.put("roles", shiroRolesFilter); filters.put("roles", shiroRolesFilter());
filters.put("user", shiroUserFilter); filters.put("user", shiroUserFilter());
bean.setFilterChainDefinitionMap(shiroFilterChainDefinitionMap.getObject()); FilterChainDefinitionMap chains = new FilterChainDefinitionMap();
chains.setFilterChainDefinitions(Global.getProperty("shiro.filterChainDefinitions"));
chains.setDefaultFilterChainDefinitions(Global.getProperty("shiro.defaultFilterChainDefinitions"));
bean.setFilterChainDefinitionMap(chains.getObject());
return bean; return bean;
} }
@@ -167,4 +151,44 @@ public class ShiroConfig {
return bean; return bean;
} }
/**
* Shiro 生命周期处理器实现初始化和销毁回调
*/
@Bean(name="lifecycleBeanPostProcessor")
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}
/**
* Shiro 过滤器代理配置
*/
@Bean
@DependsOn({ "lifecycleBeanPostProcessor" })
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator bean = new DefaultAdvisorAutoProxyCreator();
bean.setProxyTargetClass(true);
return bean;
}
/**
* 启用Shrio授权注解拦截方式AOP式方法级权限检查
*/
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(WebSecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor bean = new AuthorizationAttributeSourceAdvisor();
bean.setSecurityManager(securityManager);
return bean;
}
// /**
// * 在方法中 注入 securityManager 进行代理控制
// */
// @Bean
// public MethodInvokingFactoryBean methodInvokingFactoryBean(DefaultWebSecurityManager securityManager) {
// MethodInvokingFactoryBean bean = new MethodInvokingFactoryBean();
// bean.setStaticMethod("org.apache.shiro.SecurityUtils.setSecurityManager");
// bean.setArguments(new Object[] { securityManager });
// return bean;
// }
} }

View File

@@ -7,6 +7,7 @@ import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer; import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Profile;
import com.jeesite.common.io.PropertiesUtils; import com.jeesite.common.io.PropertiesUtils;
@@ -15,6 +16,7 @@ import com.jeesite.common.io.PropertiesUtils;
* @author ThinkGem * @author ThinkGem
* @version 2018-1-8 * @version 2018-1-8
*/ */
@Profile("default")
@SpringBootApplication(scanBasePackages={"com.jeesite.config"}) @SpringBootApplication(scanBasePackages={"com.jeesite.config"})
public class Application extends SpringBootServletInitializer { public class Application extends SpringBootServletInitializer {

View File

@@ -3,17 +3,19 @@
*/ */
package com.jeesite.config.web; package com.jeesite.config.web;
import javax.servlet.Filter;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.cache.ehcache.EhCacheManagerFactoryBean; import org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.web.filter.CharacterEncodingFilter; import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.filter.DelegatingFilterProxy;
import org.springframework.web.filter.RequestContextFilter;
import com.jeesite.common.config.Global; import com.jeesite.common.config.Global;
import com.jeesite.common.shiro.web.ShiroFilterFactoryBean;
import com.jeesite.common.web.PageCachingFilter; import com.jeesite.common.web.PageCachingFilter;
/** /**
@@ -28,13 +30,13 @@ public class FilterConfig {
* Encoding Filter * Encoding Filter
*/ */
@Bean @Bean
@Order(1000)
public FilterRegistrationBean characterEncodingFilter() { public FilterRegistrationBean characterEncodingFilter() {
FilterRegistrationBean bean = new FilterRegistrationBean(); FilterRegistrationBean bean = new FilterRegistrationBean();
bean.setFilter(new CharacterEncodingFilter()); bean.setFilter(new CharacterEncodingFilter());
bean.addInitParameter("encoding", "UTF-8"); bean.addInitParameter("encoding", "UTF-8");
bean.addInitParameter("forceEncoding", "true"); bean.addInitParameter("forceEncoding", "true");
bean.addUrlPatterns("/*"); bean.addUrlPatterns("/*");
bean.setOrder(1000);
return bean; return bean;
} }
@@ -42,6 +44,7 @@ public class FilterConfig {
* PageCache Filter, cache .html suffix. * PageCache Filter, cache .html suffix.
*/ */
@Bean @Bean
@Order(2000)
@ConditionalOnProperty(name = "ehcache.pageCaching.enabled", havingValue = "true") @ConditionalOnProperty(name = "ehcache.pageCaching.enabled", havingValue = "true")
public FilterRegistrationBean pageCachingFilter(EhCacheManagerFactoryBean ehCacheManager) { public FilterRegistrationBean pageCachingFilter(EhCacheManagerFactoryBean ehCacheManager) {
FilterRegistrationBean bean = new FilterRegistrationBean(); FilterRegistrationBean bean = new FilterRegistrationBean();
@@ -51,33 +54,20 @@ public class FilterConfig {
bean.addInitParameter("cacheName", "pageCachingFilter"); bean.addInitParameter("cacheName", "pageCachingFilter");
bean.addUrlPatterns(StringUtils.split(Global.getProperty( bean.addUrlPatterns(StringUtils.split(Global.getProperty(
"ehcache.pageCaching.urlPatterns"), ",")); "ehcache.pageCaching.urlPatterns"), ","));
bean.setOrder(2000);
return bean; return bean;
} }
/** /**
* Apache Shiro Filter * Apache Shiro Filter
* @throws Exception
*/ */
@Bean @Bean
public FilterRegistrationBean shiroFilterProxy() { @Order(3000)
public FilterRegistrationBean shiroFilterProxy(ShiroFilterFactoryBean shiroFilter) throws Exception {
FilterRegistrationBean bean = new FilterRegistrationBean(); FilterRegistrationBean bean = new FilterRegistrationBean();
bean.setFilter(new DelegatingFilterProxy("shiroFilter")); bean.setFilter((Filter) shiroFilter.getInstance());
bean.addInitParameter("targetFilterLifecycle", "true");
bean.addUrlPatterns("/*"); bean.addUrlPatterns("/*");
bean.setOrder(3000);
return bean; return bean;
} }
/**
* Request Context Filter 需要放在shiroFilter后否则request获取不到session
*/
@Bean
public FilterRegistrationBean requestContextFilter() {
FilterRegistrationBean bean = new FilterRegistrationBean();
bean.setFilter(new RequestContextFilter());
bean.addUrlPatterns("/*");
bean.setOrder(4000);
return bean;
}
} }

View File

@@ -6,10 +6,9 @@ package com.jeesite.config.web;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean; import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.web.context.request.RequestContextListener; import org.springframework.web.context.request.RequestContextListener;
import com.jeesite.common.shiro.cas.CasOutSessionListener;
/** /**
* Listener 配置 * Listener 配置
* @author ThinkGem * @author ThinkGem
@@ -17,26 +16,15 @@ import com.jeesite.common.shiro.cas.CasOutSessionListener;
*/ */
@Configuration @Configuration
public class ListenerConfig { public class ListenerConfig {
/**
* CAS Session Listener
*/
@Bean
public ServletListenerRegistrationBean<CasOutSessionListener> casOutSessionListener() {
ServletListenerRegistrationBean<CasOutSessionListener> bean = new ServletListenerRegistrationBean<>();
bean.setListener(new CasOutSessionListener());
bean.setOrder(1000);
return bean;
}
/** /**
* Request Context Listener * Request Context Listener
*/ */
@Bean @Bean
@Order(1000)
public ServletListenerRegistrationBean<RequestContextListener> requestContextListener() { public ServletListenerRegistrationBean<RequestContextListener> requestContextListener() {
ServletListenerRegistrationBean<RequestContextListener> bean = new ServletListenerRegistrationBean<>(); ServletListenerRegistrationBean<RequestContextListener> bean = new ServletListenerRegistrationBean<>();
bean.setListener(new RequestContextListener()); bean.setListener(new RequestContextListener());
bean.setOrder(2000);
return bean; return bean;
} }

View File

@@ -1,3 +1,10 @@
spring:
profiles:
active: default
main:
banner-mode: "off"
server: server:
@@ -6,10 +13,6 @@ server:
tomcat: tomcat:
uri-encoding: UTF-8 uri-encoding: UTF-8
spring:
main:
banner-mode: "off"
debug: true debug: true