将 Spring 授权服务器连接到外部 IDP 并触发身份验证

Connect Spring Authorization server to external IDP and trigger authentication

我们创建了一个带有 JDBC 后端令牌存储的授权服务器。 GitHub 上托管了一个类似的实现。 使用不同的授权类型,它在我们的环境中工作得非常好。不同的 Web 应用程序将它用于 SSO,它会颁发令牌,然后这些令牌也用于使用 API。

我们需要一种方法让用户登录,并在用户 return 被外部 IDP 验证后发出令牌,模拟用户从登录表单手动登录。

我们必须使用外部 IDP 身份验证扩展此服务器。因此,如果用户连接到他们的域网络,并且具有 ADFS(作为示例),则预期流程如下:

我们尝试了多种实现方式,网上也参考了多个,目前还没有成功。请注意,我们不需要连接到社交媒体 IDP,而是我们必须使用来自企业级的响应,如 ADFS、One-login 等。

任何初始指示将不胜感激。

要使用 GitHub 进行身份验证并生成可用于下游应用程序的 spring 令牌,我们可以像下面这样更改我们的代码。

在 WebSecurityConfigurerAdapter 中添加以下代码以配置 (HttpSecurity http)

http.exceptionHandling()
                  .authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/")).and()
                .addFilterBefore(ssoFilter(), BasicAuthenticationFilter.class).addFilter(customBasicAuthFilter);

然后在 WebSecurityConfigurerAdapter 中再次

@Bean
        public FilterRegistrationBean oauth2ClientFilterRegistration(OAuth2ClientContextFilter filter) {
            FilterRegistrationBean registration = new FilterRegistrationBean();
            registration.setFilter(filter);
            registration.setOrder(-100);
            return registration;
        }

        @Bean
        @ConfigurationProperties("github")
        public ClientResources github() {
            return new ClientResources();
        }


    private Filter ssoFilter() {
        CompositeFilter filter = new CompositeFilter();
        List<Filter> filters = new ArrayList<>();
        filters.add(ssoFilter(github(), "/login/github"));
        filter.setFilters(filters);
        return filter;
    }

    private Filter ssoFilter(ClientResources client, String path) {
        OAuth2ClientAuthenticationProcessingFilter oAuth2ClientAuthenticationFilter = new OAuth2ClientAuthenticationProcessingFilter(
                path);
        OAuth2RestTemplate oAuth2RestTemplate = new OAuth2RestTemplate(client.getClient(), oauth2ClientContext);
        oAuth2ClientAuthenticationFilter.setRestTemplate(oAuth2RestTemplate);
        UserInfoTokenServices tokenServices = new UserInfoTokenServices(client.getResource().getUserInfoUri(),
                client.getClient().getClientId());
        tokenServices.setRestTemplate(oAuth2RestTemplate);
        oAuth2ClientAuthenticationFilter.setTokenServices(tokenServices);
        return oAuth2ClientAuthenticationFilter;
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.parentAuthenticationManager(authenticationManager);
        PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        auth.jdbcAuthentication().dataSource(dataSource).passwordEncoder(passwordEncoder);
    }

添加一个class ClientResources

class ClientResources {

    @NestedConfigurationProperty
    private AuthorizationCodeResourceDetails client = new AuthorizationCodeResourceDetails();

    @NestedConfigurationProperty
    private ResourceServerProperties resource = new ResourceServerProperties();

    public AuthorizationCodeResourceDetails getClient() {
        return client;
    }

    public ResourceServerProperties getResource() {
        return resource;
    }
}

除此之外,我们还需要在应用程序中添加 GitHub 设置。

github.client.clientId = <<Clientid>>
github.client.clientSecret = <<clientSecret>>
github.client.accessTokenUri = https://github.com/login/oauth/access_token
github.client.userAuthorizationUri = https://github.com/login/oauth/authorize
github.client.clientAuthenticationScheme = form
github.resource.userInfoUri = https://api.github.com/user
logging.level.org.springframework.security = DEBUG

对于其他支持 OAuth 的用户,您可以采用类似的方式。我也在探索如何使用 ADFS 身份验证。在 Whosebug 上发布的查询也是如此。