内嵌系统注销,session统一注销,redis管理,单机与集群
在项目中遇到了这么一个问题,在这里记录当时解决的方式
出现的问题:系统内嵌系统,当时外系统注销用户后发现内嵌iframe的另一个系统没有退出登录,缓存仍然在,依然可以使用用户身份访问,外系统登陆另一个用户账号时,内嵌系统任然是上一次或第一次登陆的用户信息,导致用户信息不匹配和其它操作的漏洞。
调试很多次,发现问题出在由于外系统和内嵌系统session不是一个session,没有做session共享注销时CAS会通知外系统下的所有子系统退出,由于内嵌系统session没有清除而致。
解决过程:
配置文件:地址根据自己项目配置
# spring.redis
spring.redis.cluster.nodes=localhost:7001,localhost:7002,localhost:7003,localhost:7004,localhost:7005,localhost:7006
spring.redis.pool.max-active=300
spring.redis.database=0
spring.redis.pool.max-wait=-1
spring.redis.pool.max-idle=100
spring.redis.pool.min-idle=20
spring.redis.timeout=60000
# redis session
spring.session.store-type=redis
# spring.cas
spring.cas.cas-server-login-url = https://localhost:7443/cas/login
spring.cas.cas-server-url-prefix = https://localhost:7443/cas
spring.cas.server-name = http://localhost/web/index
shiro-cas.casServerUrlPrefix = https://local:7443/cas
shiro-cas.casLoginUrl = ${shiro-cas.casServerUrlPrefix}/login
shiro-cas.casLogoutUrl = ${shiro-cas.casServerUrlPrefix}/logout
shiro-cas.shiroServerUrlPrefix = 内嵌的地址
shiro-cas.casFilterUrlPattern = /cas
shiro-cas.logout = ${shiro-cas.shiroServerUrlPrefix}/logout
shiro-cas.logoutFilter = /logout
shiro-cas.loginUrl = ${shiro-cas.casLoginUrl}?service=${shiro-cas.shiroServerUrlPrefix}${shiro-cas.casFilterUrlPattern}
shiro-cas.logoutUrl = ${shiro-cas.casLogoutUrl}?service=${shiro-cas.casLoginUrl}?service=${shiro-cas.shiroServerUrlPrefix}${shiro-cas.casFilterUrlPattern}
原项目没接Shiro,只用CAS做单点,修改后,将cas的配置注释掉
//@Configuration
public class CasConfig {
重新使用shiro-cas。
pom文件 注释cas-client-core,新加shiro-spring,shiro-ehcache,shiro-cas
<!--cas -->
<!--<dependency>-->
<!--<groupId>org.jasig.cas.client</groupId>-->
<!--<artifactId>cas-client-core</artifactId>-->
<!--<version>3.4.1</version>-->
<!--</dependency>-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.2.4</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>1.2.4</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-cas</artifactId>
<version>1.2.4</version>
</dependency>
配置类:
1.CasShiroConfig CasShiro的配置文件,常用配置,以及拦截的请求规则
package com.demo;
import org.apache.shiro.cas.CasFilter;
import org.apache.shiro.cas.CasSubjectFactory;
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.DefaultWebSecurityManager;
import org.jasig.cas.client.session.SingleSignOutHttpSessionListener;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.DelegatingFilterProxy;
import javax.servlet.Filter;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
/**
*FILE : CasShiroConfig
*DATE :
*AUTHOR
*/
@Configuration
public class CasShiroConfig {
@Autowired
ShrioCasAutoconfig autoconfig;
private String casFilterName = "casFilter";
@Bean
public MyShiroCasRealm myShiroCasRealm() {
MyShiroCasRealm realm = new MyShiroCasRealm();
realm.setCasServerUrlPrefix(autoconfig.getCasServerUrlPrefix());
/**客户端回调地址**/
realm.setCasService(autoconfig.getShiroServerUrlPrefix() + autoconfig.getCasFilterUrlPattern());
return realm;
}
/**
* 注册单点登出listener
* @return
*/
@SuppressWarnings({
"rawtypes", "unchecked" })
@Bean
public ServletListenerRegistrationBean singleSignOutHttpSessionListener(){
ServletListenerRegistrationBean bean = new ServletListenerRegistrationBean();
bean.setListener(new SingleSignOutHttpSessionListener());
bean.setEnabled(true);
return bean;
}
/**
* 注册单点登出filter
* @return
*/
@Bean
public FilterRegistrationBean singleSignOutFilter(){
FilterRegistrationBean bean = new FilterRegistrationBean();
bean.setName("singleSignOutFilter");
bean.setFilter(new SingleSignOutFilterExt());
bean.addUrlPatterns("/*");
// bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
bean.setEnabled(true);
return bean;
}
/**
* 注册DelegatingFilterProxy(Shiro)
*
* @return
* @author
* @create
*/
@Bean
public FilterRegistrationBean delegatingFilterProxy() {
FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
filterRegistration.setFilter(new DelegatingFilterProxy("shiroFilter"));
// 该值缺省为false,表示生命周期由SpringApplicationContext管理,设置为true则表示由ServletContainer管理
filterRegistration.addInitParameter("targetFilterLifecycle", "true");
filterRegistration.setEnabled(true);
filterRegistration.addUrlPatterns("/*");
// filterRegistration.setOrder(Integer.MAX_VALUE-10);
return filterRegistration;
}
@Bean(name = "lifecycleBeanPostProcessor")
public static LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}
@Bean
public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator daap = new DefaultAdvisorAutoProxyCreator();
daap.setProxyTargetClass(true);
return daap;
}
@Bean(name = "securityManager")
public DefaultWebSecurityManager getDefaultWebSecurityManager(MyShiroCasRealm myShiroCasRealm) {
DefaultWebSecurityManager dwsm = new DefaultWebSecurityManager();
dwsm.setRealm(myShiroCasRealm);
dwsm.setSubjectFactory(new CasSubjectFactory());
return dwsm;
}
@Bean
public AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor aasa = new AuthorizationAttributeSourceAdvisor()