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

标签 spring spring-boot spring-security adfs spring-oauth2

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

我们需要一种方法让用户登录,并在用户从外部 IDP 返回时通过身份验证后发出 token ,这有点模拟用户从登录表单手动登录。

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

  • 用户尝试访问客户端应用
  • 重定向到授权服务器
  • 无需输入凭据,用户可以单击按钮通过 ADFS 进行身份验证(稍后也可以自动执行)
  • ADFS 应返回身份验证正常,并带有用户信息
  • 触发该用户在授权服务器中的登录,以便发出 OAuth2 token ,并将其重定向回客户端应用

我们尝试了多种方式来实现,并引用了多个resources在线,但还没有成功。请注意,我们不需要连接到社交媒体 IDP,而是我们必须使用来自企业级的响应,如 ADFS、一次登录等。

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

最佳答案

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

在 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);
    }

添加一类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 身份验证。查询发布于 Stackoverflow同样。

关于spring - 将 Spring 授权服务器连接到外部 IDP 并触发身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48307024/

相关文章:

java - Spring -oauth2 : HTTP Status 403 - Access Denied

grails - Spring Security核心插件从1.3.x升级到2.0.4时出错

java - 需要 Spring Web 服务客户端教程或示例

java - Autowiring 在 Spring 4 中不起作用

java - SpringJunit4ClassRunner 的类路径在哪里,如何直接指向我操作系统中的文件?

java - 获取 JPAQuery 结果作为页面

java - Spring Data REST - 如何在投影中包含计算数据?

java - 运行 JUnit 测试后所做的数据库更改不可见

spring-boot - 更正应用程序的类路径,使其包含 org.elasticsearch.common.logging.Loggers 的单个兼容版本

java - Spring Security OAuth2 撤销 token 不起作用