我正在开发一个基于Spring-Boot - 1.1.6,Spring -Security -3.2.5等的Web应用程序。
我正在使用基于Java的配置:
@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);
}
});
}
}
要求是在会话cookie无效或丢失的情况下返回Http状态401(无论原因)
我看到InvalidSessionStrategy
,但我找不到在SessionManagementFilter
上设置它的方法。
有人可以告诉我如何实施我的计划或另一个符合要求的计划
答案 0 :(得分:5)
我们有完全相同的问题,我做了这个黑客来解决它(是的,我知道,这是一个黑客,因此名称......)。
我创建了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;
}
}
答案 1 :(得分:4)
使用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;
}
}
答案 2 :(得分:0)
由于我正在使用AspectJ(我的意思是编译时编织而不是Spring AOP),通过在{{1}之后设置我的自定义SessionManagementFilter
来破解InvalidSessionStrategy
创建非常容易。构造:
SessionManagementFilter
如果您没有使用AspectJ,请尝试添加@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());
}
});
}
}
并将此Aspect添加到您的上下文中,如果@Component
是一个bean(因为Spring-AOP applias仅适用于spring bean),它可能会起作用< / p>