artemb
artemb

Reputation: 9371

Spring Security - need 403 error, not redirect

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

Answers (5)

hillel_guy
hillel_guy

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

usethe4ce
usethe4ce

Reputation: 23819

you need to

  • Create a RequestMatcher to determine which requests should get a 403 (AntPathRequestMatcher may suffice in your case).
  • Configure the HttpSessionRequestCache to check the matcher and not store those pages for post-login redirect.
  • Use a 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

Bartosz Bilicki
Bartosz Bilicki

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

tzrlk
tzrlk

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

Javi
Javi

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

Related Questions