Java – handling custom exceptions in spring security

We are using spring MVC spring security hibernate to create a restful API

Authentication can occur in a variety of ways: basic auth, through different parameters in post requests, and through web login For each authentication mechanism, the namespace element configured in < HTTP > spring security XML

We handle all our spring exceptions in the custom handlerexceptionresolver This is good for all exceptions thrown in our controller, but I don't know how to handle custom exceptions thrown in the custom spring safety filter Because the spring safety filter didn't see us throw an exception in the custom spring safety filter before any of our controllers were called

I found this problem on stackoverflow: use custom exceptions in spring security But I don't understand where they handle exceptions thrown We tried this method, but our custom handlerexceptionresolver is not called Instead, the user is presented with an ugly stack trace presented by Tomcat

Why do we need this? Users can be activated and deactivated If they are disabled and try to do something, we want to return JSON with a custom error message This should be different from what is displayed when spring security raises accessdeniedexception Accessdeniedexception somehow makes it to our handlerexceptionresolver, but I can't follow exactly how

Possible solutions we consider using exceptiontranslationfilter, but when we throw our custom exception (set a breakpoint in the catch statement of the dofilter () method), this will not be called) In my understanding, this catch block should be called and an authentication entry point should be used

Another possibility: we can perform operations similar to exceptiontranslationfilter and accessdeniedhandler in the spring security filter chain:

RequestDispatcher dispatcher = request.getRequestDispatcher(errorPage);
dispatcher.forward(request,response);

We can add some parameters (error code, reason, etc.) to the request and point them to the controller that will handle rendering in JSON or HTML

Here is a brief excerpt of our configuration:

Spring safety:

<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>

AppConfig for handlerexceptionresolver

@Bean
public HandlerExceptionResolver handlerExceptionResolver(){
    logger.info("creating handler exception resolver");
    return new AllExceptionHandler();
}

Our custom handlerexceptionresolver

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");
}

The relevant part of one of our filters:

try {
    Authentication authResult = authenticationmanger.authenticate(authRequest);
    SecurityContextHolder.getContext().setAuthentication(authResult);
}

catch(AuthenticationException Failed) {
    SecurityContextHolder.clearContext();
    throw Failed; 
}

On the 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>

Does anyone have any instructions on how to solve this problem? I have read many articles about Google, most of which describe how to deal with the accessdenied exception thrown by spring security when there is no filter to verify the request

We use spring security 3.1 0 and spring web MVC 3.1 0

Solution

It is important to remember that the order of filters in spring security is important

From the spring security 3 Book:

If your filter is about authorization, it is a good practice to use the method used by the default authorization filter as the end of the chain So you don't have to reinvent it

Standard filter: table in documentation

After you configure the filter chain correctly, you can configure the error page and even customize the handler For more information, see documentation

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>