diff --git a/modules/core/src/main/java/com/jeesite/common/shiro/filter/LogoutFilter.java b/modules/core/src/main/java/com/jeesite/common/shiro/filter/LogoutFilter.java index aa9dd002..9e5804bf 100644 --- a/modules/core/src/main/java/com/jeesite/common/shiro/filter/LogoutFilter.java +++ b/modules/core/src/main/java/com/jeesite/common/shiro/filter/LogoutFilter.java @@ -29,31 +29,30 @@ public class LogoutFilter extends org.apache.shiro.web.filter.authc.LogoutFilter @Override protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception { - return super.preHandle(request, response); -// try{ -// Subject subject = getSubject(request, response); -// String redirectUrl = getRedirectUrl(request, response, subject); -// //try/catch added for SHIRO-298: -// try { -// // 记录用户退出日志 -// LogUtils.saveLog(ServletUtils.getRequest(), "系统退出"); -// // 退出登录 -// subject.logout(); -// } catch (SessionException ise) { -// log.debug("Encountered session exception during logout. This can generally safely be ignored.", ise); -// } -// -// // 如果是Ajax请求,返回Json字符串。 -// if (ServletUtils.isAjaxRequest((HttpServletRequest)request)){ -// ServletUtils.renderResult((HttpServletResponse)response, Global.TRUE, "退出成功!"); -// return false; -// } -// -// issueRedirect(request, response, redirectUrl); -// }catch(Exception e){ -// log.debug("Encountered session exception during logout. This can generally safely be ignored.", e); -// } -// return false; + try{ + Subject subject = getSubject(request, response); + String redirectUrl = getRedirectUrl(request, response, subject); + //try/catch added for SHIRO-298: + try { + // 记录用户退出日志 + LogUtils.saveLog(ServletUtils.getRequest(), "系统退出"); + // 退出登录 + subject.logout(); + } catch (SessionException ise) { + log.debug("Encountered session exception during logout. This can generally safely be ignored.", ise); + } + + // 如果是Ajax请求,返回Json字符串。 + if (ServletUtils.isAjaxRequest((HttpServletRequest)request)){ + ServletUtils.renderResult((HttpServletResponse)response, Global.TRUE, "退出成功!"); + return false; + } + + issueRedirect(request, response, redirectUrl); + }catch(Exception e){ + log.debug("Encountered session exception during logout. This can generally safely be ignored.", e); + } + return false; } /** @@ -61,12 +60,12 @@ public class LogoutFilter extends org.apache.shiro.web.filter.authc.LogoutFilter */ @Override 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); -// String url = Global.getProperty("shiro.logoutUrl"); -// // 如果配置了登出之后跳转的url,并且url不能为 ${adminPath}/logout 否则会造成死循环。 -// if (StringUtils.isNoneBlank(url) && !url.equals((Global.getAdminPath()+"/logout"))){ -// return url; -// } } } diff --git a/modules/core/src/main/java/com/jeesite/common/shiro/filter/RolesAuthorizationFilter.java b/modules/core/src/main/java/com/jeesite/common/shiro/filter/RolesAuthorizationFilter.java index 1d136ba9..1ea4272f 100644 --- a/modules/core/src/main/java/com/jeesite/common/shiro/filter/RolesAuthorizationFilter.java +++ b/modules/core/src/main/java/com/jeesite/common/shiro/filter/RolesAuthorizationFilter.java @@ -17,14 +17,12 @@ public class RolesAuthorizationFilter extends org.apache.shiro.web.filter.authz. @Override protected void redirectToLogin(ServletRequest request, ServletResponse response) throws IOException { - super.redirectToLogin(request, response); -// PermissionsAuthorizationFilter.redirectToDefaultPath(request, response); + PermissionsAuthorizationFilter.redirectToDefaultPath(request, response); } @Override protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws IOException { - return super.onAccessDenied(request, response); -// return PermissionsAuthorizationFilter.redirectTo403Page(request, response); + return PermissionsAuthorizationFilter.redirectTo403Page(request, response); } } diff --git a/modules/core/src/main/java/com/jeesite/config/spring/ShiroConfig.java b/modules/core/src/main/java/com/jeesite/config/common/ShiroConfig.java similarity index 57% rename from modules/core/src/main/java/com/jeesite/config/spring/ShiroConfig.java rename to modules/core/src/main/java/com/jeesite/config/common/ShiroConfig.java index b3562933..d2c652da 100644 --- a/modules/core/src/main/java/com/jeesite/config/spring/ShiroConfig.java +++ b/modules/core/src/main/java/com/jeesite/config/common/ShiroConfig.java @@ -1,7 +1,7 @@ /** * Copyright (c) 2013-Now http://jeesite.com All rights reserved. */ -package com.jeesite.config.spring; +package com.jeesite.config.common; 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.filter.CasAuthenticationFilter; 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.RolesAuthorizationFilter; import com.jeesite.common.shiro.filter.UserFilter; import com.jeesite.common.shiro.realm.AuthorizingRealm; import com.jeesite.common.shiro.session.SessionDAO; @@ -68,8 +70,7 @@ public class ShiroConfig { /** * CAS登录过滤器 */ - @Bean - public CasAuthenticationFilter shiroCasFilter(AuthorizingRealm authorizingRealm) { + private CasAuthenticationFilter shiroCasFilter(AuthorizingRealm authorizingRealm) { CasAuthenticationFilter bean = new CasAuthenticationFilter(); bean.setAuthorizingRealm(authorizingRealm); return bean; @@ -78,78 +79,61 @@ public class ShiroConfig { /** * Form登录过滤器 */ - @Bean - public FormAuthenticationFilter shiroAuthcFilter(AuthorizingRealm authorizingRealm) { + private FormAuthenticationFilter shiroAuthcFilter(AuthorizingRealm authorizingRealm) { FormAuthenticationFilter bean = new FormAuthenticationFilter(); bean.setAuthorizingRealm(authorizingRealm); return bean; } -// /** -// * 登出过滤器 -// */ -// @Bean -// public LogoutFilter shiroLogoutFilter() { -// return new LogoutFilter(); -// } + /** + * 登出过滤器 + */ + private LogoutFilter shiroLogoutFilter() { + return new LogoutFilter(); + } /** * 权限字符串过滤器 */ - @Bean - public PermissionsAuthorizationFilter shiroPermsFilter() { + private PermissionsAuthorizationFilter shiroPermsFilter() { return new PermissionsAuthorizationFilter(); } -// /** -// * 角色权限过滤器 -// */ -// @Bean -// public RolesAuthorizationFilter shiroRolesFilter() { -// return new RolesAuthorizationFilter(); -// } + /** + * 角色权限过滤器 + */ + private RolesAuthorizationFilter shiroRolesFilter() { + return new RolesAuthorizationFilter(); + } /** * 用户权限过滤器 */ - @Bean - public UserFilter shiroUserFilter() { + private UserFilter shiroUserFilter() { 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认证过滤器 */ @Bean - public ShiroFilterFactoryBean shiroFilter(WebSecurityManager securityManager, CasAuthenticationFilter shiroCasFilter, - FormAuthenticationFilter shiroAuthcFilter, -// LogoutFilter shiroLogoutFilter, - PermissionsAuthorizationFilter shiroPermsFilter, -// RolesAuthorizationFilter shiroRolesFilter, - UserFilter shiroUserFilter, FilterChainDefinitionMap shiroFilterChainDefinitionMap) { + public ShiroFilterFactoryBean shiroFilter(WebSecurityManager securityManager, + AuthorizingRealm authorizingRealm) { ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean(); bean.setSecurityManager(securityManager); bean.setLoginUrl(Global.getProperty("shiro.loginUrl")); bean.setSuccessUrl(Global.getProperty("shiro.successUrl")); Map filters = bean.getFilters(); - filters.put("cas", shiroCasFilter); - filters.put("authc", shiroAuthcFilter); -// filters.put("logout", shiroLogoutFilter); - filters.put("perms", shiroPermsFilter); -// filters.put("roles", shiroRolesFilter); - filters.put("user", shiroUserFilter); - bean.setFilterChainDefinitionMap(shiroFilterChainDefinitionMap.getObject()); + filters.put("cas", shiroCasFilter(authorizingRealm)); + filters.put("authc", shiroAuthcFilter(authorizingRealm)); + filters.put("logout", shiroLogoutFilter()); + filters.put("perms", shiroPermsFilter()); + filters.put("roles", shiroRolesFilter()); + filters.put("user", shiroUserFilter()); + FilterChainDefinitionMap chains = new FilterChainDefinitionMap(); + chains.setFilterChainDefinitions(Global.getProperty("shiro.filterChainDefinitions")); + chains.setDefaultFilterChainDefinitions(Global.getProperty("shiro.defaultFilterChainDefinitions")); + bean.setFilterChainDefinitionMap(chains.getObject()); return bean; } @@ -167,4 +151,44 @@ public class ShiroConfig { 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; +// } + } diff --git a/modules/core/src/main/java/com/jeesite/modules/db/InitCoreData.xlsx b/modules/core/src/main/java/com/jeesite/modules/db/InitCoreData.xlsx index bbb12e75..00d7715d 100644 Binary files a/modules/core/src/main/java/com/jeesite/modules/db/InitCoreData.xlsx and b/modules/core/src/main/java/com/jeesite/modules/db/InitCoreData.xlsx differ diff --git a/web/src/main/java/com/jeesite/config/Application.java b/web/src/main/java/com/jeesite/config/Application.java index 4b3b19d6..86678a0e 100644 --- a/web/src/main/java/com/jeesite/config/Application.java +++ b/web/src/main/java/com/jeesite/config/Application.java @@ -7,6 +7,7 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.support.SpringBootServletInitializer; +import org.springframework.context.annotation.Profile; import com.jeesite.common.io.PropertiesUtils; @@ -15,6 +16,7 @@ import com.jeesite.common.io.PropertiesUtils; * @author ThinkGem * @version 2018-1-8 */ +@Profile("default") @SpringBootApplication(scanBasePackages={"com.jeesite.config"}) public class Application extends SpringBootServletInitializer { diff --git a/web/src/main/java/com/jeesite/config/web/FilterConfig.java b/web/src/main/java/com/jeesite/config/web/FilterConfig.java index 16bf0880..309cf14c 100644 --- a/web/src/main/java/com/jeesite/config/web/FilterConfig.java +++ b/web/src/main/java/com/jeesite/config/web/FilterConfig.java @@ -3,17 +3,19 @@ */ package com.jeesite.config.web; +import javax.servlet.Filter; + import org.apache.commons.lang3.StringUtils; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.cache.ehcache.EhCacheManagerFactoryBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; 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.shiro.web.ShiroFilterFactoryBean; import com.jeesite.common.web.PageCachingFilter; /** @@ -28,13 +30,13 @@ public class FilterConfig { * Encoding Filter */ @Bean + @Order(1000) public FilterRegistrationBean characterEncodingFilter() { FilterRegistrationBean bean = new FilterRegistrationBean(); bean.setFilter(new CharacterEncodingFilter()); bean.addInitParameter("encoding", "UTF-8"); bean.addInitParameter("forceEncoding", "true"); bean.addUrlPatterns("/*"); - bean.setOrder(1000); return bean; } @@ -42,6 +44,7 @@ public class FilterConfig { * PageCache Filter, cache .html suffix. */ @Bean + @Order(2000) @ConditionalOnProperty(name = "ehcache.pageCaching.enabled", havingValue = "true") public FilterRegistrationBean pageCachingFilter(EhCacheManagerFactoryBean ehCacheManager) { FilterRegistrationBean bean = new FilterRegistrationBean(); @@ -51,33 +54,20 @@ public class FilterConfig { bean.addInitParameter("cacheName", "pageCachingFilter"); bean.addUrlPatterns(StringUtils.split(Global.getProperty( "ehcache.pageCaching.urlPatterns"), ",")); - bean.setOrder(2000); return bean; } /** * Apache Shiro Filter + * @throws Exception */ @Bean - public FilterRegistrationBean shiroFilterProxy() { + @Order(3000) + public FilterRegistrationBean shiroFilterProxy(ShiroFilterFactoryBean shiroFilter) throws Exception { FilterRegistrationBean bean = new FilterRegistrationBean(); - bean.setFilter(new DelegatingFilterProxy("shiroFilter")); - bean.addInitParameter("targetFilterLifecycle", "true"); + bean.setFilter((Filter) shiroFilter.getInstance()); bean.addUrlPatterns("/*"); - bean.setOrder(3000); 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; - } - + } diff --git a/web/src/main/java/com/jeesite/config/web/ListenerConfig.java b/web/src/main/java/com/jeesite/config/web/ListenerConfig.java index b61cd616..09173d16 100644 --- a/web/src/main/java/com/jeesite/config/web/ListenerConfig.java +++ b/web/src/main/java/com/jeesite/config/web/ListenerConfig.java @@ -6,10 +6,9 @@ package com.jeesite.config.web; import org.springframework.boot.web.servlet.ServletListenerRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; import org.springframework.web.context.request.RequestContextListener; -import com.jeesite.common.shiro.cas.CasOutSessionListener; - /** * Listener 配置 * @author ThinkGem @@ -17,26 +16,15 @@ import com.jeesite.common.shiro.cas.CasOutSessionListener; */ @Configuration public class ListenerConfig { - - /** - * CAS Session Listener - */ - @Bean - public ServletListenerRegistrationBean casOutSessionListener() { - ServletListenerRegistrationBean bean = new ServletListenerRegistrationBean<>(); - bean.setListener(new CasOutSessionListener()); - bean.setOrder(1000); - return bean; - } - + /** * Request Context Listener */ @Bean + @Order(1000) public ServletListenerRegistrationBean requestContextListener() { ServletListenerRegistrationBean bean = new ServletListenerRegistrationBean<>(); bean.setListener(new RequestContextListener()); - bean.setOrder(2000); return bean; } diff --git a/web/src/main/resources/application.yml b/web/src/main/resources/application.yml index abc6af57..7007eeba 100644 --- a/web/src/main/resources/application.yml +++ b/web/src/main/resources/application.yml @@ -1,3 +1,10 @@ +spring: + + profiles: + active: default + + main: + banner-mode: "off" server: @@ -6,10 +13,6 @@ server: tomcat: uri-encoding: UTF-8 -spring: - main: - banner-mode: "off" - debug: true