Ответ 1
Я решил свою проблему, поэтому, думаю, я должен поделиться ею здесь. Эта конфигурация позволяет серверу отправлять сообщение об ошибке по-разному в зависимости от запрашивающего программного обеспечения. Если запрос поступает из веб-браузера, он проверяет заголовок User-Agent
и перенаправляет на регистрацию формы, если это необходимо. Если запрос исходит, например, curl
, он будет распечатывать сообщение об ошибке обычного текста, когда аутентификация завершится с ошибкой.
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:sec="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd">
<!-- AspectJ pointcut expression that locates our "post" method and applies security that way
<protect-pointcut expression="execution(* bigbank.*Service.post*(..))" access="ROLE_TELLER"/>-->
<sec:global-method-security secured-annotations="enabled"/>
<bean id="basicAuthenticationFilter"
class="org.springframework.security.web.authentication.www.BasicAuthenticationFilter"
p:authenticationManager-ref="authenticationManager"
p:authenticationEntryPoint-ref="basicAuthenticationEntryPoint" />
<bean id="basicAuthenticationEntryPoint"
class="webapp.PlainTextBasicAuthenticationEntryPoint"
p:realmName="myWebapp"/>
<bean id="formAuthenticationEntryPoint"
class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint"
p:loginFormUrl="/login.jsp"/>
<bean id="daep" class="org.springframework.security.web.authentication.DelegatingAuthenticationEntryPoint">
<constructor-arg>
<map>
<entry key="hasHeader('User-Agent','Mozilla') or hasHeader('User-Agent','Opera') or hasHeader('User-Agent','Explorer')" value-ref="formAuthenticationEntryPoint" />
</map>
</constructor-arg>
<property name="defaultEntryPoint" ref="basicAuthenticationEntryPoint"/>
</bean>
<sec:http entry-point-ref="daep">
<sec:intercept-url pattern="/login.jsp*" filters="none"/>
<sec:intercept-url pattern="/json" access="ROLE_USER,ROLE_ADMIN" />
<sec:intercept-url pattern="/json/*" access="ROLE_USER,ROLE_ADMIN" />
<sec:logout
logout-url="/logout"
logout-success-url="/home.jsp"/>
<sec:form-login
login-page="/login.jsp"
login-processing-url="/login"
authentication-failure-url="/login.jsp?login_error=1" default-target-url="/home.jsp"/>
<sec:custom-filter position="BASIC_AUTH_FILTER" ref="basicAuthenticationFilter" />
</sec:http>
<sec:authentication-manager alias="authenticationManager">
<sec:authentication-provider>
...
</sec:authentication-provider>
</sec:authentication-manager>
</beans>
PlainTextBasicAuthenticationEntryPoint
, расширяя org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint;
public class PlainTextBasicAuthenticationEntryPoint extends BasicAuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
response.addHeader("WWW-Authenticate", "Basic realm=\"" + getRealmName() + "\"");
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
PrintWriter writer = response.getWriter();
writer.println("HTTP Status " + HttpServletResponse.SC_UNAUTHORIZED + " - " + authException.getMessage());
}
}