Spring Securityを用いたLine Login実装 メモ

* Java フレームワークSpring Securityを用いたLine Loginを実装方法をメモする。

## Line Login  設定

### チャネル作成

* [LINE Developersコンソール](https://developers.line.biz/console/)でLINEログイン用チャネルを作成する。
  * Webアプリ用として作成する。
  * Callback URL (redirect_uri)に以下を設定する。
        * `http://localhost:8080/login/oauth2/code/line`



## Spring プロジェクト作成

### ベースプロジェクト作成

* [こちら](https://qiita.com/t-shin0hara/items/687085ec34ae78ca2260)を参考にベースプロジェクトを作成する。

  * プロジェクト名は`LineLoginTest`のような適当な名前を指定する。

  * 依存関係

    * Spring Security

      ※参考サイトにあるlombokなどは今回使用しない。

* pom.xmlに以下の依存関係を追加する。

  ```xml
  <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-oauth2-client</artifactId>
  </dependency>
  ```

### 接続設定

* `src/main/resources/application.properties`に以下のようにLINE接続設定を追加する。
  * `client-id`:チャネルIDを指定(コンソールから確認)
  * `client-secret`:チャンネルシークレットを指定(コンソールから確認)

```properties
spring.security.oauth2.client.provider.line.authorization-uri=https://access.line.me/oauth2/v2.1/authorize
spring.security.oauth2.client.provider.line.token-uri=https://api.line.me/oauth2/v2.1/token
spring.security.oauth2.client.provider.line.user-info-uri=https://api.line.me/v2/profile
spring.security.oauth2.client.provider.line.user-info-authentication-method=query
spring.security.oauth2.client.provider.line.user-name-attribute=userId
spring.security.oauth2.client.provider.line.jwk-set-uri=https://api.line.me/oauth2/v2.1/certs
spring.security.oauth2.client.registration.line.provider=line
spring.security.oauth2.client.registration.line.client-id=<YOUR CHANNEL ID>
spring.security.oauth2.client.registration.line.client-secret=<YOUR CLIENT SECRET>
spring.security.oauth2.client.registration.line.client-authentication-method=post
spring.security.oauth2.client.registration.line.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.line.redirect-uri={baseUrl}/login/oauth2/code/{registrationId}
spring.security.oauth2.client.registration.line.scope=profile
spring.security.oauth2.client.registration.line.client-name=LINE
```

### コントローラー(LoginController.java)

```java
package com.example.test.controller;

import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
import org.springframework.security.oauth2.client.annotation.RegisteredOAuth2AuthorizedClient;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class LoginController {
	@GetMapping("/")
	public String index(Model model, @AuthenticationPrincipal final OAuth2User user,
			@RegisteredOAuth2AuthorizedClient OAuth2AuthorizedClient authorizedClient) {
		model.addAttribute("userName", user.getName());
		model.addAttribute("clientName", authorizedClient.getClientRegistration().getClientName());
		model.addAttribute("userAttributes", user.getAttributes());
		return "index";
	}
}
```



### ビュー(index.html)

* ログインユーザーID、表示名称、クライアント名を表示させる。

```html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:th="http://www.thymeleaf.org"
	xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
<head>
<title>Line Login with Spring Security</title>
<meta charset="utf-8" />
</head>
<body>
	<div style="float: right" th:fragment="logout"
		sec:authorize="isAuthenticated()">
		<div style="float: left">
			<span style="font-weight: bold">User: </span><span
				sec:authentication="name"></span>
		</div>
		<div style="float: none">&nbsp;</div>
		<div style="float: right">
			<form action="#" th:action="@{/logout}" method="post">
				<input type="submit" value="Logout" />
			</form>
		</div>
	</div>
	<h1>Line Login with Spring Security</h1>
	<div>
		You are successfully logged in <span style="font-weight: bold"
			th:text="${userName}"></span> via the OAuth 2.0 Client <span
			style="font-weight: bold" th:text="${clientName}"></span>
	</div>
	<div>&nbsp;</div>
	<div>
		<span style="font-weight: bold">User Attributes:</span>
		<ul>
			<li th:each="attribute : ${userAttributes}"><span
				style="font-weight: bold" th:text="${attribute.key}"></span>: <span
				th:text="${attribute.value}"></span></li>
		</ul>
	</div>
</body>
</html>
```



### 動作確認

**1.** メインクラスを右クリック -> [実行] -> [Spring Boot アプリケーション] を選択し、起動する。※プロジェクト作成時にデフォルトで作成されるメインクラスに変更は加えていない。
**2.** http://localhost:8080 にアクセスする。

**3.** (認証未実施の場合は、http://localhost:8080/login にリダイレクトされる。)

**4.** LINEリンクをクリックし、LINEの認可エンドポイントへリダイレクトされる。

**5.** LINE認証を行い、http://localhost:8080 へリダイレクトされる。

   * ユーザー、クライアント情報が表示される。

## 参考情報

* [Spring Security/OAuth 2.0 Login Sample](https://github.com/spring-projects/spring-security/tree/master/samples/boot/oauth2login)
* [Spring Security + 設定ファイルで始める LINE との ID Federation](https://engineering.linecorp.com/ja/blog/detail/159/)
* [ウェブアプリにLINEログインを組み込む（LINEログイン v2.0）](https://developers.line.biz/ja/docs/line-login/integrate-line-login-v2/)
* [SpringbootでLINEのOAuth2ログインを試した](https://koirand.github.io/blog/2018/line-login-with-springboot/)