メインコンテンツまでスキップ
新しい友達のために:

Logto は、モダンなアプリや SaaS 製品向けに設計された Auth0 の代替です。 Cloudオープンソース の両方のサービスを提供し、アイデンティティと管理 (IAM) システムを迅速に立ち上げるのに役立ちます。認証 (Authentication)、認可 (Authorization)、マルチテナント管理を すべて一つに まとめて楽しんでください。

Logto Cloud で無料の開発テナントから始めることをお勧めします。これにより、すべての機能を簡単に探索できます。

この記事では、Java Spring BootLogto を使用して、WeChat (Native) サインイン体験(ユーザー認証 (Authentication))を迅速に構築する手順を説明します。

前提条件

  • 稼働中の Logto インスタンス。紹介ページ をチェックして始めてください。
  • Java Spring Boot の基本的な知識。
  • 使用可能な WeChat (Native) アカウント。

Logto でアプリケーションを作成する

Logto は OpenID Connect (OIDC) 認証 (Authentication) と OAuth 2.0 認可 (Authorization) に基づいています。これは、複数のアプリケーション間でのフェデレーテッドアイデンティティ管理をサポートし、一般的にシングルサインオン (SSO) と呼ばれます。

あなたの 従来型 Web アプリケーションを作成するには、次の手順に従ってください:

  1. Logto コンソール を開きます。「Get started」セクションで、「View all」リンクをクリックしてアプリケーションフレームワークのリストを開きます。あるいは、Logto Console > Applications に移動し、「Create application」ボタンをクリックします。 Get started
  2. 開いたモーダルで、左側のクイックフィルターチェックボックスを使用して、利用可能なすべての "従来型 Web" フレームワークをフィルタリングするか、"従来型 Web" セクションをクリックします。"Java Spring Boot" フレームワークカードをクリックして、アプリケーションの作成を開始します。 Frameworks
  3. アプリケーション名を入力します。例:「Bookstore」と入力し、「Create application」をクリックします。

🎉 タダーン!Logto で最初のアプリケーションを作成しました。詳細な統合ガイドを含むお祝いページが表示されます。ガイドに従って、アプリケーションでの体験を確認してください。

Java Spring Boot SDK を統合する

ヒント:
  • このガイドのサンプルコードは、 spring-boot-sample GitHub リポジトリ で確認できます。
  • Logto を Java Spring Boot アプリケーションに統合するために公式 SDK は必要ありません。Logto との OIDC 認証 (Authentication) フローを処理するために、 Spring Security および Spring Security OAuth2 ライブラリ を使用します。

Java Spring Boot アプリケーションの設定

依存関係の追加

gradle ユーザーの場合、次の依存関係を build.gradle ファイルに追加してください:

build.gradle
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
}

maven ユーザーの場合、次の依存関係を pom.xml ファイルに追加してください:

pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<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.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>

OAuth2 クライアント設定

Logto コンソールで新しい Java Spring Boot アプリケーションを登録し、Web アプリケーション用のクライアント認証情報と IdP 設定を取得してください。

次の設定を application.properties ファイルに追加してください:

application.properties
spring.security.oauth2.client.registration.logto.client-name=logto
spring.security.oauth2.client.registration.logto.client-id={{YOUR_CLIENT_ID}}
spring.security.oauth2.client.registration.logto.client-secret={{YOUR_CLIENT_ID}}
spring.security.oauth2.client.registration.logto.redirect-uri={baseUrl}/login/oauth2/code/{registrationId}
spring.security.oauth2.client.registration.logto.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.logto.scope=openid,profile,offline_access
spring.security.oauth2.client.registration.logto.provider=logto

spring.security.oauth2.client.provider.logto.issuer-uri={{LOGTO_ENDPOINT}}/oidc
spring.security.oauth2.client.provider.logto.authorization-uri={{LOGTO_ENDPOINT}}/oidc/auth
spring.security.oauth2.client.provider.logto.jwk-set-uri={{LOGTO_ENDPOINT}}/oidc/jwks

実装

詳細に入る前に、エンドユーザーの体験について簡単に説明します。サインインプロセスは次のように簡略化できます:

  1. あなたのアプリがサインインメソッドを呼び出します。
  2. ユーザーは Logto のサインインページにリダイレクトされます。ネイティブアプリの場合、システムブラウザが開かれます。
  3. ユーザーがサインインし、あなたのアプリにリダイレクトされます(リダイレクト URI として設定されています)。

