SPNEGO身份验证失败的java自定义错误页
我有一个Spring MVC REST端点,我成功地将其配置为由Kerberos as recommended保护。成功认证后,一切正常。问题是当涉及到自定义401
错误页面时
我将其配置为(我是spring boot 1.3.5),如下所示:
@Bean
public EmbeddedServletContainerCustomizer containerCustomizer() {
return container -> container.addErrorPages(new ErrorPage(HttpStatus.UNAUTHORIZED, "/error/401.html"));
}
这很好地工作,我可以通过切换到基本身份验证并提供错误的凭据来确认
当使用Kerberos时-如果我使用kinit访问我的安全端点,一切正常,并且在curl中,我会看到详细的请求:
curl -v -u : --negotiate http://my-enpoint:8080/
> GET / HTTP/1.1
> Host: ...:8080
> User-Agent: curl/7.43.0
> Accept: */*
< HTTP/1.1 401 Unauthorized
< ...
< WWW-Authenticate: Negotiate
> GET / HTTP/1.1
> Host: ...:8080
> Authorization: Negotiate YIIH7 ...
< HTTP/1.1 200 OK
< Server: Apache-Coyote/1.1
< ...
现在,如果我做kdestroy并再次做卷曲:
curl -v -u : --negotiate http://my-enpoint:8080/
> GET / HTTP/1.1
> Host:...8080
> User-Agent: curl/7.43.0
> Accept: */*
< HTTP/1.1 401 Unauthorized
< ...
< WWW-Authenticate: Negotiate
。。。就这样。在这种情况下,spring返回401
作为预期的响应,这是握手的一部分,因此不会发送错误页面
下面是我的两个问题:
如果spring尝试进行协商,但客户机根本没有响应,它怎么可能回退到任何其他身份验证作为回退(form,basic)
# 1 楼答案
所以回到我的调查中
我观察到的这种行为是意料之中的。如果客户端(浏览器、curl)无法进行身份验证,则不会继续进行身份验证。提供定制页面的关键是
SpnegoEntrypoint
。它允许在其中指定转发URL,它的javadoc说明:重点是转发url任何资源,它将包含在第一个
401
响应中。您可以包括任何页面,而不仅仅是表单登录。在我的例子中,我包括自定义401错误页面,因为我不做任何身份验证回退然后,通信看起来就像客户端发送
GET
和get的返回401
响应,并在主体中显示我的自定义错误页面。如果客户端能够协商,它将完全忽略响应主体,并使用适当的令牌重新提交请求。如果无法进行身份验证,它会显示返回的任何内容——自定义错误页面# 2 楼答案
作为对第一个问题的回答:
我有相同的用例,但选择了另一种解决方案,在该解决方案中,我扩展了SpnegoEntryPoint,在响应中添加了一个小JSON主体,供REST客户端使用: