我有一个简单的 REST 应用程序,需要一些使用 HTTP 基本身份验证保护的资源。我不想看到容器生成 HTML 来响应此应用程序的客户端可能执行的任何操作。所以我像这样设置了 SpringSecurity:
<http pattern="/api/**" auto-config="true" create-session="stateless" entry-point-ref="entryPoint">
<intercept-url pattern="/**" method="PUT" access="ROLE_ADMIN" />
<intercept-url pattern="/**" method="POST" access="ROLE_ADMIN" />
<intercept-url pattern="/**" method="DELETE" access="ROLE_ADMIN" />
<http-basic />
</http>
<http security="none" />
<authentication-manager>
<authentication-provider>
<user-service id="userDetailsService"
properties="classpath:META-INF/spring/users.properties"/>
</authentication-provider>
</authentication-manager>
我的 EntryPoint 类如下所示:
public class BasicJsonEntryPoint extends BasicAuthenticationEntryPoint {
@Override
public void commence(
HttpServletRequest request,
HttpServletResponse response,
AuthenticationException authException
) throws IOException, ServletException {
response.addHeader("WWW-Authenticate", "Basic realm=\"" + getRealmName() + "\"");
response.setStatus(SC_UNAUTHORIZED);
PrintWriter writer = response.getWriter();
writer.println("{\"status\":" + SC_UNAUTHORIZED + ", \"message\":\"" + authException.getMessage() + "\"}");
}
}
当我点击 protected 资源/方法组合时,这会起作用,并且得到类似以下内容的内容;
HTTP/1.1 401 Unauthorized
Server: Apache-Coyote/1.1
WWW-Authenticate: Basic realm="Admin"
Content-Length: 84
Date: Sun, 29 Sep 2013 11:50:48 GMT
{"status":401, "message":"Full authentication is required to access this resource"}
..这正是我想要的。但是,如果我在 Authorize: HTTP header 中提供无效凭据,我会收到 Tomcat 的 HTML 响应...
HTTP/1.1 401 Unauthorized
Server: Apache-Coyote/1.1
WWW-Authenticate: Basic realm="Admin"
Content-Type: text/html;charset=utf-8
Content-Length: 1019
Date: Sun, 29 Sep 2013 11:51:14 GMT
<html><head><title>Apache Tomcat/7.0.33 - Error report</title><style><!--H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}HR {color : #525D76;}--></style> </head><body><h1>HTTP Status 401 - Invalid basic authentication token</h1><HR size="1" noshade="noshade"><p><b>type</b> Status report</p><p><b>message</b> <u>Invalid basic authentication token</u></p><p><b>description</b> <u>This request requires HTTP authentication.</u></p><HR size="1" noshade="noshade"><h3>Apache Tomcat/7.0.33</h3></body></html>
为了在这里获得相同的 JSON 响应,我还必须重写/实现什么(最好使用我已经创建的相同类)?
非常感谢,
最佳答案
问题出在 BasicAuthenticationFilter
中,它使用它自己的 BasicAuthenticationEntryPoint
实例而不是您的实现。所以你可以稍微调整一下:
<http auto-config="true" create-session="stateless">
<intercept-url .../>
<http-basic />
<custom-filter ref="basicAuthenticationFilter" before="BASIC_AUTH_FILTER" />
</http>
<beans:bean id="basicAuthenticationFilter"
class="org.springframework.security.web.authentication.www.BasicAuthenticationFilter">
<beans:property name="authenticationManager" ref="authenticationManager" />
<beans:property name="authenticationEntryPoint" ref="entryPoint" />
</beans:bean>
<beans:bean id="entryPoint" class="mypackage.BasicJsonEntryPoint">
<beans:property name="realmName" value="realm"/>
</beans:bean>
<authentication-manager alias="authenticationManager">
<authentication-provider>
...
</authentication-provider>
</authentication-manager>
关于java - 重写 spring-security BadCredentialsException 的容器响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19102095/