リダイレクトベースのサインインについて

  1. この認証 (Authentication) プロセスは OpenID Connect (OIDC) プロトコルに従い、Logto はユーザーのサインインを保護するために厳格なセキュリティ対策を講じています。
  2. 複数のアプリがある場合、同じアイデンティティプロバイダー (Logto) を使用できます。ユーザーがあるアプリにサインインすると、Logto は別のアプリにアクセスした際に自動的にサインインプロセスを完了します。

リダイレクトベースのサインインの理論と利点について詳しく知るには、Logto サインイン体験の説明を参照してください。


サインイン後にユーザーをアプリケーションへリダイレクトするためには、前のステップで client.registration.logto.redirect-uri プロパティを使ってリダイレクト URI を設定する必要があります。

リダイレクト URI を設定する

Logto Console のアプリケーション詳細ページに移動します。リダイレクト URI http://localhost:3000/callback を追加します。

Logto Console のリダイレクト URI

サインインと同様に、ユーザーは共有セッションからサインアウトするために Logto にリダイレクトされるべきです。完了したら、ユーザーをあなたのウェブサイトに戻すと良いでしょう。例えば、http://localhost:3000/ をサインアウト後のリダイレクト URI セクションとして追加します。

その後、「保存」をクリックして変更を保存します。

WebSecurityConfig の実装

プロジェクトに新しいクラス WebSecurityConfig を作成する

WebSecurityConfig クラスは、アプリケーションのセキュリティ設定を構成するために使用します。このクラスは認証 (Authentication) と認可 (Authorization) フローを処理する主要なクラスです。詳細は Spring Security ドキュメント をご確認ください。

WebSecurityConfig.java
package com.example.securingweb;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;

@Configuration
@EnableWebSecurity

public class WebSecurityConfig {
// ...
}

idTokenDecoderFactory ビーンを作成する

Logto はデフォルトで ES384 アルゴリズムを使用するため、デフォルトの OidcIdTokenDecoderFactory を上書きして同じアルゴリズムを使う必要があります。

WebSecurityConfig.java
import org.springframework.context.annotation.Bean;
import org.springframework.security.oauth2.client.oidc.authentication.OidcIdTokenDecoderFactory;
import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.jose.jws.SignatureAlgorithm;
import org.springframework.security.oauth2.jwt.JwtDecoderFactory;

public class WebSecurityConfig {
// ...

@Bean
public JwtDecoderFactory<ClientRegistration> idTokenDecoderFactory() {
OidcIdTokenDecoderFactory idTokenDecoderFactory = new OidcIdTokenDecoderFactory();
idTokenDecoderFactory.setJwsAlgorithmResolver(clientRegistration -> SignatureAlgorithm.ES384);
return idTokenDecoderFactory;
}
}

ログイン成功イベントを処理する LoginSuccessHandler クラスを作成する

ログイン成功後、ユーザーを /user ページへリダイレクトします。

CustomSuccessHandler.java
package com.example.securingweb;

import java.io.IOException;

import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

public class CustomSuccessHandler implements AuthenticationSuccessHandler {
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
response.sendRedirect("/user");
}
}

ログアウト成功イベントを処理する LogoutSuccessHandler クラスを作成する

セッションをクリアし、ユーザーをホームページへリダイレクトします。

CustomLogoutHandler.java
package com.example.securingweb;

import java.io.IOException;

import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;

public class CustomLogoutHandler implements LogoutSuccessHandler {
@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
throws IOException, ServletException {
HttpSession session = request.getSession();

if (session != null) {
session.invalidate();
}

response.sendRedirect("/home");
}
}

WebSecurityConfig クラスに securityFilterChain を追加する

securityFilterChain は、リクエストとレスポンスを処理するフィルタのチェーンです。

securityFilterChain を設定し、ホームページへのアクセスを許可し、それ以外のリクエストには認証 (Authentication) を要求します。ログイン・ログアウトイベントの処理には CustomSuccessHandlerCustomLogoutHandler を使用します。

WebSecurityConfig.java
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.DefaultSecurityFilterChain;

public class WebSecurityConfig {
// ...

@Bean
public DefaultSecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeRequests(authorizeRequests ->
authorizeRequests
.antMatchers("/", "/home").permitAll() // ホームページへのアクセスを許可
.anyRequest().authenticated() // その他のリクエストは認証 (Authentication) が必要
)
.oauth2Login(oauth2Login ->
oauth2Login
.successHandler(new CustomSuccessHandler())
)
.logout(logout ->
logout
.logoutSuccessHandler(new CustomLogoutHandler())
);
return http.build();
}
}

