हम वसंत एमवीसी + वसंत सुरक्षा + हाइबरनेट के साथ एक विश्वसनीय API बना रहे हैं। एपीआई जेएसओएन और एचटीएमएल दोनों का उत्पादन कर सकता है। वसंत सुरक्षा के लिए एक अच्छी त्रुटि हैंडलिंग करना मुझे सिरदर्द दे रहा है:वसंत सुरक्षा में कस्टम अपवादों को संभालें
प्रमाणीकरण विभिन्न तरीकों से हो सकता है: मूल अनुरोध, POST अनुरोध में विभिन्न पैरामीटर के माध्यम से और वेब लॉग-इन के माध्यम से भी। प्रत्येक प्रमाणीकरण तंत्र के लिए, वसंत सुरक्षा xml कॉन्फ़िगरेशन के <http>
नेमस्पेस तत्व में घोषित एक फ़िल्टर है।
हम अपने सभी वसंत अपवादों को कस्टम HandlerExceptionResolver
में संभालते हैं। यह हमारे नियंत्रकों में फेंकने वाले सभी अपवादों के लिए ठीक काम करता है, लेकिन मुझे नहीं पता कि कस्टम वसंत सुरक्षा फ़िल्टर में फेंकने वाले कस्टम अपवादों को कैसे संभाला जाए। चूंकि वसंत सुरक्षा फ़िल्टर हमारे किसी भी नियंत्रक के आने से पहले आता है, इसलिए हमें अपवाद नहीं दिखते हैं कि हम अपने कस्टम वसंत सुरक्षा फ़िल्टर में फेंक देते हैं।
मुझे यह प्रश्न यहां stackoverflow पर मिला: Use custom exceptions in Spring Security। हालांकि मुझे नहीं पता कि वे वहां फेंकने वाले अपवादों को कैसे संभालते हैं। हमने इस दृष्टिकोण की कोशिश की लेकिन हमारे कस्टम HandlerExceptionResolver
को नहीं कहा जाता है। इसके बजाए उपयोगकर्ता को टॉमकैट द्वारा प्रस्तुत एक बदसूरत स्टैकट्रस के साथ प्रस्तुत किया जाता है।
हमें इसकी आवश्यकता क्यों है? उपयोगकर्ताओं को सक्रिय और निष्क्रिय किया जा सकता है। यदि वे निष्क्रिय हैं और कुछ क्रियाएं करने का प्रयास करते हैं तो हम एक कस्टम त्रुटि संदेश के साथ जेएसओएन वापस करना चाहते हैं। वसंत सुरक्षा AccessDeniedException
फेंकने पर यह प्रदर्शित होने से अलग होना चाहिए। AccessDeniedException
किसी भी तरह से यह हमारे HandlerExceptionResolver
पर बनाता है, लेकिन मैं वास्तव में कैसे पालन नहीं कर सका।
संभव समाधान हम एक ExceptionTranslationFilter
का उपयोग कर के बारे में सोचा है, लेकिन इस नहीं बुलाया जाता है जब हम अपने कस्टम अपवाद (विधि doFilter() की पकड़ बयान में एक ब्रेकपाइंट सेट) फेंक देते हैं। मेरी समझ में इस पकड़ ब्लॉक को बुलाया जाना चाहिए और प्रमाणीकरण प्रविष्टि बिंदु का उपयोग किया जाना चाहिए।
एक और संभावना है: हम वसंत सुरक्षा फिल्टर श्रृंखला में ExceptionTranslationFilter
के लिए इसी तरह कुछ करना है और क्या इसके AccessDeniedHandler
करता है के लिए इसी तरह कुछ कर सकते हैं:
RequestDispatcher dispatcher = request.getRequestDispatcher(errorPage);
dispatcher.forward(request, response);
हम कुछ पैरामीटर जोड़ सकता है (त्रुटि कोड, कारण आदि) अनुरोध के लिए और यह एक नियंत्रक को इंगित करता है जो JSON या HTML में प्रतिपादन का ख्याल रखेगा।
स्प्रिंग सुरक्षा::
यहाँ हमारे विन्यास की एक छोटी अंश है
<http create-session="stateless" use-expressions="true" >
<!-- Try getting the authorization object from the request parameters. -->
<security:custom-filter ref="filter1" after="SECURITY_CONTEXT_FILTER"/>
<security:custom-filter ref="filter2" before="LOGOUT_FILTER"/>
<!-- Intercept certain URLS differently -->
<intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')" />
<!-- Some more stuff here -->
<intercept-url pattern="/**" access="denyAll" />
<http-basic />
</http>
HandlerExceptionResolver
@Bean
public HandlerExceptionResolver handlerExceptionResolver(){
logger.info("creating handler exception resolver");
return new AllExceptionHandler();
}
हमारे कस्टम HandlerExceptionResolver की AppConfig
public class AllExceptionHandler implements HandlerExceptionResolver {
private static final Logger logger = LoggerFactory
.getLogger(AppConfig.class);
@Override
public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex) {
// This is just a snipped of the real method code
return new ModelAndView("errorPage");
}
हमारे फ़िल्टर में से एक के प्रासंगिक भाग:
try {
Authentication authResult = authenticationManger.authenticate(authRequest);
SecurityContextHolder.getContext().setAuthentication(authResult);
}
catch(AuthenticationException failed) {
SecurityContextHolder.clearContext();
throw failed;
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<context-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>xxx.xxx.xxx.config</param-value>
</context-param>
<context-param>
<param-name>spring.profiles.default</param-name>
<param-value>LIVE</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value></param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<!-- Add multipart support for files up to 10 MB -->
<multipart-config>
<max-file-size>10000000</max-file-size>
</multipart-config>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>openEntityManagerInViewFilter</filter-name>
<filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>openEntityManagerInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<!-- Map filters -->
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<error-page>
<error-code>404</error-code>
<location>/handle/404</location>
</error-page>
</web-app>
किसी को भी हम यह कैसे हल कर सकते थे पर किसी भी संकेत दिए गए है? मैंने Google पर कई लेखों को देखा, उनमें से अधिकतर वर्णन करते हैं कि वसंत सुरक्षा द्वारा फेंक दिया गया AccessDeniedException को कैसे संभालना है जब कोई फ़िल्टर अनुरोध प्रमाणित करने में सक्षम नहीं होता है।
हम वसंत सुरक्षा 3.1.0 और वसंत वेब एमवीसी 3.1.0 का उपयोग कर रहे हैं।
आपके उत्तर के लिए धन्यवाद: बस यह सुनिश्चित करने के लिए कि अगर मैं आपको सही तरीके से समझता हूं। आप मेरे फ़िल्टर के लिए = "EXCEPTION_TRANSLATION_FILTER" के बाद कुछ का उपयोग करने का सुझाव देते हैं। – David
हां। 'EXCEPTION_TRANSLATION_FILTER' के बाद कोई भी स्थिति अच्छी है। –
यह एक कस्टम हैंडलर के साथ संयोजन में चाल करेगा। धन्यवाद! – David