spring-security Spring OAuth2 -没有客户端身份验证,请尝试添加适当的身份验证筛选器

pieyvz9o  于 2022-11-11  发布在  Spring
关注(0)|答案(6)|浏览(214)

我们有一个使用spring-security-oauth2:1.0的应用程序。我试图将其更改为新版本spring-security-oauth2:2.0.7.RELEASE。一些类被删除,一些包结构被更改,我设法整理了所有这些事情,我能够启动服务器没有任何问题。但我在这里面临一个奇怪的问题。
对于OAuth2 - 1.0 version,当用户登录时,我们通常在/oauth/token上执行GET请求,例如:
http://localhost:8080/echo/oauth/token?grant_type=password&client_id=ws&client_secret=secret&scope=read,write&username=john@abc.com&password=password123
以前还挺好的。
当我尝试同样的事情时,首先,由于TokenEndPoint.java中的逻辑,我无法发出GET请求

private Set<HttpMethod> allowedRequestMethods = new HashSet<HttpMethod>(Arrays.asList(HttpMethod.POST));

@RequestMapping(value = "/oauth/token", method=RequestMethod.GET)
public ResponseEntity<OAuth2AccessToken> getAccessToken(Principal principal, @RequestParam
Map<String, String> parameters) throws HttpRequestMethodNotSupportedException {
    if (!allowedRequestMethods.contains(HttpMethod.GET)) {
        throw new HttpRequestMethodNotSupportedException("GET");
    }
    return postAccessToken(principal, parameters);
}

我已经尝试了一个POST请求与上述URL相同,但我得到了InsufficientAuthenticationException与错误消息
没有客户端身份验证。请尝试添加适当的身份验证筛选器
这是因为TokenEndpoint.java中的以下POST请求控制器。当我调试时,我看到principal为空。

@RequestMapping(value = "/oauth/token", method=RequestMethod.POST)
    public ResponseEntity<OAuth2AccessToken> postAccessToken(Principal principal, @RequestParam
    Map<String, String> parameters) throws HttpRequestMethodNotSupportedException {
        //principal is null here
        if (!(principal instanceof Authentication)) {
            throw new InsufficientAuthenticationException(
                    "There is no client authentication. Try adding an appropriate authentication filter.");
        }
     .............
 }

我有一个身份验证过滤器,当我使用version 1.0时,它工作得很好。

<authentication-manager xmlns="http://www.springframework.org/schema/security">
        <authentication-provider user-service-ref="userDetailsService"/>
    </authentication-manager>

   <bean id="userDetailsService" class="com.hcl.nc.service.UserDetailsService">
        <constructor-arg><ref bean="sessionFactory" /></constructor-arg>
    </bean>

我一直认为请求会通过authentication-provider的验证,然后转到token-endpoint,但这似乎不是正确的流程。在用version 2.0.7调试了应用程序之后,现在我真的怀疑我对流程的理解。

有人能解释一下为什么它在以前的版本中工作,为什么现在不工作吗?
是否必须执行其他操作才能获得OAuth令牌??
:我已经检查了以下问题:hereherehere。但是我无法找到正确的解决方案。

sxissh06

sxissh061#

我不知道以前的版本,但我知道一点关于2.0.7。
我怀疑您的问题是您的TokenEndpoint安全性尝试针对您的 * 用户 * 服务验证您的 * 客户端 *。
TokenEndpoint受BasicAuthenticationFilter保护。默认情况下,此筛选器将使用AuthenticationManager示例,该示例本身包含AuthenticationProvider,而AuthenticationProvider本身依赖于UserDetailsService的示例。诀窍在于,UserDetailsService的此特定示例必须基于客户端,而不是基于用户:这就是为什么有ClientDetailsUserDetailsService,它将ClientDetailsService适配到UserDetailsService
通常,当您使用框架的配置类AuthorizationServerConfigurerAdapter@EnableAuthorizationServer等时,所有这些操作都已经默认完成了。

1aaf6o9v

1aaf6o9v2#

我遇到了同样的问题,我的application.yml有这样一行:

servlet:
    path: /auth

因此令牌地址为:/auth/oauth/token
我从application.yml中删除了路径,因此令牌路径变为:
/oauth/token
一切都很好。
我希望这对你有帮助

cnwbcb6i

cnwbcb6i3#

以下错误的问题之一,可能是没有执行身份验证。我在Spring的旧实现中遇到过这个问题。
请验证:
TokenEndpoint -〉postAccessToken方法。检查主体是否不为空。如果为空,则表示未执行基本身份验证。
添加过滤器的解决方案之一是用途:

@Configuration
public class FilterChainInitializer extends AbstractSecurityWebApplicationInitializer {

}

有关AbstractSecurityWebApplicationInitializer的更多信息,请参见Spring文档

lnxxn5zx

lnxxn5zx4#

在我例子中,我找到了以下配置:

安全性.allowFormAuthenticationForClients();//此处

然后发布此http://localhost:8081/sso/oauth/token?client_id=unity-client&client_secret=unity&grant_type=authorization_code&code=Yk4Sum&redirect_uri=http://localhost:8082/sso-demo/passport/login
对我很有效,试试吧

@Configuration
@EnableAuthorizationServer
public class Oauth2Config extends AuthorizationServerConfigurerAdapter {

    private static final Logger log = LoggerFactory.getLogger(Oauth2Config.class);

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security.allowFormAuthenticationForClients(); // here 
    }

    @Override
    public void configure(final ClientDetailsServiceConfigurer clients) throws Exception { // @formatter:off
        clients.inMemory()
                .withClient("unity-client")
                .secret("unity")
                .authorizedGrantTypes("authorization_code", "password", "client_credentials", "implicit", "refresh_token")
                .scopes("foo", "read", "write")
                .accessTokenValiditySeconds(3600) // 1 hour
                .refreshTokenValiditySeconds(2592000) // 30 days
        ;
    } // @formatter:on

    @Override
    public void configure(final AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
    }

}
c90pui9n

c90pui9n5#

此问题可能是由于打开所有请求造成的。您应该将其删除。

@Override
public void configure(WebSecurity web) throws Exception {
    web
            .ignoring()
            .antMatchers("/**");
}
dl5txlt9

dl5txlt96#

我正在学习这个教程-使用Spring Boot构建API后端的实用指南。请参见https://www.infoq.com/minibooks/spring-boot-building-api-backend,但是使用最新的SpringBoot版本(2.7)
我遇到了这个问题:
org.springframework.security.authentication.InsufficientAuthenticationException: There is no client authentication. Try adding an appropriate authentication filter. at org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.postAccessToken(TokenEndpoint.java:91) ~[spring-security-oauth2-2.3.5.RELEASE.jar:na]
我的解决方案/修正是用@EnableWebSecurity注解WebSecurityGlobalConfig,因为在原来的课程中这个注解是缺失的。所以添加这个注解已经为我修正了这个错误。

相关问题