Reputation: 9371
I am using Spring Security 3.0.4. I have a bunch of web service which are protected by Spring Security. When I access them as an unauthenticated user, Spring Security redirects to login page. Instead of that, I want to return HTTP 403 error. How can I achieve that?
Here is my security config:
<http auto-config="false" use-expressions="true" >
<intercept-url pattern="/authorization.jsp" access="permitAll"/>
<intercept-url pattern="/registration.jsp" access="permitAll"/>
<intercept-url pattern="/api/authorization/auth" access="permitAll"/>
<intercept-url pattern="/api/authorization/new" access="permitAll"/>
<intercept-url pattern="/api/accounts/new" access="permitAll"/>
<intercept-url pattern="/app/**" access="permitAll"/>
<intercept-url pattern="/extjs/**" access="permitAll"/>
<intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
<form-login login-page="/authorization.jsp"
default-target-url="/index.jsp"
authentication-failure-url="/registration.jsp?login_error=1"
always-use-default-target="true"
/>
<logout logout-success-url="/authorization.jsp"
logout-url="/j_spring_security_logout"
invalidate-session="true"/>
</http>
Upvotes: 40
Views: 21980
Reputation: 696
This solution worked for me (reference)
http
...
.oauth2Login().permitAll()
.and().exceptionHandling()
.defaultAuthenticationEntryPointFor(
new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED),
new RequestHeaderRequestMatcher("X-Requested-With", "XMLHttpRequest"))
...
Upvotes: 0
Reputation: 23819
you need to
RequestMatcher
to determine which requests should get a 403 (AntPathRequestMatcher
may suffice in your case).HttpSessionRequestCache
to check the matcher and not store those pages for post-login redirect.DelegatingAuthenticationEntryPoint
to either 403 the request outright or redirect to login according to the matcher.See the example here:
http://distigme.wordpress.com/2012/11/01/ajax-and-spring-security-form-based-login/
Upvotes: 10
Reputation: 13235
For java configuration you need to do
http.exceptionHandling().authenticationEntryPoint(alwaysSendUnauthorized401AuthenticationEntryPoint);
Where alwaysSendUnauthorized401AuthenticationEntryPoint is innstance of class
public class AlwaysSendUnauthorized401AuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public final void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException {
LOGGER.debug("Pre-authenticated entry point called. Rejecting access");
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
}
}
This disables default behavior of Spring (redirecting unauthenticated requests to login form).
Side note: for such case HTTP code SC_UNAUTHORIZED(401) is better choice than SC_FORBIDDEN(403).
Upvotes: 17
Reputation: 896
There's an article on the spring forums here that outlines how to get your app determining between the two methods. So far I'm using the following code to secure my data controllers:
<bean id="ep403" class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint"/>
<sec:http pattern="/data/**" entry-point-ref="ep403" use-expressions="true">
<sec:intercept-url pattern="/**" access="isAuthenticated()"/>
</sec:http>
<bean id="epauth" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<constructor-arg value="/login.html"/>
</bean>
<sec:http pattern="/**" entry-point-ref="epauth" use-expressions="true">
<sec:intercept-url pattern="/**" access="isAuthenticated()"/>
</sec:http>
So the whole DelegatingAuthenticationEntryPoint solution in the article I linked is a bit more heavyweight, but I imagine it does the job just fine as well.
Upvotes: 10
Reputation: 19769
It should return a 403 error unless you configure it to go to another url with this tag:
<sec:access-denied-handler error-page="/urlToGoIfForbidden" />
Upvotes: -4