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

时间:2018-01-17 17:43:48

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

我们使用JDBC后端令牌存储创建了一个授权服务器。类似的实现托管在GitHub上。 它在我们的环境中使用不同的授权类型完美地工作。不同的Web应用程序将此用于SSO,它会发出令牌,然后用于使用API​​。

我们需要一种方法来记录用户,如果用户从外部IDP返回进行身份验证,则会发出令牌,模拟用户从登录表单手动登录。

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

  • 用户尝试访问客户端应用
  • 重定向到授权服务器
  • 用户可以点击按钮通过ADFS进行身份验证(这可以在以后自动执行),而不是输入凭证。
  • ADFS应该使用用户信息
  • 返回身份验证
  • 在授权服务器中触发该用户的登录,以便发出OAuth2令牌,并重定向回客户端应用程序

我们已经尝试了多种方法来实现它,并在网上引用了多个resources,但尚未成功。请注意,我们需要连接到社交媒体IDP,而我们必须使用企业级的响应,如ADFS,One-login等。

任何初始指针都会非常感激。

1 个答案:

答案 0 :(得分:1)

要使用GitHub进行身份验证并生成可以在下游应用程序中使用的弹簧令牌,我们可以更改我们的代码,如下所示。

在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上发布了相同的查询。