春のセキュリティ5.1 - Webクライアントとクライアントの資格情報のフローのためのトークンを取得します。

ダレン・フォーサイス:

私は、ベアラトークンビアを取得しようとしていますwebclientサーブレットアプリケーションで保護されたリソースサーバの統合テストのための以下の設定で。

spring:
  security:
    oauth2:
      client:
        registration:
          idp:
            clientId: id
            clientSecret: secret
            authorization-grant-type: client_credentials
            scope: read
        provider:
          idp:
            authorization-uri: myidp/authorization.oauth2
            token-uri: myidp/token.oauth2
            user-info-uri: myidp/userinfo.openid
            user-name-attribute: name

そして、豆、

    @Bean
    WebClient webClient(ClientRegistrationRepository clientRegistrations,
            OAuth2AuthorizedClientRepository authorizedClients) {
        ServletOAuth2AuthorizedClientExchangeFilterFunction oauth = new ServletOAuth2AuthorizedClientExchangeFilterFunction(
                clientRegistrations, authorizedClients);
        // (optional) explicitly opt into using the oauth2Login to provide an access token implicitly
        // oauth.setDefaultOAuth2AuthorizedClient(true);
        // (optional) set a default ClientRegistration.registrationId
        // oauth.setDefaultClientRegistrationId("client-registration-id");
        return WebClient.builder().apply(oauth.oauth2Configuration()).build();
    }

そして、テストにWebクライアントをオートワイヤリングなどのようにそれを呼び出します

webClient.get().uri("http://localhost:" + port + "/web/it")
                .attributes(ServletOAuth2AuthorizedClientExchangeFilterFunction.clientRegistrationId("idp")).retrieve()
                .bodyToMono(String.class).block();

これは、交換機能は、いずれかの利用可能な場合はアクセストークンを取得し、またはIDPから新しいものを取得するための呼び出しを行うだろう、私の仮定です。しかし、それはいつものように失敗するHttpSessionOAuth2AuthorizedClientRepositoryHttpServletRequestnullです。

以下のように見える全体的なテストでは、自動設定にこのフィードは、IDPプロバイダのためのいくつかの豆を設定します。

@SpringBootTest(classes = WebITApplication.class,
        webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ExtendWith(SpringExtension.class)
@ActiveProfiles("web-it")
class WebJwtIt {

    @LocalServerPort
    private int port;

    @Autowired
    private WebClient webClient;

    @Test
    void testIdpJwt() {

        String response = webClient.get().uri("http://localhost:" + port + "/web/it")
                .attributes(ServletOAuth2AuthorizedClientExchangeFilterFunction.clientRegistrationId("ping")).retrieve()
                .bodyToMono(String.class).block();
        assertThat(response).isEqualTo("pass");
    }

    @RestController
    @SpringBootApplication
    @ImportAutoConfiguration(IdpAutoConfiguration.class)
    static class WebITApplication implements IdpSecurityAdapter {

              @Bean
    WebClient webClient(ClientRegistrationRepository clientRegistrations,
            OAuth2AuthorizedClientRepository authorizedClients) {
        ServletOAuth2AuthorizedClientExchangeFilterFunction oauth = new ServletOAuth2AuthorizedClientExchangeFilterFunction(
                clientRegistrations, authorizedClients);
        // (optional) explicitly opt into using the oauth2Login to provide an access token implicitly
        // oauth.setDefaultOAuth2AuthorizedClient(true);
        // (optional) set a default ClientRegistration.registrationId
        // oauth.setDefaultClientRegistrationId("client-registration-id");
        return WebClient.builder().apply(oauth.oauth2Configuration()).build();
    }
        public static void main(String args[]) {

            new SpringApplicationBuilder().profiles("web-it").build().run(WebITApplication.class, args);
        }

        @GetMapping
        public String secured() {
            return "secured";
        }

        @GetMapping("/web/it")
        public String securedOne() {
            return "pass";
        }

        @Override
        public void configure(final HttpSecurity httpSecurity) throws IdpSecurityAdapterException {
            try {
                httpSecurity.oauth2Client();
            } catch (Exception e) {
                throw new IdpSecurityAdapterException("Failed to Configure Oauth2Client", e);
            }
        }

        @Override
        public IdpProvider getIdpProvider() {
            return IdpProvider.MyIdp;
        }
    }

私のためのトークンを取得し、リクエストに追加するWebクライアントのためにとにかくありますか?私はこれが可能だった知っているspring-security-oauth:OAuthRestTemplateと私はそれがWebクライアントで可能だと思ったドキュメントを読みます。

フロランコーンズ:

ここでの問題は、あなたが正しい方法あなたのWebクライアントをインスタンス化していないということです。

あなたは上にある通り、クライアント側には、へのアクセスを持っていませんOAuth2AuthorizedClientRepositoryこのBeanは、使用してにログインした上で、リソースサーバにリンクされていることになっている.oauth2Login()のメソッド宣言HttpSecurityの設定を。これらの詳細は、ここで説明されています。春のセキュリティ5のOAuth2ログインを

ここでも、あなたは上にあるクライアント側に何が必要なのJWTトークンを取得する認可サーバに要求をトリガーする交換フィルター機能があるので。あなたは使用することができますServerOAuth2AuthorizedClientExchangeFilterFunction代わりに。

あなたは、より良い使用WebClientCustomizerWebClientのフィルターに交換フィルタ機能を追加します。どうして ?単にあなたのSpringアプリケーションaに注入するので、WebClient.Builderあなたがウェブの交換にリンクされているネイティブのメトリクスにアクセスできるようになります。

したがって、あなたはの新しいインスタンス使用してWebクライアントを構築しますUnAuthenticatedServerOAuth2AuthorizedClientRepository。このようなBeanを:

// Use injection to get an in-memory reposiroty or client registrations
@Bean
WebClient webClient(ClientRegistrationRepository clientRegistrations) {

    // Provides support for an unauthenticated user such as an application
    ServerOAuth2AuthorizedClientExchangeFilterFunction oauth = new ServerOAuth2AuthorizedClientExchangeFilterFunction(
            clientRegistrations, new UnAuthenticatedServerOAuth2AuthorizedClientRepository());

    // Build up a new WebClientCustomizer implementation to inject the oauth filter
    // function into the WebClient.Builder instance
    return new WebClientSecurityCustomizer(oauth);
}

あなたは上にある通り、クライアント側、あなたはどの認可クライアントのリポジトリのBeanインスタンス化を使用することはできません理由です、あなたのプロセスにユーザーを関連付けるされていません。:春のセキュリティのドキュメントで確認してください春のセキュリティのドキュメント:クラスUnAuthenticatedServerOAuth2AuthorizedClientRepository

:私は、次のGitHubのプロジェクトのデモケース総括しようとした春のセキュリティのOAuth2マシン・ツー・マシンのシナリオ- GitHubのを

私は、これはあなたのWebクライアントの設定に関する詳細な洞察を与える願っています。何か質問がある場合はお問い合わせください。

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=202370&siteId=1