Spring boot Spring:转发到/oauth/token端点将丢失身份验证

Spring boot Spring:转发到/oauth/token端点将丢失身份验证,spring-boot,spring-security,spring-oauth2,Spring Boot,Spring Security,Spring Oauth2,我正在构建一个Spring启动授权服务器,它需要使用两种不同的身份验证方法生成Oauth2令牌。我希望每个方法都有一个不同的端点,但默认情况下Spring只创建/oauth/token,虽然它可以更改,但我认为它不可能有两个不同的路径 作为替代方案,我尝试在控制器中创建两个方法,它们执行内部转发到/oauth/token,向请求添加一个参数,以便知道它来自何处 我有这样的想法: @RequestMapping(value=“/foo/oauth/token”,method=RequestMeth

我正在构建一个Spring启动授权服务器,它需要使用两种不同的身份验证方法生成Oauth2令牌。我希望每个方法都有一个不同的端点,但默认情况下Spring只创建
/oauth/token
,虽然它可以更改,但我认为它不可能有两个不同的路径

作为替代方案,我尝试在控制器中创建两个方法,它们执行内部转发到
/oauth/token
,向请求添加一个参数,以便知道它来自何处

我有这样的想法:

@RequestMapping(value=“/foo/oauth/token”,method=RequestMethod.POST)
公共模型和视图fooauth(模型映射模型){
addAttribute(“方法”、“foo”);
返回新模型和视图(“转发:/oauth/token”,模型);
}
这将正确执行转发,但身份验证失败,原因是:

There is no client authentication. Try adding an appropriate authentication filter.
当直接发送到
/oauth/token
时,相同的请求可以正常工作,因此我猜问题在于转发后BasicAuthenticationFilter没有运行


如何使其工作?

仔细查看为Oauth端点和转发控制器创建的筛选器链,很容易发现后者缺少BasicAuthenticationFilter,因为它们没有经过身份验证,并且在转发之后不会再次执行身份验证

为了解决这个问题,我创建了一个新配置,如下所示:

@配置
公共类转发器安全配置扩展了WebSecurity配置适配器{
@自动连线
私有列表),在两个端点上运行具有相同身份验证选项的相同筛选器链

/oauth/token
端点最终运行时,它会找到预期的身份验证结果,一切正常


最后,如果您想在两个转发端点上运行不同的ClientDetails服务,只需创建两个类似这样的配置类,并在每个类中的
SetShareObject
调用中替换ClientDetails服务。请注意,为此,您必须在每个类中设置不同的
@Order
值。

<>我也有同样的问题。经过一些研究,我发现问题是由Spring Boot 2引起的,而不是由Spring安全配置引起的。根据:

Spring安全和Spring会话筛选器配置为异步、错误和请求调度程序类型

以及Spring Boot的源代码:

@Bean
@ConditionalOnBean(name = DEFAULT_FILTER_NAME)
public DelegatingFilterProxyRegistrationBean securityFilterChainRegistration(
        SecurityProperties securityProperties) {
    DelegatingFilterProxyRegistrationBean registration = new DelegatingFilterProxyRegistrationBean(
            DEFAULT_FILTER_NAME);
    registration.setOrder(securityProperties.getFilter().getOrder());
    registration.setDispatcherTypes(getDispatcherTypes(securityProperties));
    return registration;
}

private EnumSet<DispatcherType> getDispatcherTypes(
        SecurityProperties securityProperties) {
    if (securityProperties.getFilter().getDispatcherTypes() == null) {
        return null;
    }
    return securityProperties.getFilter().getDispatcherTypes().stream()
            .map((type) -> DispatcherType.valueOf(type.name())).collect(Collectors
                    .collectingAndThen(Collectors.toSet(), EnumSet::copyOf));
}
因此,默认情况下,Spring Boot配置Spring安全性,使其筛选器不会应用于转发请求(而仅适用于异步、错误和请求),因此,在将请求转发到
/oauth/token
时,不会应用任何安全筛选器对请求进行身份验证

解决方案很简单。您可以在
应用程序.properties
中添加以下行,以便对所有转发的请求应用默认筛选器

spring.security.filter.dispatcher-types=async,error,request,forward
或者使用路径匹配器和dispatcherType=FORWARD创建您自己的自定义筛选链,以仅筛选转发给
/oauth/token
的请求

spring.security.filter.dispatcher-types=async,error,request,forward