作記録

記憶代わり

Spring Security OAuth2 Login と LINEログイン を利用してログイン機能を実装する

version

  • Spring Boot Starter Security 2.7.1

参考

まずは、下記の動画、documentを理解すると分かりやすいと思う。

また、下記のSpring Security OAuth2 LoginとLINEログインのdocumentも理解すると分かりやすいと思う。

1. LINE Developersに開発者アカウントを作成

下記のdocument通りに開発者アカウントを作成する。
https://developers.line.biz/ja/docs/line-developers-console/login-account/

2. LINE Developersの開発者アカウントにProviderを作

Providerとは、

LINEプラットフォームを通じてサービスを提供する個人、企業、またはそのほかの組織を意味する情報です。

下記のdocument通りにProviderを作成する。
https://developers.line.biz/ja/docs/liff/getting-started/#creating-provider-and-channel

3. LINE Developersの開発者アカウントのProviderにChannelを作成する

Channelとは、

LINEプラットフォームが提供する機能を、プロバイダーが開発するサービスで利用するための通信路です。

おそらくChannelは、サービスの機能毎に作ることを想定されてそう。
例えばAサービスのLINEログイン, BサービスのLINEログイン, CサービスのMessaging APIそれぞれが個別のChannelを持つように作ると良さそう。

下記のdocument通りにChannelを作成する。
https://developers.line.biz/ja/docs/liff/getting-started/#creating-provider-and-channel

4. ChannelのCallback URLを設定

4-1. Callback URLとは

LINEログインの文脈でのCallbackとは、リダイレクションエンドポイントを指すと思われる。
リダイレクションエンドポイントは、Spring Security OAuth2 Loginの文脈では、リダイレクトURIと呼ばれる。
要は、LINE側が認証を行った後にブラウザにレスポンスするリダイレクト先のエンドポイントである。
このリダイレクションエンドポイントの実際のURLは、後述の5で定義する。
このリダイレクションエンドポイントは、OAuth2LoginAuthenticationFilterに引っかかる。

4-2. 定義する値

ChannelのLINEログインのタブ内に下記のような形式でCallback URLを定義する。
***は、スキーム + ドメイン である。

***/login/oauth2/code/line

ただし、ローカル環境のリダイレクトエンドポイントの場合、下記のように記述すると有効なURLとみなされない。 http://localhost:8080/login/oauth2/code/login

よって、ローカル環境のリダイレクトエンドポイントの場合、下記のように記述する。

http://127.0.0.1:8080/login/oauth2/code/line

5. Spring Security OAuth2 Loginの設定

ClientRegistrationの設定を行う。
ClientRegistrationのClientとは、本記事で言えば LINEログイン Channel を指す。
設定項目の説明は、下記を参照すると良い。
https://spring.pleiades.io/spring-security/reference/servlet/oauth2/login/core.html#oauth2login-boot-property-mappings
https://spring.pleiades.io/spring-security/reference/servlet/oauth2/client/core.html#oauth2Client-client-registration

具体的には、application.propertiesに下記の設定をする。

key 指定するvalueについて
spring.security.oauth2.client.registration.line.client-id Channel の Basic Settings の ChannelID を指定する。
spring.security.oauth2.client.registration.line.client-secret Channel の Basic Settings の Channel secret を指定する。
spring.security.oauth2.client.registration.line.authorization-grant-type authorization_code を指定する。LINEログインの処理は、認可コード付与のフローに基づくためである。
spring.security.oauth2.client.registration.line.redirect-uri http://127.0.0.1:8080/login/oauth2/code/line を指定する。これによりcode(認可コード)とstateを付与したリクエストをリダイレクションエンドポイントに送る。これによりOAuth2LoginAuthenticationFilterに引っかかる。
spring.security.oauth2.client.registration.line.scope profile を指定する。これによりprofileを取得する権限を得る。他に指定出来るスコープは、こちらを参照する。
spring.security.oauth2.client.provider.line.authorization-uri https://access.line.me/oauth2/v2.1/authorize を指定する。これにより認可エンドポイントのリクエスト先が決まる。LINEログインにおける 認可エンドポイント は、こちらに記載される https://access.line.me/oauth2/v2.1/authorize である。
spring.security.oauth2.client.provider.line.token-uri https://api.line.me/oauth2/v2.1/token を指定する。これによりトークンエンドポイントへのリクエスト先が決まる。LINEログインにおけるトークンエンドポイントが、こちらに記載される https://api.line.me/oauth2/v2.1/token である。
spring.security.oauth2.client.provider.line.user-info-uri https://api.line.me/v2/profile を指定する。これによりUserInfo Endpointへのリクエスト先が決まる。LINEログインにおけるUserInfo Endpointが、こちらに記載される https://api.line.me/v2/profile である。
spring.security.oauth2.client.provider.line.user-name-attribute userId を指定する。上記のUserInfo Endpointから返される識別子の属性の名前を記述する。これは、こちらに記載される userId である。

6. SpringSecurityFilterChain のBeanをDIコンテナに登録

参考

具体的には、下記のようなConfigクラスを実装する。
下記の実装は、最低限の設定である。

@EnableWebSecurity
public class SpringSecurityConfig {
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        return http
            .oauth2Login(customizer -> customizer
                .loginPage("/login")
                .defaultSuccessUrl("/")
            )
            .logout(customizer -> customizer
                .logoutSuccessUrl("/login")
            )
            .authorizeHttpRequests(customizer -> customizer
                .mvcMatchers("/css/**", "/favicon.ico").permitAll()
                .mvcMatchers("/login").permitAll()
                .anyRequest().authenticated()
            )
            .build();
    }
}

7. Lineログインテスト

7-1. 最初のリクエス

ローカル環境で開発をしている場合、Spring Security OAuth2 Loginのデフォルトでは、下記のURLにリクエストを送ることで OAuth2AuthorizationRequestRedirectFilter に引っかかり、必要なパラメータを付与したLINEログインの認可エンドポイント(https://access.line.me/oauth2/v2.1/authorize)にリクエストを送る。

http://127.0.0.1:8080/oauth2/authorization/line


参考

7-2. 7-2の後

LINEログインの認可エンドポイントにリクエストを送ると、上記4-1に記述した通りリダイレクトのレスポンスを返す。
リダイレクトのURLは、上記5で spring.security.oauth2.client.registration.line.redirect-uri に設定したURLである。
このURLにリクエストをすると、OAuth2LoginAuthenticationFilterに引っかかる。

8. LINEログインのユーザーIDを取得

下記のようなログインしているLINEのユーザーIDを取得出来るコンポーネントを作成する。

@Component
public class LineLoginContext {
    OAuth2AuthorizedClientService oAuth2AuthorizedClientService;

    LineLoginContext(OAuth2AuthorizedClientService oAuth2AuthorizedClientService) {
        this.oAuth2AuthorizedClientService = oAuth2AuthorizedClientService;
    }

    public LINEUserId LINEのユーザーID() {
        DefaultOAuth2User ログインユーザー = (DefaultOAuth2User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();

        return LINEUserId.of(ログインユーザー.getName());
    }
}

9. LINEログイン 関連の Resource(リソース)

下記からダウンロード可能。

https://developers.line.biz/ja/docs/line-login/login-button/