当前位置: 首页 > 知识库问答 >
问题:

以编程方式访问spring security OAuth2 5.3时,使用OAuth2AuthorizedClient Manager设置BeareToken

严正初
2023-03-14

我设置了一个使用keycloak作为授权服务器的Spring Web应用程序。该应用程序配置为使用oauth2Login,需要用户使用keycloak登录。该Web应用程序还配置为oauth2Resourceserver,以便可以使用在keycloak中定义的角色保护其URL,这些角色从JWT自定义转换为JwtAuthentiationToken。配置如下所示:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests(authorizeRequests ->
                authorizeRequests.antMatchers("/test*").hasAnyRole("Dev", "QA")
                                 .anyRequest().authenticated())
            .oauth2ResourceServer(oauth2 -> oauth2.jwt(jwt -> jwt.jwtAuthenticationConverter(this.keycloakJwtAuthenticationConverter())))
            .oauth2Login(oauth2 -> oauth2.userInfoEndpoint(userInfo -> userInfo.userAuthoritiesMapper(this.userAuthoritiesMapper())))
            .oauth2Client();
    }
    ...

该应用程序还充当oauth2Client,它使用open-Feign调用其他设置为资源服务器的应用程序。我使用了一个伪请求拦截器,它试图将JWT令牌放入HTTP承载头中,如下所示:

@Autowired
private OAuth2AuthorizedClientManager authorizedClientManager;

@Bean
public RequestInterceptor requestInterceptor() {

    return requestTemplate -> {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId("keycloak")
                                                                        .principal(authentication)
                                                                        .build();
        OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(authorizeRequest);
        OAuth2AccessToken accessToken = authorizedClient.getAccessToken();

        requestTemplate.header(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken.getTokenValue());
    };
}

当用户使用KeyClope前端登录应用程序时,上述代码正常工作。

但是,当我不手动登录应用程序,而是使用keydepage auth-client时,请以编程方式登录

org.springframework.security.oauth2.client.ClientAuthorizationRequiredException: [client_authorization_required] Authorizathtml" target="_blank">ion required for Client Registration Id: keycloak

这导致登录html返回到RestTemplate,而不是预期的相关数据。。

共有1个答案

逄俊力
2023-03-14

经过深思熟虑,这可能不是处理来自在完全不同的应用程序中创建的承载令牌的身份验证的合适方法-我认为应用程序应该负责重新授权其自己的访问令牌。

如果用户通过keycloak登录,则从SecurityContext中检索的身份验证对象是OAuth2AuthentiationToken。如果调用来自具有JWT令牌的外部应用程序,该令牌是它获取并在超文本传输协议标头中设置为“承载”的,则身份验证对象是JwtAuthentiationToken。

希望这是区分这两个用例的适当方法。如果身份验证是OAuth2AuthentiationToken,那么可以使用上述代码成功重新授权它。如果它是JwtAuthentiationToken,那么我可以将令牌添加到承载超文本传输协议标头并让资源服务器验证它,而无需重新授权令牌,因为这应该由源应用程序完成。

 类似资料:
  • 问题内容: 我正在尝试在应用程序启动期间进行设置,但似乎为时已晚,非无头模式已经启动: 除此之外,还有另一种方法让无头为真吗?我不希望在控制台上进行任何配置。 问题答案: 我正在使用一个类,该类在常量(和其他静态代码)中静态加载JFreeChart的不同部分。 将静态加载块移到类的顶部解决了我的问题。 这不起作用: 通过将Java移动到类的顶部,让Java尽早执行该静态块! 当考虑它时,这是完全有

  • 问题内容: 我们使用下面的代码从属性文件中注入具有属性的Spring bean。 有没有一种方法可以通过编程方式访问属性?我试图做一些没有依赖注入的代码。所以我只想要一些这样的代码: 问题答案: 怎么样?

  • 服务器时间在单击按钮事件中自动设置为我的设备。

  • 有没有办法以编程方式自定义这些TextInputLayout属性: textColorHint 彩色口音 颜色控制正常 颜色控制已激活 文本选择句柄 我知道如何使用主题属性对它们进行样式化,但是我正在处理的项目动态地加载颜色信息,据我所知,在运行时无法更改主题/样式值。

  • 我正在开发与地图相关的android应用程序,如果未启用位置服务,我需要在客户端开发中检查是否启用位置访问显示对话框提示。 如何在android中以编程方式启用“位置访问”?