इस जवाब में पोस्ट किए गए कई समाधानों के साथ संघर्ष करने के बाद, <http>
नाम स्थान के कॉन्फ़िगरेशन का उपयोग करते समय कुछ काम करने की कोशिश करने के लिए , मुझे आखिरकार एक दृष्टिकोण मिला जो वास्तव में मेरे उपयोग के मामले में काम करता है। मुझे वास्तव में इसकी आवश्यकता नहीं है कि स्प्रिंग सिक्योरिटी एक सत्र शुरू नहीं करती है (क्योंकि मैं अनुप्रयोग के अन्य भागों में सत्र का उपयोग करता हूं), बस यह कि यह सत्र में प्रमाणीकरण को "याद" नहीं करता है (इसे फिर से जांचना चाहिए हर अनुरोध)।
इसके साथ शुरू करने के लिए, मैं यह पता लगाने में सक्षम नहीं था कि ऊपर वर्णित "अशक्त कार्यान्वयन" तकनीक कैसे करें। यह स्पष्ट नहीं था कि क्या आप SecurityContextRepository को null
या किसी सेशन ऑप्शन पर सेट करने वाले हैं। पूर्व काम नहीं करता क्योंकि NullPointerException
भीतर फेंक दिया जाता है SecurityContextPersistenceFilter.doFilter()
। नो-ऑप कार्यान्वयन के लिए, मैंने सबसे सरल तरीके से लागू करने की कोशिश की जिसकी मैं कल्पना कर सकता हूं:
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;
}
}
यह मेरे आवेदन में काम नहीं करता है, क्योंकि कुछ अजीब प्रकार के ClassCastException
साथ करना है response_
।
यहां तक कि यह मानते हुए कि मैंने एक कार्यान्वयन खोजने का प्रबंधन किया है जो काम करता है (केवल सत्र में संदर्भ को संग्रहीत नहीं करता है), अभी भी समस्या है कि <http>
कॉन्फ़िगरेशन द्वारा निर्मित फ़िल्टर में कैसे इंजेक्ट किया जाए। डॉक्स केSECURITY_CONTEXT_FILTER
अनुसार आप केवल स्थान पर फ़िल्टर को प्रतिस्थापित नहीं कर सकते । जिस तरह से मैं हुक में पाया जाता है कि कवर के नीचे बनाया गया है एक बदसूरत बीन लिखने के लिए था :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());
}
}
}
}
}
}
}
वैसे भी, समाधान है कि वास्तव में काम करता है, यद्यपि बहुत hackish। बस Filter
उस सत्र प्रविष्टि को हटाता है जिसका उपयोग 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_);
}
}
फिर कॉन्फ़िगरेशन में:
<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>