ホームページを作成する

(すでにプロジェクトにホームページがある場合はこのステップをスキップできます)

HomeController.java
package com.example.securingweb;

import java.security.Principal;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HomeController {
@GetMapping({ "/", "/home" })
public String home(Principal principal) {
return principal != null ? "redirect:/user" : "home";
}
}

このコントローラーは、ユーザーが認証 (Authentication) されていればユーザーページへリダイレクトし、そうでなければホームページを表示します。ホームページにサインインリンクを追加します。

resources/templates/home.html
<body>
<h1>Welcome!</h1>

<p><a th:href="@{/oauth2/authorization/logto}">Login with Logto</a></p>
</body>

ユーザーページを作成する

ユーザーページを処理する新しいコントローラーを作成します:

UserController.java
package com.example.securingweb;

import java.security.Principal;
import java.util.Map;

import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
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;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/user")
public class UserController {

@GetMapping
public String user(Model model, Principal principal) {
if (principal instanceof OAuth2AuthenticationToken) {
OAuth2AuthenticationToken token = (OAuth2AuthenticationToken) principal;
OAuth2User oauth2User = token.getPrincipal();
Map<String, Object> attributes = oauth2User.getAttributes();

model.addAttribute("username", attributes.get("username"));
model.addAttribute("email", attributes.get("email"));
model.addAttribute("sub", attributes.get("sub"));
}

return "user";
}
}

ユーザーが認証 (Authentication) されると、認証済みプリンシパルオブジェクトから OAuth2User データを取得します。詳細は OAuth2AuthenticationToken および OAuth2User をご参照ください。

ユーザーデータを読み取り、user.html テンプレートに渡します。

resources/templates/user.html
<body>
<h1>User Details</h1>
<div>
<p>
<div><strong>name:</strong> <span th:text="${username}"></span></div>
<div><strong>email:</strong> <span th:text="${email}"></span></div>
<div><strong>id:</strong> <span th:text="${sub}"></span></div>
</p>
</div>

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

追加のクレーム (Claims) をリクエストする

principal (OAuth2AuthenticationToken) から返されるオブジェクトに一部のユーザー情報が欠けていることがあります。これは、OAuth 2.0 と OpenID Connect (OIDC) が最小特権の原則 (PoLP) に従うように設計されており、Logto はこれらの標準に基づいて構築されているためです。

デフォルトでは、限られたクレーム (Claims) が返されます。より多くの情報が必要な場合は、追加のスコープ (Scopes) をリクエストして、より多くのクレーム (Claims) にアクセスできます。

備考:

「クレーム (Claim)」はサブジェクトについての主張であり、「スコープ (Scope)」はクレーム (Claims) のグループです。現在のケースでは、クレーム (Claim) はユーザーに関する情報の一部です。

スコープ (Scope) とクレーム (Claim) の関係の非規範的な例を示します:

ヒント:

「sub」クレーム (Claim) は「サブジェクト (Subject)」を意味し、ユーザーの一意の識別子(つまり、ユーザー ID)です。

Logto SDK は常に 3 つのスコープ (Scopes) をリクエストします:openidprofile、および offline_access

追加のユーザー情報を取得するには、application.properties ファイルに追加のスコープを設定できます。たとえば、emailphoneurn:logto:scope:organizations スコープをリクエストするには、application.properties ファイルに次の行を追加します:

application.properties
  spring.security.oauth2.client.registration.logto.scope=openid,profile,offline_access,email,phone,urn:logto:scope:organizations

その後、OAuth2User オブジェクトで追加のクレーム (Claims) にアクセスできます。

アプリケーションを実行してテストする

アプリケーションを実行し、 http://localhost:8080 にアクセスします。

  • サインインリンク付きのホームページが表示されます。
  • リンクをクリックして Logto でサインインします。
  • 認証 (Authentication) に成功すると、ユーザーページにリダイレクトされ、ユーザー情報が表示されます。
  • ログアウトボタンをクリックするとサインアウトし、ホームページにリダイレクトされます。

WeChat (Native) コネクターを追加する

迅速なサインインを有効にし、ユーザーコンバージョンを向上させるために、アイデンティティプロバイダー (IdP) として Java Spring Boot を接続します。Logto ソーシャルコネクターは、いくつかのパラメーター入力を許可することで、この接続を数分で確立するのに役立ちます。

