1. 概要

このチュートリアルでは、SpringOAuth2RestTemplateを使用してOAuth2REST呼び出しを行う方法を学習します。

GitHubアカウントのリポジトリを一覧表示できるSpringWebアプリケーションを作成します。

2. Maven構成

まず、spring-boot-starter-securityspring-security-oauth2-autoconfigureの依存関係をpom.xmlに追加する必要があります。 Webアプリケーションを構築しているので、spring-boot-starter-webおよびspring-boot-starter-thymeleafアーティファクトも含める必要があります。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.security.oauth.boot</groupId>
    <artifactId>spring-security-oauth2-autoconfigure</artifactId>
    <version>2.5.2</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

3. OAuth2のプロパティ

次に、OAuth構成を application.properties ファイルに追加して、GitHubアカウントに接続できるようにします。

github.client.clientId=[CLIENT_ID]
github.client.clientSecret=[CLIENT_SECRET]
github.client.userAuthorizationUri=https://github.com/login/oauth/authorize
github.client.accessTokenUri=https://github.com/login/oauth/access_token
github.client.clientAuthenticationScheme=form

github.resource.userInfoUri=https://api.github.com/user
github.resource.repoUri=https://api.github.com/user/repos

[ CLIENT_ID][CLIENT_SECRET]をGitHubOAuthアプリの値に置き換える必要があることに注意してください。 OAuthアプリの作成ガイドに従って、GitHubに新しいアプリを登録できます。

AuthorizationコールバックURLがhttp:// localhost:8080、に設定されていることを確認しましょう。これにより、OAuthフローがWebアプリケーションのホームページにリダイレクトされます。

4. OAuth2RestTemplate構成

次に、アプリケーションにOAuth2サポートを提供するためのセキュリティ構成を作成します。

4.1. SecurityConfigクラス

まず、 WebSecurityConfigurerAdapter を拡張して、Springの構成ヘルパーを利用しましょう。

@Configuration
@EnableOAuth2Client
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    OAuth2ClientContext oauth2ClientContext;

    public SecurityConfig(OAuth2ClientContext oauth2ClientContext) {
        this.oauth2ClientContext = oauth2ClientContext;
    }

    ...
}

@ EnableOAuth2Client を使用すると、OAuth2RestTemplateの作成に使用するOAuth2コンテキストにアクセスできます。

4.2. OAuth2RestTemplate Bean

次に、OAuth2RestTemplateのbeanを作成します。

@Bean
public OAuth2RestTemplate restTemplate() {
    return new OAuth2RestTemplate(githubClient(), oauth2ClientContext);
}

@Bean
@ConfigurationProperties("github.client")
public AuthorizationCodeResourceDetails githubClient() {
    return new AuthorizationCodeResourceDetails();
}

これにより、OAuth2のプロパティとコンテキストを使用してテンプレートのインスタンスを作成します。

@ConfigurationProperties アノテーションは、すべてのgithub.clientプロパティをAuthorizationCodeResourceDetailsインスタンスに挿入します。

4.3. 認証フィルター

3番目に、OAuth2フローを処理するための認証フィルターが必要です。

private Filter oauth2ClientFilter() {
    OAuth2ClientAuthenticationProcessingFilter oauth2ClientFilter = new OAuth2ClientAuthenticationProcessingFilter("/login/github");
    OAuth2RestTemplate restTemplate = restTemplate();
    oauth2ClientFilter.setRestTemplate(restTemplate);
    UserInfoTokenServices tokenServices = new UserInfoTokenServices(githubResource().getUserInfoUri(), githubClient().getClientId());
    tokenServices.setRestTemplate(restTemplate);
    oauth2ClientFilter.setTokenServices(tokenServices);
    return oauth2ClientFilter;
}

@Bean
@ConfigurationProperties("github.resource")
public ResourceServerProperties githubResource() {
    return new ResourceServerProperties();
}

ここでは、アプリケーションの / login / githubURLでOAuth2フローを開始するようにフィルターに指示しています。

4.4. Springセキュリティ構成

最後に、 OAuth2ClientContextFilter を登録して、Webセキュリティ構成を作成しましょう。

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests().antMatchers("/", "/login**", "/error**")
      .permitAll().anyRequest().authenticated()
      .and().logout().logoutUrl("/logout").logoutSuccessUrl("/")
      .and().addFilterBefore(oauth2ClientFilter(), BasicAuthenticationFilter.class);
}

