3

現時点では、Spring-Security-Oauth2、Zuul、OpenAM を OAuth2 認証サーバーとして、WCF REST API をリソース サーバーとして統合しようとしています。最終的なセットアップは次のようになります。

安全

spring と AngularJS を使用して SSO 環境をセットアップする方法を説明するチュートリアルを読みました ( sso with spring と angularJS )。ただし、私の場合は、OpenAM とパスワード付与フローを使用してユーザーを認証したいと考えています。したがって、Spring Boot アプリケーションでは、現在の構成は次のようになります。

@SpringBootApplication
@EnableZuulProxy
@EnableOAuth2Client
public class ApolloUIProxyApplication {

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

    @Configuration
    protected static class SecurityConfiguration extends WebSecurityConfigurerAdapter {

        @Override
        public void configure(HttpSecurity http) throws Exception {
            http.logout().and().antMatcher("/**").authorizeRequests()
                    .antMatchers("/index.html", "/home.html", "/", "/login").permitAll()
                    .anyRequest().authenticated().and().csrf()
                    .csrfTokenRepository(csrfTokenRepository()).and()
                    .addFilterAfter(csrfHeaderFilter(), CsrfFilter.class)
                    .addFilterAfter(authenticationProcessingFilter(), CsrfFilter.class);
        }

        @Bean
        public ZuulFilter tokenRelayFilter(){
            JwtTokenRelayFilter filter = new JwtTokenRelayFilter();
            filter.setRestTemplate(restTemplate());
            return new JwtTokenRelayFilter();
        }

        @Bean
        public ZuulFilter customTokenFilter(){
            return new CustomZuulFilter();
        }

        @Bean
        public JwtAccessTokenConverter jwtAccessTokenConverter(){
            return new JwtAccessTokenConverter();
        }

        private Filter csrfHeaderFilter() {
            return new OncePerRequestFilter() {
                @Override
                protected void doFilterInternal(HttpServletRequest request,
                                                HttpServletResponse response, FilterChain filterChain)
                        throws ServletException, IOException {
                    CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class
                            .getName());
                    if (csrf != null) {
                        Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
                        String token = csrf.getToken();
                        if (cookie == null || token != null
                                && !token.equals(cookie.getValue())) {
                            cookie = new Cookie("XSRF-TOKEN", token);
                            cookie.setPath("/");
                            response.addCookie(cookie);
                        }
                    }
                    filterChain.doFilter(request, response);
                }
            };
        }

        private CsrfTokenRepository csrfTokenRepository() {
            HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
            repository.setHeaderName("X-XSRF-TOKEN");
            return repository;
        }


        private OAuth2ClientAuthenticationProcessingFilter authenticationProcessingFilter(){
            OAuth2ClientAuthenticationProcessingFilter processingFilter = new OAuth2ClientAuthenticationProcessingFilter("/login");
            processingFilter.setRestTemplate(restTemplate());
            processingFilter.setTokenServices(resourceServerTokenServices());
            return processingFilter;
        }

        @Bean
        public ResourceServerTokenServices resourceServerTokenServices(){
            OpenAMRemoteTokenService remoteTokenServices = new OpenAMRemoteTokenService();
            remoteTokenServices.setRestTemplate(restTemplate());
            remoteTokenServices.setAccessTokenConverter(accessTokenConverter());
            remoteTokenServices.setClientId("...");
            remoteTokenServices.setClientSecret("...");
            remoteTokenServices.setCheckTokenEndpointUrl("http://...");
            return remoteTokenServices;
        }

        @Bean
        public OAuth2RestTemplate restTemplate(){
            OAuth2RestTemplate template = new OAuth2RestTemplate(resourceDetails(), clientContext());
            return template;
        }

        @Bean
        public AccessTokenProvider accessTokenProvider(){
            ResourceOwnerPasswordAccessTokenProvider provider = new ResourceOwnerPasswordAccessTokenProvider();
            return provider;
        }

        @Bean
        public OAuth2ClientContext clientContext(){
            return new OpenAMClientContext();
        }

        @Bean
        public OAuth2ProtectedResourceDetails resourceDetails(){
            ResourceOwnerPasswordResourceDetails details = new ResourceOwnerPasswordResourceDetails();
            details.setGrantType("password");
            details.setAccessTokenUri("http://...");
            details.setScope(Arrays.asList("openid");
            details.setClientId("...");
            details.setClientSecret("...");
            return details;
        }

        @Bean
        public AccessTokenConverter accessTokenConverter(){
            DefaultAccessTokenConverter tokenConverter = new DefaultAccessTokenConverter();
            tokenConverter.setUserTokenConverter(userAuthenticationConverter());
            return tokenConverter;
        }

        @Bean
        public UserAuthenticationConverter userAuthenticationConverter(){
            return new OpenAMUserAuthenticationConverter();
        }

    }
}

カスタムの RemoteTokenService を作成しました。そうしないと、Spring が OpenAM の tokeninfo エンドポイントにアクセスできず、Post ではなく GET リクエストが必要になるためです。この接続は現在正常に機能しているため、OpenAM から有効なアクセス トークンを取得し、tokeninfo.endpoint でトークン/ユーザー情報を照会することもできます。Authentication オブジェクトが作成され、Spring のセキュリティ コンテキストに格納されます。ZuulFilter の認証オブジェクトにもアクセスできます。

私の問題は、「OAuth2ClientContext」を微調整して、servletRequest からユーザーの資格情報を取得し、それを「AccessTokenRequest」に配置する必要があることです。それ以外の場合は、ResourceDetails でそれらをハードコードする必要がありますが、これは私の場合には適切ではありません。

その結果、ClientContext (およびおそらく AccessTokenRequest も) がシステムのすべてのユーザー間で共有されます。私が欲しいのは、セッションスコープのクライアントコンテキストです。これにより、複数のユーザーをログインさせ、すべてのリクエストで各ユーザーの適切な SecurityContext にアクセスできます。

だから私の質問は、

1) ClientContext および AccessTokenRequest セッションをスコープ化するにはどうすればよいですか?

2) Spring Session モジュールを使用する必要がありますか?

3) sessionStrategy を設定する必要がありますか?

ありがとうございました!

4

0 に答える 0