如何确保让我的自定义 OidcUserService 被默认调用?

Posted

技术标签:

【中文标题】如何确保让我的自定义 OidcUserService 被默认调用?【英文标题】:How to ensure make my custom OidcUserService called over the default? 【发布时间】:2020-01-19 19:02:02 【问题描述】:

tl;dr:为什么我的OidcUserService虽然注册了却不是?


我正在尝试使用我自己的OAuth2UserService,方法是按照Spring Security documentation 中的说明进行注册。

但是,当我在 OidcUserService.loadUser(OidcUserRequest)](https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/oauth2/client/oidc/userinfo/OidcUserService.html#loadUser-org.springframework.security.oauth2.client.oidc.userinfo.OidcUserRequest-) 方法上设置断点时,它会一直命中 com.okta.spring.boot.oauth.OktaOidcUserService!我使用com.okta.spring:okta-spring-boot-parent:1.2.2-SNAPSHOT这可能是问题吗?

我注册了我的OidcUserServicelike documented:

@SpringBootApplication
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class RedirectCodeFlowApplication 

    public static void main(String[] args) 
        SpringApplication.run(RedirectCodeFlowApplication.class, args);
    

    @Configuration
    static class WebConfig extends WebSecurityConfigurerAdapter 
        @Override
        protected void configure(HttpSecurity http) throws Exception 
            final OidcUserService delegate = new OidcUserService();

            http.authorizeRequests().anyRequest().authenticated()
                .and()
                .oauth2Login()
                .userInfoEndpoint()
                .oidcUserService( (userRequest) -> 
                        System.out.println( "!!xXx!! never gets here" );

                        OidcUser oidcUser = delegate.loadUser(userRequest);

                        OAuth2AccessToken accessToken = userRequest.getAccessToken();
                        Set<GrantedAuthority> mappedAuthorities = new HashSet<>();

                        oidcUser = new DefaultOidcUser(mappedAuthorities, oidcUser.getIdToken(), oidcUser.getUserInfo());

                        return oidcUser;
                    )
            ;
        

而且我调用的方法很简单:

@RestController
public class WelcomeController 

    @GetMapping("/")
    public Welcome getMessageOfTheDay(Principal principal) 
        return "The message of the day is boring.";
    

本文均改编自:https://github.com/okta/okta-spring-boot/blob/master/examples/redirect-code-flow/src/main/java/com/okta/spring/example/RedirectCodeFlowApplication.java

【问题讨论】:

【参考方案1】:

这是一个已知问题:https://github.com/okta/okta-spring-boot/issues/136

这是一个用于处理 HttpSecurity 和 HttpConfigurer 如何加载的变通方法。

我不能 100% 确定我们可以解决这个问题,但是,公开一种添加自定义 GrantedAuthority 的方法会很容易。

我将再次研究前者,但作为最后的手段,您能否确认您正在尝试设置自定义 GrantedAuthority?

【讨论】:

我正在尝试设置自定义 GrantedAuthority,但我不知道如何在 Okta 中添加更多角色,因此我正在尝试将属性转换为 GrantedAuthority。我平均需要为每个用户添加大约 16 个 GrantedAuthorities。 酷,有帮助!仅供参考,您可以将声明转换为 GrantedAuthority:github.com/okta/okta-spring-boot#configure-your-properties(默认为 groups 声明) 您的问题解决了吗?我也有同样的情况。【参考方案2】:

简单的解决方案是将您的自定义服务定义为名为“oidcUserService”的 bean。

  @Bean(name = "oidcUserService")
  OAuth2UserService<OidcUserRequest, OidcUser> getOidcUserService() 
    return new CustomOidcUserService();
  

有了这个http配置可以简单如下:

http.authorizeRequests().anyRequest().authenticated()
                .and()
                .oauth2Login();

【讨论】:

oidcUserService 没有被调用。我无法使用 access_token 并且 spring 最终尝试解码 id_token。我想让 Spring 获取访问令牌。

以上是关于如何确保让我的自定义 OidcUserService 被默认调用?的主要内容,如果未能解决你的问题,请参考以下文章

如何让我的自定义不和谐机器人发送消息

如何让我的 UIView 使用我的自定义 CALayer 作为其支持层?

表格视图中的自定义单元格未显示?

如何让我的topojson文件与数据图一起使用?

无法让我的自定义播放按钮在我的视频播放器上工作

Java Swing 如何在我的自定义 ColorChooserPanel 中创建颜色样本?