问题
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>
回答1:
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).
回答2:
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.
回答3:
you need to
- Create a
RequestMatcherto determine which requests should get a 403 (AntPathRequestMatchermay suffice in your case). - Configure the
HttpSessionRequestCacheto check the matcher and not store those pages for post-login redirect. - Use a
DelegatingAuthenticationEntryPointto 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/
回答4:
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" />
来源:https://stackoverflow.com/questions/4269686/spring-security-need-403-error-not-redirect