Ashish Agarwal
Ashish Agarwal

Reputation: 51

Spring Security show 404 if user is not authorize

My spring security configuration is

<http pattern="/resources/**" security="none"/>
    <http pattern="/login**" security="none"/>
    <http pattern="/invalidsession**" security="none"/>
    <http pattern="/forgotpassword**" security="none"/>
    <http pattern="/accessdenied**" security="none"/>
    <http auto-config="true" use-expressions="true">
        <intercept-url pattern="/common/**" access="hasAnyRole('SITE_ADMIN','CLIENT_ADMIN')" />
        <intercept-url pattern="/site/**" access="hasRole('SITE_ADMIN')" />
        <intercept-url pattern="/**" access="hasRole('CLIENT_ADMIN')" />
        <!-- access denied page 
        <access-denied-handler error-page="/accessdenied" />
        -->
        <access-denied-handler ref="my403" />
        <form-login login-page="/login" 
             username-parameter="username"
            password-parameter="password"  authentication-failure-url="/login?error" 
            authentication-success-handler-ref="myAuthenticationSuccessHandler"
            />
        <logout logout-success-url="/login?logout" />
        <session-management invalid-session-url="/invalidsession" />
    </http>

When SITE_ADMIN user open a page which does not exist then It shows access denied page instead of 404 page. It is doing because of <intercept-url pattern="/**" access="hasRole('CLIENT_ADMIN')" />. Spring security is checking authorization before pagenotfound. how can i show 404 if page does not exist and SITE_ADMIN is currently logging.

Upvotes: 1

Views: 1787

Answers (2)

Serge Ballesta
Serge Ballesta

Reputation: 148965

This requirement will be rather hard to fulfill : Spring security filters do their web authorization tests before the dispatcher servlet has seen the request.

So what could be done ? Here are some paths but I never tried any of them.

1/ Use a custom AccessDeniedHandler. Its handle method will get the request and response, so it could try to pass them directly to the DispatcherServlet with a dummy response. The hard part would be to analyse the response to see if it is a 404 error page, and if it is copy the dummy response in the real response, otherwise proceed with default AccessDeniedHandlerImpl method. Looks like rather hacky ...

2/ Give up with web security and only use method security consistently on all your service methods. That way, the security will only be called if the DispatcherServlet successfully found a controller for the request. The drawback it that you will get no security for static pages. But this way if much more spring way.

Anyway, I would never try to do that. I someone is not allowed to go in a particular hierarchy, I do not want him to know exactly what pages exist. I am not particularly fond of security by obfuscation, but I prefere hiding everything that is not directly usefull for the user.

Upvotes: 1

iamiddy
iamiddy

Reputation: 3073

Not sure why you want this, but you can accomplish it by Implementing AuthenticationEntryPoint and have the commence method set 404 for your CLIENT_ADMIN and leave the default for everyone else

something like

   @Component
  public class EntryPointUnauthorizedHandler implements AuthenticationEntryPoint{
            @Override
 public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,AuthenticationException e) throws IOException, ServletException {
     // use SecurityContextHolder.getContext() for your security checks
     httpServletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED,"Access Denied");
                }

            }

Now you can add the entry-point in your http-security config

Upvotes: 1

Related Questions