

Spring SecurityでOpenID Connect認証してみた
こんにちは、ソリューション開発部の瀧口です。最近ダムが気になります。
先日ダムの観光放流に行ったのですが、そのスケールに圧倒されました。山の中に突然出てくる、まさに「そびえたつ」という言葉そのままの存在感。放流が始まるときの「ドドドドド」という音、雨ガッパがいるくらいの容赦なさで降り注ぐ水しぶき。あらためて、人間ってすごいモノ作るんだなーと実感しました。
ちなみに、その時ジムに置いてきたポケモンが未だに帰ってきません。今シーズンの観光放流ももう終わるのに・・・ 誰か私のカイリューを解放してあげて!!
さて、私のカイリューはジムを守っていますが、Webアプリケーションを守るといえば、そう Spring Security ですね。そんなSpring Securityですが、11月28日に5.0.0がリリースされています。新機能として、OAuth 2.0 / OpenID Connectへの対応が入っていたので、さっそくOpenID Connectでの認証を試してみました。
Googleアカウントでログイン
Spring SecurityのOAuth 2.0 / OpenID Connectクライアント実装である spring-security-oauth2-client では、Google / GitHub / Facebook / Okta の設定が提供されています。この4つ以外でも、自前で設定を用意することで対応可能ですが、ここでは最初から提供されているGoogleを使ってみます。
クライアントの登録
Google DeveloperのOpenID Connectページに沿って、OAuth クライアントIDを作成します。承認済みのリダイレクト URIには http://localhost:8080/login/oauth2/code/google を設定しておきます。クライアントIDとクライアントシークレットは、後で設定するので控えておきましょう。
Spring Bootプロジェクトの作成
実際に認証を行うアプリケーションを作成します。Spring Security 5.0.0にはSpring Bootの2.0.0.M7から対応しています。
pom.xml
spring-boot-starter-security に加え、spring-security-oauth2-clientとspring-security-oauth2-joseを追加することで、AutoConfigureが有効になります。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.M7</version>
</parent>
<groupId>jp.co.arksystems</groupId>
<artifactId>security-oidc</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>9</source>
<target>9</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<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</groupId>
<artifactId>spring-security-oauth2-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-jose</artifactId>
</dependency>
</dependencies>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/libs-milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
</project>
application.yml
Googleにクライアントを作成したときに控えておいたクライアントIDとシークレットを、application.ymlに設定します。CommonOAuth2Provider で事前設定がされているので、最低限の設定で済みます。
spring:
security:
oauth2:
client:
registration:
google:
client-id: {クライアントID}
client-secret: {クライアントシークレット}
メインクラス
Spring Bootのメインクラスを用意します。ここでは、ID TokenやUserInfo Requestで取得できる属性値をJSONで出力するハンドラを追加してみます。
@SpringBootApplication
@RestController
public class OidcLoginApplication {
public static void main(String[] args) {
SpringApplication.run(OidcLoginApplication.class, args);
}
@GetMapping("/")
public Map<?, ?> index(Principal principal) {
if (principal instanceof OAuth2AuthenticationToken) {
final OAuth2AuthenticationToken auth = (OAuth2AuthenticationToken) principal;
return auth.getPrincipal().getAttributes();
}
return Map.of("name", principal.getName());
}
}
動作例
たったこれだけで、Googleを使ったOpenID Connect認証が実現できています。Spring Bootアプリケーションを実行し、ブラウザで http://localhost:8080 にアクセスしてみます。
すると画像のように、認証プロバイダを選択する画面が表示されます。今回はGoogleしか設定していないので1つですが、FacebookやGitHubの設定も行うと、この画面に追加されます。


Googleを選択すると、実際にGoogleアカウントでのログイン画面にリダイレクトされます。


ログインに成功すると、アプリケーション側にリダイレクトされ、以下のようなJSONが取得できます。
{
"at_hash":"XXX",
"sub":"XXX",
"email_verified":true,
"gender":"male",
"profile":"https://plus.google.com/+XXX",
"iss":"https://accounts.google.com",
"given_name":"Toshio",
"locale":"ja",
"picture":"https://lh4.googleusercontent.com/XXX/photo.jpg",
"aud":[
"XXX.apps.googleusercontent.com"
],
"azp":"XXX.apps.googleusercontent.com",
"name":"Toshio Takiguchi",
"exp":"2017-11-29T08:42:43.000+0000",
"family_name":"Takiguchi",
"iat":"2017-11-29T07:42:43.000+0000",
"email":"xxx@gmail.com"
}
無事にOpenID Connectで認証に成功し、アプリケーションにログインすることができました!
まとめ
OAuth2やOpenID Connectは、GoogleやFacebookのようなソーシャルサービスだけでなく、Windows Server 2016のAD FSやAzure ADも対応しており、今後エンタープライズ系でも普及が加速していくと考えられます。Spring Securityを使えば、今回ご紹介したように、簡単にOpenID Connectによる認証に対応できますので、検討してみてはいかがでしょうか。
最後に1つだけ。
いつまでパスワード変更画面の実装で消耗してるの?