ソーシャルコネクターを追加するには、次の手順に従ってください:

  1. Console > Connectors > Social Connectors に移動します。
  2. 「Add social connector」をクリックし、「WeChat (Native)」を選択します。
  3. README ガイドに従い、必要なフィールドを完了し、設定をカスタマイズします。
Connector tab
注記:

インプレースコネクターガイドに従っている場合は、次のセクションをスキップできます。

WeChat モバイルアプリ を設定する

WeChat オープンプラットフォームでモバイルアプリを作成する

ヒント:

すでに完了しているセクションはスキップできます。

アカウントを作成する

https://open.weixin.qq.com/ を開き、右上の「Sign Up」ボタンをクリックして、サインアッププロセスを完了します。

モバイルアプリを作成する

作成したアカウントでサインインします。「Mobile Application」(移动应用)タブで、大きな緑色の「Create a mobile app」(创建移动应用)ボタンをクリックします。

アプリタブ

申請フォームに必要な情報を入力しましょう。

モバイルアプリ作成

基本情報

ほとんどは直感的に入力できますが、いくつかのヒントを紹介します:

  • WeChat サインインをテストしたいだけで、アプリが App Store にない場合は、「App is available」セクションで「No」を選択して「App download link」をスキップできます。
  • 「App operation flow chart」は少し難しそうに見えます。経験上、シンプルなフローチャートといくつかのアプリのスクリーンショットを用意すると審査通過の可能性が高まります。

「Next step」をクリックして進みます。

プラットフォーム情報

iOS と Android のいずれか、または両方のプラットフォームを設定して、Logto と WeChat ネイティブサインインを統合できます。

iOS アプリ

「iOS app」(iOS 应用)にチェックを入れ、アプリの対象デバイスタイプも選択します。

アプリプラットフォーム

App Store での公開を「No」にした場合は、「AppStore download address」の入力を省略できます。

Bundle IDTest version Bundle IDUniversal Links を入力します(実際には 1 つのリンクだけで十分です 😂)。

注記:

Bundle IDTest version Bundle ID は同じ値でも構いません。

ヒント:

WeChat のネイティブサインインにはユニバーサルリンクが必要です。まだ設定していない場合や分からない場合は、 Apple 公式ドキュメント を参照してください。

Android アプリ

「Android app」(Android 应用)にチェックを入れます。

Android アプリプラットフォーム

Application Signing Signature(应用签名)と Application Package Name(应用包名)を入力します。

注記:

署名を取得するにはアプリに署名する必要があります。詳細は Sign your app を参照してください。

署名が完了したら、signingReport タスクを実行して署名情報を取得できます。

./gradlew your-android-project:signingReport

該当ビルドバリアントのレポート内の MD5 値が Application Signing Signature(应用签名)となりますが、値からセミコロンをすべて削除し、小文字にしてください。

例:1A:2B:3C:4D1a2b3c4d

審査結果を待つ

プラットフォーム情報の入力が終わったら、「Submit Review」をクリックして続行します。通常、審査は早く、1~2日以内に終了します。

審査基準は一定ではなく、審査担当者は毎回ランダムに割り当てられているようです。最初はリジェクトされることもありますが、諦めずに現状を説明し、どのように修正すればよいか審査担当者に尋ねてみてください。

アプリで WeChat ネイティブサインインを有効にする

iOS

アプリに Logto iOS SDK を統合済みであることを前提とします。この場合、非常にシンプルで、WeChat SDK のドキュメントを読む必要すらありません:

1. Xcode プロジェクトでユニバーサルリンクと URL スキームを設定する

Xcode プロジェクト → Signing & Capabilities タブで「Associated Domains」機能を追加し、事前に設定したユニバーサルリンクを追加します。

ユニバーサルリンク

次に「Info」タブに移動し、WeChat App ID を使って カスタム URL スキーム を追加します。

カスタム URL スキーム

最後に Info.plist を開き、LSApplicationQueriesSchemes の下に weixinULAPIweixin を追加します。

Plist
注記:

これらの手順はあまり合理的ではありませんが、私たちが見つけた最小限の動作構成です。詳細は 公式ガイド(魔法のような) を参照してください。

2. LogtoSocialPluginWechat を Xcode プロジェクトに追加する

フレームワークを追加します:

フレームワーク追加

