Après avoir lutté avec les nombreuses solutions publiées dans cette réponse, pour essayer de faire fonctionner quelque chose lors de l'utilisation de la <http>configuration de l' espace de noms, j'ai finalement trouvé une approche qui fonctionne réellement pour mon cas d'utilisation. Je n'ai pas vraiment besoin que Spring Security ne démarre pas une session (parce que j'utilise session dans d'autres parties de l'application), mais simplement qu'il ne se "souvienne" pas du tout de l'authentification dans la session (il devrait être revérifié chaque demande).
Pour commencer, je n'ai pas pu comprendre comment faire la technique "d'implémentation nulle" décrite ci-dessus. Il n'était pas clair si vous êtes censé définir le securityContextRepository sur nullou sur une implémentation sans opération. Le premier ne fonctionne pas car un NullPointerExceptionest jeté à l'intérieur SecurityContextPersistenceFilter.doFilter(). En ce qui concerne l'implémentation no-op, j'ai essayé de l'implémenter de la manière la plus simple que je puisse imaginer:
public class NullSpringSecurityContextRepository implements SecurityContextRepository {
@Override
public SecurityContext loadContext(final HttpRequestResponseHolder requestResponseHolder_) {
return SecurityContextHolder.createEmptyContext();
}
@Override
public void saveContext(final SecurityContext context_, final HttpServletRequest request_,
final HttpServletResponse response_) {
}
@Override
public boolean containsContext(final HttpServletRequest request_) {
return false;
}
}
Cela ne fonctionne pas dans mon application, à cause d'un étrange ClassCastExceptionrapport avec le response_type.
Même en supposant que j'ai réussi à trouver une implémentation qui fonctionne (en ne stockant simplement pas le contexte en session), il reste le problème de savoir comment l'injecter dans les filtres construits par la <http>configuration. Vous ne pouvez pas simplement remplacer le filtre à la SECURITY_CONTEXT_FILTERposition, comme indiqué dans la documentation . Le seul moyen que j'ai trouvé pour accrocher dans le SecurityContextPersistenceFilterqui est créé sous les couvertures était d'écrire un ApplicationContextAwareharicot laid :
public class SpringSecuritySessionDisabler implements ApplicationContextAware {
private final Logger logger = LoggerFactory.getLogger(SpringSecuritySessionDisabler.class);
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(final ApplicationContext applicationContext_) throws BeansException {
applicationContext = applicationContext_;
}
public void disableSpringSecuritySessions() {
final Map<String, FilterChainProxy> filterChainProxies = applicationContext
.getBeansOfType(FilterChainProxy.class);
for (final Entry<String, FilterChainProxy> filterChainProxyBeanEntry : filterChainProxies.entrySet()) {
for (final Entry<String, List<Filter>> filterChainMapEntry : filterChainProxyBeanEntry.getValue()
.getFilterChainMap().entrySet()) {
final List<Filter> filterList = filterChainMapEntry.getValue();
if (filterList.size() > 0) {
for (final Filter filter : filterList) {
if (filter instanceof SecurityContextPersistenceFilter) {
logger.info(
"Found SecurityContextPersistenceFilter, mapped to URL '{}' in the FilterChainProxy bean named '{}', setting its securityContextRepository to the null implementation to disable caching of authentication",
filterChainMapEntry.getKey(), filterChainProxyBeanEntry.getKey());
((SecurityContextPersistenceFilter) filter).setSecurityContextRepository(
new NullSpringSecurityContextRepository());
}
}
}
}
}
}
}
Quoi qu'il en soit, à la solution qui fonctionne réellement, bien que très hackish. Utilisez simplement un Filterqui supprime l'entrée de session HttpSessionSecurityContextRepositoryrecherchée quand il fait son truc:
public class SpringSecuritySessionDeletingFilter extends GenericFilterBean implements Filter {
@Override
public void doFilter(final ServletRequest request_, final ServletResponse response_, final FilterChain chain_)
throws IOException, ServletException {
final HttpServletRequest servletRequest = (HttpServletRequest) request_;
final HttpSession session = servletRequest.getSession();
if (session.getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY) != null) {
session.removeAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
}
chain_.doFilter(request_, response_);
}
}
Puis dans la configuration:
<bean id="springSecuritySessionDeletingFilter"
class="SpringSecuritySessionDeletingFilter" />
<sec:http auto-config="false" create-session="never"
entry-point-ref="authEntryPoint">
<sec:intercept-url pattern="/**"
access="IS_AUTHENTICATED_REMEMBERED" />
<sec:intercept-url pattern="/static/**" filters="none" />
<sec:custom-filter ref="myLoginFilterChain"
position="FORM_LOGIN_FILTER" />
<sec:custom-filter ref="springSecuritySessionDeletingFilter"
before="SECURITY_CONTEXT_FILTER" />
</sec:http>