@Bean
public FilterRegistrationBean<OAuth2ClientContextFilter> oauth2ClientFilterRegistration(OAuth2ClientContextFilter filter) {
    FilterRegistrationBean<OAuth2ClientContextFilter> registration = new FilterRegistrationBean<>();
    registration.setFilter(filter);
    registration.setOrder(Ordered.HIGHEST_PRECEDENCE + 1);
    return registration;
}

Webアプリケーションパスを保護し、OAuth2ClientAuthenticationProcessingFilterBasicAuthenticationFilterよりも前に登録されていることを確認します。

5. OAuth2RestTemplateを使用する

OAuth2RestTemplateの主な目標は、OAuth2ベースのAPI呼び出しを行うために必要なコードを減らすことです。 これは基本的に、アプリケーションの2つのニーズを満たします。

  • OAuth2認証フローを処理します
  • API呼び出しを行うためにSpringRestTemplateを拡張します

これで、OAuth2RestTemplateをWebコントローラーの自動配線beanとして使用できるようになりました。

5.1. ログイン

ログインとホームオプションを使用してindex.htmlファイルを作成しましょう。

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
    <title>OAuth2Client</title>
</head>
<body>
<h3>
    <a href="/login/github" th:href="@{/home}" th:if="${#httpServletRequest?.remoteUser != undefined }">
        Go to Home
    </a>
    <a href="/hello" th:href="@{/login/github}" th:if="${#httpServletRequest?.remoteUser == undefined }">
        GitHub Login
    </a>
</h3>
</body>
</html>

認証されていないユーザーにはログインオプションが表示され、認証されたユーザーはホームページにアクセスできます。

5.2. 家

次に、認証されたGitHubユーザーに挨拶するコントローラーを作成しましょう。

@Controller
public class AppController {

    OAuth2RestTemplate restTemplate;

    public AppController(OAuth2RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    @GetMapping("/home")
    public String welcome(Model model, Principal principal) {
        model.addAttribute("name", principal.getName());
        return "home";
    }
}

welcomeメソッドにセキュリティPrincipalパラメーターがあることに注意してください。 Principalの名前をUIモデルの属性として使用しています。

home.htmlテンプレートを見てみましょう。

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Home</title>
</head>
<body>
    <p>
        Welcome <b th:inline="text"> [[${name}]] </b>
    </p>
    <h3>
        <a href="/repos">View Repositories</a><br/><br/>
    </h3>

    <form th:action="@{/logout}" method="POST">
        <input type="submit" value="Logout"/>
    </form>
</body>
</html>

さらに、ユーザーのリポジトリリストとログアウトオプションを表示するためのリンクを追加しています。

5.3. GitHubリポジトリ

次に、前のコントローラーで作成した OAuth2RestTemplate を使用して、ユーザーが所有するすべてのGitHubリポジトリーを表示します。

まず、リポジトリを表すGithubRepoクラスを作成する必要があります。

public class GithubRepo {
    Long id;
    String name;

    // getters and setters

}

次に、以前のAppControllerにリポジトリマッピングを追加しましょう。

@GetMapping("/repos")
public String repos(Model model) {
    Collection<GithubRepo> repos = restTemplate.getForObject("https://api.github.com/user/repos", Collection.class);
    model.addAttribute("repos", repos);
    return "repositories";
}

OAuth2RestTemplateは、GitHubにリクエストを送信するためのすべてのボイラープレートコードを処理します。 また、REST応答をGithubRepoコレクションに変換します。

最後に、 repository.html テンプレートを作成して、リポジトリコレクションを反復処理しましょう。

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Repositories</title>
</head>
<body>
    <p>
        <h2>Repos</h2>
    </p>
    <ul th:each="repo: ${repos}">
        <li th:text="${repo.name}"></li>
    </ul>
</body>
</html>

6. 結論

この記事では、 OAuth2RestTemplateを使用して、GitHubなどのOAuth2リソースサーバーへのREST呼び出しを簡素化する方法を学びました。

OAuth2フローを実行するWebアプリケーションの構成要素を確認しました。 次に、REST API呼び出しを行って、GitHubユーザーのすべてのリポジトリを取得する方法を確認しました。

いつものように、このチュートリアルの完全な例は、GitHubにあります。