そして Build Settings > Linking > Other Linker Flags に -ObjC を追加します:

リンカーフラグ
注記:

このプラグインには WeChat Open SDK 1.9.2 が含まれています。プラグインをインポートすれば import WechatOpenSDK を直接利用できます。

3. プラグインを LogtoClient の初期化オプションに追加する

let logtoClient = LogtoClient(
useConfig: config,
socialPlugins: [LogtoSocialPluginWechat()]
)

4. onOpenURL を適切に処理する

注記:

LogtoClient.handle(url:) 関数は有効化したすべてのネイティブコネクターを処理します。1 回呼び出すだけで十分です。

// SwiftUI
YourRootView()
.onOpenURL { url in
LogtoClient.handle(url: url)
}

// または AppDelegate
func application(_ app: UIApplication, open url: URL, options: /*...*/) -> Bool {
LogtoClient.handle(url: url)
}

Android

アプリに Logto Android SDK を統合済みであることを前提とします。この場合、非常にシンプルで、WeChat SDK のドキュメントを読む必要すらありません:

1. プロジェクトに Wechat Open SDK を追加する

mavenCentral() リポジトリが Gradle プロジェクトのリポジトリに含まれていることを確認します:

repositories {
// ...
mavenCentral()
}

Wechat Open SDK を依存関係に追加します:

dependencies {
// ...
api("com.tencent.mm.opensdk:wechat-sdk-android:6.8.0") // kotlin-script
// または
api 'com.tencent.mm.opensdk:wechat-sdk-android:6.8.0' // groovy-script
}

2. プロジェクトに WXEntryActivity を導入する

パッケージルートの下に wxapi パッケージを作成し、その中に WXEntryActivity を追加します(例:com.sample.app の場合):

// WXEntryActivity.kt
package com.sample.app.wxapi

import io.logto.sdk.android.auth.social.wechat.WechatSocialResultActivity

class WXEntryActivity: WechatSocialResultActivity()
// WXEntryActivity.java
package com.sample.app.wxapi

import io.logto.sdk.android.auth.social.wechat.WechatSocialResultActivity

public class WXEntryActivity extends WechatSocialResultActivity {}

プロジェクト内での WXEntryActivity の最終的な配置は次のようになります(Kotlin の例):

src/main/kotlin/com/sample/app/wxapi/WXEntryActivity.kt

3. AndroidManifest.xml を修正する

AndroidManifest.xml に次の行を追加します:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.sample.app">

<application>
<!-- 追加する行 -->
<activity android:name=".wxapi.WXEntryActivity" android:exported="true"/>
</application>

</manifest>

設定を保存する

Logto コネクター設定エリアで必要な値をすべて記入したことを確認してください。「保存して完了」または「変更を保存」をクリックすると、WeChat (Native) コネクターが利用可能になります。

サインイン体験で WeChat (Native) コネクターを有効にする

ソーシャルコネクターを正常に作成したら、サインイン体験で「WeChat (Native) で続行」ボタンとして有効にすることができます。

  1. Console > サインイン体験 > サインアップとサインイン に移動します。
  2. (オプション)ソーシャルログインのみが必要な場合は、サインアップ識別子に「該当なし」を選択します。
  3. 設定済みの WeChat (Native) コネクターを「ソーシャルサインイン」セクションに追加します。
サインイン体験タブ

テストと検証

Java Spring Boot アプリに戻ります。これで WeChat (Native) を使用してサインインできるはずです。お楽しみください!

さらなる読み物

エンドユーザーフロー:Logto は、MFA やエンタープライズシングルサインオン (SSO) を含む即時使用可能な認証 (Authentication) フローを提供し、アカウント設定、セキュリティ検証、マルチテナント体験の柔軟な実装のための強力な API を備えています。

認可 (Authorization):認可 (Authorization) は、ユーザーが認証 (Authentication) された後に行えるアクションやアクセスできるリソースを定義します。ネイティブおよびシングルページアプリケーションの API を保護し、ロールベースのアクセス制御 (RBAC) を実装する方法を探ります。

組織 (Organizations):特にマルチテナント SaaS や B2B アプリで効果的な組織機能は、テナントの作成、メンバー管理、組織レベルの RBAC、およびジャストインタイムプロビジョニングを可能にします。

顧客 IAM シリーズ:顧客(または消費者)アイデンティティとアクセス管理に関する連続ブログ投稿で、101 から高度なトピックまでを網羅しています。