Bu yanıtta yayınlanan sayısız çözümle uğraştıktan sonra, <http>
ad alanı yapılandırmasını kullanırken çalışan bir şey elde etmeye çalıştıktan sonra , nihayet kullanım durumum için gerçekten işe yarayan bir yaklaşım buldum. Aslında Spring Security'nin bir oturum başlatmamasını istemiyorum (çünkü uygulamanın diğer bölümlerinde oturum kullanıyorum), sadece oturumdaki kimlik doğrulamasını hiç "hatırlamıyor" (yeniden kontrol edilmelidir) her istek).
Öncelikle, yukarıda açıklanan "boş uygulama" tekniğini nasıl yapacağımı çözemedim. SecurityContextRepository'yi null
işlemsiz bir uygulamaya mı ayarlamanız gerektiği açık değildi . İlki işe yaramıyor çünkü içine bir NullPointerException
atılıyor SecurityContextPersistenceFilter.doFilter()
. Operasyonsuz uygulamaya gelince, hayal edebileceğim en basit şekilde uygulamayı denedim:
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;
}
}
Bunun nedeni bazı garip, benim uygulamada çalışmıyor ClassCastException
ile yapmak zorunda response_
tip.
Çalışan bir uygulama bulmayı başardığımı varsayarsak bile (bağlamı oturumda saklamayarak), bunun <http>
konfigürasyon tarafından oluşturulan filtrelere nasıl enjekte edileceği sorunu hala var . Dokümanlara göreSECURITY_CONTEXT_FILTER
, filtreyi pozisyonda kolayca değiştiremezsiniz . Kapakların altında yaratılana bağlanmanın tek yolu çirkin bir fasulye yazmaktı :SecurityContextPersistenceFilter
ApplicationContextAware
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());
}
}
}
}
}
}
}
Her neyse, gerçekten işe yarayan çözüme, çok hileli de olsa. Basitçe , işini yaptığında aradığı Filter
oturum girişini silen bir kullanın HttpSessionSecurityContextRepository
:
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_);
}
}
Ardından konfigürasyonda:
<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>