Reputation: 51
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
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
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