spring-security 收到空凭据(用户名和密码)时如何创建自定义响应?
Posted
技术标签:
【中文标题】spring-security 收到空凭据(用户名和密码)时如何创建自定义响应?【英文标题】:How create a custom response when spring-security receives null credentials (username and password)? 【发布时间】:2015-08-24 10:20:33 【问题描述】:我正在使用邮递员将用户名和密码没有价值发送到我的服务器;就像username=null
和password=null
。
为了控制我的服务器的安全性,我使用 spring security 3.2。当它收到这些凭据时,spring-security 会响应此错误。
Estado HTTP 500 - Fields must not be empty
java.lang.IllegalArgumentException: Cannot pass null or empty values to constructor
org.springframework.security.core.userdetails.User.<init>(User.java:99)
org.springframework.security.core.userdetails.User.<init>(User.java:69)
com.equifax.product.fraud.applicationprocessing.web.rest.interceptors.security.SecurityAuthenticationProvider.retrieveUser(SecurityAuthenticationProvider.java:59)
org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:132)
org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:156)
org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:177)
org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:168)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344)
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261)
我想输出带有错误消息的自定义 JSON,我该怎么做?
这是我的 security.xml:
<security:http create-session="never" use-expressions="true"
auto-config="false">
<security:intercept-url pattern="/application/**"
access="isFullyAuthenticated()" />
<security:anonymous />
<security:http-basic entry-point-ref="securityAccessDeniedEntryPoint" />
<security:access-denied-handler ref="securityAccessDeniedHandler" />
</security:http>
<security:authentication-manager alias="authenticationManager"
erase-credentials="false">
<security:authentication-provider
ref="genericSecurityAuthenticationProvider" />
</security:authentication-manager>
我正在使用 Spring 3.2
【问题讨论】:
一个普遍的问题,你在这个项目中使用 Jersey 库吗? 第二个问题,你用的是什么Spring版本? @ThomasWeglinski 我使用的是 spring 3.2,我不使用 Jersey。 【参考方案1】:您正在传递基本身份验证字符串“:”(在 base64 解码之后),因此正如您所说,这会导致空密码和用户名。 BasicAuthenticationFilter
将这些传递给身份验证提供程序,这是您的自定义代码 (SecurityAuthenticationProvider
),因此无法准确说出它的作用。在那里的某个地方,您正在使用这些值创建一个 User
实例,这会引发您看到的异常。相反,您应该检查 AuthenticationProvider
中的空值并抛出 Authenticationexception
。
您还需要覆盖BasicAuthenticationFilter
中的onUnsuccessfulAuthentication
函数以编写所需的错误响应。您必须将其配置为 custom filter,而不是使用 <security:http-basic />
元素。
【讨论】:
【参考方案2】:使用 spring security 的标准异常,如果你已经有一个异常处理程序将消息转换为 Json 响应,它将自行处理。
catch (Exception exception)
throw new AuthenticationCredentialsNotFoundException("Fields must not be empty", exception);
【讨论】:
为了这个工作,它是必要的创建一个entry-point-handler
和 access-denied-handler
与您的具体消息【参考方案3】:
你可以做的是定义一个AuthenticationFailureHandler bean,在你实现这个bean之后,你可以在onAuthenticationFailure()方法中做你想做的事情。
XML 配置:
<beans:bean id="myFailureHandler" class="my.custom.impl.MyCustomAuthenticationFailureHandler"/>
<security:http ....>
<security:form-login authentication-failure-handler-ref="myFailureHandler" />
</security:http>
http://docs.spring.io/autorepo/docs/spring-security/3.2.0.RELEASE/apidocs/org/springframework/security/web/authentication/AuthenticationFailureHandler.html
Obs.:如果您想做的事情不适用于此解决方案,您可以实现 AuthenticationProvider
【讨论】:
apperEstado HTTP 500 - Request processing failed; nested exception is com.example.product.fraud.basic.configuration.framework.exceptions.ConfigurationNotFoundException: User Configuration Not Found.
您可以做的另一件事是创建一个异常处理程序
这里的配置错误——需要在特定的过滤器上设置失败处理程序。但是,基本身份验证不支持身份验证失败处理程序,因此在这种情况下它不是一个选项。【参考方案4】:
在使用 spring security 之前我从来没有这样做过,但我认为这篇文章描述了你需要的一切:http://www.mkyong.com/spring-security/customize-http-403-access-denied-page-in-spring-security/
【讨论】:
不,这在这里没有帮助。拒绝访问处理程序仅适用于经过身份验证的用户。以上是关于spring-security 收到空凭据(用户名和密码)时如何创建自定义响应?的主要内容,如果未能解决你的问题,请参考以下文章
spring-security oauth2 REST 服务器在错误凭据(400)错误响应中不需要的 Stacktrace
带有 spring-security 的 OAuth2 - 通过 HTTP 方法限制 REST 访问
不断收到 401 未经授权的“无效凭据”Laravel Passport