Spring security 如何在Spring Security中设置自定义无效会话策略
我正在开发一个基于Spring Boot-1.1.6、Spring-Security-3.2.5和更多的web应用程序 我正在使用基于Java的配置:Spring security 如何在Spring Security中设置自定义无效会话策略,spring-security,Spring Security,我正在开发一个基于Spring Boot-1.1.6、Spring-Security-3.2.5和更多的web应用程序 我正在使用基于Java的配置: @Configuration @EnableWebMvcSecurity public class SecurityCtxConfig extends WebSecurityConfigurerAdapter { @Bean DelegatingAuthenticationEntryPoint delegatingAuthen
@Configuration
@EnableWebMvcSecurity
public class SecurityCtxConfig extends WebSecurityConfigurerAdapter {
@Bean
DelegatingAuthenticationEntryPoint delegatingAuthenticationEntryPoint() {
LinkedHashMap<RequestMatcher, AuthenticationEntryPoint> map = new LinkedHashMap<RequestMatcher, AuthenticationEntryPoint>();
Http403ForbiddenEntryPoint defaultEntryPoint = new Http403ForbiddenEntryPoint();
map.put(AnyRequestMatcher.INSTANCE, defaultEntryPoint);
DelegatingAuthenticationEntryPoint retVal = new DelegatingAuthenticationEntryPoint(map);
retVal.setDefaultEntryPoint(defaultEntryPoint);
return retVal;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
ExceptionHandlingConfigurer<HttpSecurity> exceptionHandling = http.exceptionHandling();
exceptionHandling.authenticationEntryPoint(delegatingAuthenticationEntryPoint());
http.logout().logoutSuccessHandler(new LogoutSuccessHandler() {
@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication arg2)
throws IOException, ServletException {
response.setStatus(HttpServletResponse.SC_OK);
}
});
}
}
@配置
@启用WebMVC安全性
公共类SecurityCxConfig扩展了WebSecurity配置适配器{
@豆子
DelegatingAuthenticationEntryPoint DelegatingAuthenticationEntryPoint(){
LinkedHashMap=新建LinkedHashMap();
Http403禁止入口点defaultEntryPoint=新的Http403禁止入口点();
put(AnyRequestMatcher.INSTANCE,defaultEntryPoint);
DelegatingAuthenticationEntryPoint retVal=新的DelegatingAuthenticationEntryPoint(地图);
retVal.setDefaultEntryPoint(defaultEntryPoint);
返回返回;
}
@凌驾
受保护的无效配置(HttpSecurity http)引发异常{
ExceptionHandlingConfigurer exceptionHandling=http.exceptionHandling();
exceptionHandling.authenticationEntryPoint(delegatingAuthenticationEntryPoint());
http.logout().logoutSuccessHandler(新logoutSuccessHandler()){
@凌驾
public void onLogoutSuccess(HttpServletRequest请求、HttpServletResponse响应、身份验证arg2)
抛出IOException、ServletException{
response.setStatus(HttpServletResponse.SC_OK);
}
});
}
}
如果会话cookie无效或丢失(无论原因如何),则需要返回Http状态401
我看到了InvalidSessionStrategy
,但我没有找到在SessionManagementFilter
上设置它的方法。
有人能告诉我如何实施我的计划或另一个满足要求的计划吗,因为我使用的是AspectJ(我的意思是编译时编织,而不是Spring AOP),在构建SessionManagementFilter
之后,通过设置我的自定义InvalidSessionStrategy
可以很容易地破解SessionManagementFilter
创建:
@Aspect
public class SessionManagementAspect {
private static final Log logger = LogFactory.getLog();
@AfterReturning("execution( org.springframework.security.web.session.SessionManagementFilter.new(..))&&this(smf)")
public void creation(JoinPoint pjp, SessionManagementFilter smf) throws Throwable {
logger.debug("Adding/Replacing the invalid session detection policy to return 401 in case of an invalid session");
smf.setInvalidSessionStrategy(new InvalidSessionStrategy() {
@Override
public void onInvalidSessionDetected(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
logInvalidSession(request, "invalid cookie");
if (!response.isCommitted())
response.sendError(HttpStatus.UNAUTHORIZED.value());
}
});
}
}
如果您没有使用AspectJ,请尝试添加
@Component
,并将此方面添加到您的上下文中,如果SessionManagementFilter
是一个bean(因为Spring AOP应用程序只在Spring bean上运行)我们遇到了完全相同的问题,我做了这个hack来解决它(是的,我知道,这是一个hack,因此名称…)。
我创建一个BeanPostProcessor
并搜索SessionManagementFilter
以重新配置它
@Bean
public HackyBeanPostProcessor myBeanPostProcessor() {
return new HackyBeanPostProcessor();
}
protected static class HackyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
// FIXME check if a new spring-security version allows this in an
// other way (current: 3.2.5.RELEASE)
if (bean instanceof SessionManagementFilter) {
SessionManagementFilter filter = (SessionManagementFilter) bean;
filter.setInvalidSessionStrategy(new InvalidSessionStrategy() {
@Override
public void onInvalidSessionDetected(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
}
});
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
return bean;
}
}
使用SpringBoot这对我很有用:
@Configuration
@EnableWebSecurity
public class UISecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
...
http.addFilterAfter(expiredSessionFilter(), SessionManagementFilter.class);
...
}
private Filter expiredSessionFilter() {
SessionManagementFilter smf = new SessionManagementFilter(new HttpSessionSecurityContextRepository());
smf.setInvalidSessionStrategy((request, response) -> response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Session go BOOM!"));
return smf;
}
}
您找到方法了吗?此解决方案有效,应该被称为Spring Security 4,2+的解决方案,可以在XML配置中使用元素会话管理和无效会话策略引用属性在安全http部分中完成。@pedorro,谢谢,这在Spring Security 5.1.4中也有效:-)