跳到主要内容
给我们的新朋友:

Logto 是一个为现代应用和 SaaS 产品设计的 Auth0 替代方案。它提供 Cloud开源 服务,帮助你快速启动身份和管理 (IAM) 系统。享受认证 (Authentication)、授权 (Authorization) 和多租户管理 一体化

我们建议从 Logto Cloud 上的免费开发租户开始。这可以让你轻松探索所有功能。

在本文中,我们将介绍使用 FlutterLogto 快速构建 Microsoft Entra ID SAML enterprise SSO 登录体验(用户认证 (Authentication))的步骤。

先决条件

  • 一个正在运行的 Logto 实例。查看 介绍页面 以开始。
  • Flutter 的基本知识。
  • 一个可用的 Microsoft Entra ID SAML enterprise SSO 账户。

Create an application in Logto

Logto 基于 OpenID Connect (OIDC) 认证 (Authentication) 和 OAuth 2.0 授权 (Authorization)。它支持跨多个应用程序的联合身份管理,通常称为单点登录 (SSO)。

要创建你的 Native app 应用程序,只需按照以下步骤操作:

  1. 打开 Logto Console。在“开始使用”部分,点击“查看全部”链接以打开应用程序框架列表。或者,你可以导航到 Logto Console > Applications,然后点击“创建应用程序”按钮。 开始使用
  2. 在打开的模态窗口中,点击“Native app”部分,或使用左侧的快速过滤复选框过滤所有可用的“Native app”框架。点击 "Flutter" 框架卡片以开始创建你的应用程序。 框架
  3. 输入应用程序名称,例如“Bookstore”,然后点击“创建应用程序”。

🎉 太棒了!你刚刚在 Logto 中创建了你的第一个应用程序。你将看到一个祝贺页面,其中包含详细的集成指南。按照指南查看你的应用程序中的体验将会是什么样的。

Integrate Flutter SDK

提示:
  • SDK 包可在 pub.dev 和 Logto GitHub 仓库 上获取。
  • 示例项目使用 Flutter material 构建。你可以在 pub.dev 上找到它。
  • 此 SDK 兼容 iOS、Android 和 Web 平台上的 Flutter 应用程序。与其他平台的兼容性尚未测试。

安装

你可以使用 pub 包管理器直接安装 logto_dart_sdk package。 在你的项目根目录下运行以下命令:

flutter pub add logto_dart_sdk

或者将以下内容添加到你的 pubspec.yaml 文件中:

dependencies:
logto_dart_sdk: ^3.0.0

然后运行:

flutter pub get

依赖和配置

SDK 版本兼容性

Logto SDK 版本Dart SDK 版本Dart 3.0 兼容性
< 2.0.0>= 2.17.6 < 3.0.0false
>= 2.0.0 < 3.0.0>= 3.0.0true
>= 3.0.0>= 3.6.0true

flutter_secure_storage 设置

在底层,这个 SDK 使用 flutter_secure_storage 来实现跨平台的持久安全令牌存储。

  • iOS 使用 Keychain
  • Android 使用 AES 加密。

配置 Android 版本

在项目的 android/app/build.gradle 文件中,将 android:minSdkVersion 设置为 >= 18

build.gradle
  android {
...

defaultConfig {
...
minSdkVersion 18
...
}
}

禁用 Android 上的自动备份

默认情况下,Android 会在 Google Drive 上备份数据。这可能导致异常 java.security.InvalidKeyException:Failed 解包密钥。为避免这种情况,

  1. 要禁用自动备份,请转到应用程序的清单文件,并将 android:allowBackupandroid:fullBackupContent 属性设置为 false

    AndroidManifest.xml
    <manifest ... >
    ...
    <application
    android:allowBackup="false"
    android:fullBackupContent="false"
    ...
    >
    ...
    </application>
    </manifest>

  2. FlutterSecureStorage 中排除 sharedprefs

    如果你需要为应用程序保留 android:fullBackupContent 而不是禁用它,可以从备份中排除 sharedprefs 目录。 请参阅 Android 文档 了解更多详细信息。

    在你的 AndroidManifest.xml 文件中,向 <application> 元素添加 android:fullBackupContent 属性,如以下示例所示。此属性指向一个包含备份规则的 XML 文件。

    AndroidManifest.xml
    <application ...
    android:fullBackupContent="@xml/backup_rules">
    </application>

    res/xml/ 目录中创建一个名为 @xml/backup_rules 的 XML 文件。在此文件中,使用 <include><exclude> 元素添加规则。以下示例备份所有共享首选项,除了 device.xml:

    @xml/backup_rules
    <?xml version="1.0" encoding="utf-8"?>
    <full-backup-content>
    <exclude domain="sharedpref" path="FlutterSecureStorage"/>
    </full-backup-content>

请查看 flutter_secure_storage 以获取更多详细信息。

flutter_web_auth_2 设置

在幕后,这个 SDK 使用 flutter_web_auth_2 来通过 Logto 认证用户。这个包提供了一种简单的方法,通过系统 webview 或浏览器来使用 Logto 认证用户。

这个插件在 iOS 12+ 和 macOS 10.15+ 上使用 ASWebAuthenticationSession,在 iOS 11 上使用 SFAuthenticationSession,在 Android 上使用 Chrome Custom Tabs,并在 Web 上打开一个新窗口。

  • iOS:无需额外设置

  • Android:在 Android 上注册回调 URL

    为了从 Logto 的登录网页捕获回调 URL,你需要在 AndroidManifest.xml 文件中注册你的登录 redirectUri。

    AndroidManifest.xml
      <manifest>
    <application>
    <activity
    android:name="com.linusu.flutter_web_auth_2.CallbackActivity"
    android:exported="true">
    <intent-filter android:label="flutter_web_auth_2">
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="YOUR_CALLBACK_URL_SCHEME_HERE" />
    </intent-filter>
    </activity>
    </application>
    </manifest>
  • Web 浏览器:创建一个端点来处理回调 URL

    如果你使用的是 Web 平台,你需要创建一个端点来处理回调 URL,并使用 postMessage API 将其发送回应用程序。

    callback.html
    <!doctype html>
    <title>认证完成</title>
    <p>认证已完成。如果没有自动发生,请关闭窗口。</p>
    <script>
    function postAuthenticationMessage() {
    const message = {
    'flutter-web-auth-2': window.location.href,
    };

    if (window.opener) {
    window.opener.postMessage(message, window.location.origin);
    window.close();
    } else if (window.parent && window.parent !== window) {
    window.parent.postMessage(message, window.location.origin);
    } else {
    localStorage.setItem('flutter-web-auth-2', window.location.href);
    window.close();
    }
    }

    postAuthenticationMessage();
    </script>

请查看 flutter_web_auth_2 包中的设置指南以获取更多详细信息。

集成

初始化 LogtoClient

导入 logto_dart_sdk 包并在应用程序的根部初始化 LogtoClient 实例。

lib/main.dart
import 'package:logto_dart_sdk/logto_dart_sdk.dart';
import 'package:http/http.dart' as http;

void main() async {
WidgetsFlutterBinding.ensureInitialized();
runApp(const MyApp());
}

class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);


Widget build(BuildContext context) {
return const MaterialApp(
title: 'Flutter Demo',
home: MyHomePage(title: 'Logto Demo Home Page'),
);
}
}

class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;


State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
late LogtoClient logtoClient;

void render() {
// 状态变化
}

// LogtoConfig
final logtoConfig = const LogtoConfig(
endpoint: "<your-logto-endpoint>",
appId: "<your-app-id>"
);

void _init() {
logtoClient = LogtoClient(
config: logtoConfig,
httpClient: http.Client(), // 可选的 http 客户端
);
render();
}


void initState() {
super.initState();
_init();
}

// ...
}

实现登录

在我们深入细节之前,这里是终端用户体验的快速概述。登录过程可以简化如下:

  1. 你的应用调用登录方法。
  2. 用户被重定向到 Logto 登录页面。对于原生应用,将打开系统浏览器。
  3. 用户登录并被重定向回你的应用(配置为重定向 URI)。

关于基于重定向的登录

  1. 此认证 (Authentication) 过程遵循 OpenID Connect (OIDC) 协议,Logto 强制执行严格的安全措施以保护用户登录。
  2. 如果你有多个应用程序,可以使用相同的身份提供商 (IdP)(日志 (Logto))。一旦用户登录到一个应用程序,当用户访问另一个应用程序时,Logto 将自动完成登录过程。

要了解有关基于重定向的登录的原理和好处的更多信息,请参阅 Logto 登录体验解释


在开始之前,你需要在管理控制台为你的应用程序添加一个重定向 URI。

让我们切换到 Logto Console 的应用详情页面。添加一个重定向 URI io.logto://callback 并点击“保存更改”。

Logto Console 中的重定向 URI
  • 对于 iOS,重定向 URI 方案并不重要,因为 ASWebAuthenticationSession 类会监听重定向 URI,无论它是否注册。
  • 对于 Android,重定向 URI 方案必须在 AndroidManifest.xml 文件中注册。

配置好重定向 URI 后,我们在页面上添加一个登录按钮,该按钮将调用 logtoClient.signIn API 来启动 Logto 登录流程:

lib/main.dart
class _MyHomePageState extends State<MyHomePage> {
// ...
final redirectUri = 'io.logto://callback';


Widget build(BuildContext context) {
// ...

Widget signInButton = TextButton(
onPressed: () async {
await logtoClient.signIn(redirectUri);
render();
},
child: const Text('Sign In'),
);

return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SelectableText('My Demo App'),
signInButton,
],
),
),
);
}
}

实现登出

让我们切换到 Logto Console 的应用详情页面。添加一个注销后重定向 URI io.logto://callback,然后点击“保存更改”。

Logto Console 中的注销后重定向 URI

注销后重定向 URI 是一个 OAuth 2.0 概念,意味着在注销后应该重定向的位置。

现在让我们在主页上添加一个登出按钮,以便用户可以从你的应用程序中登出。

lib/main.dart
class _MyHomePageState extends State<MyHomePage> {
// ...

final postSignOutRedirectUri = 'io.logto//home';


Widget build(BuildContext context) {
// ...

Widget signOutButton = TextButton(
onPressed: () async {
await logtoClient.signOut(postSignOutRedirectUri);
render();
},
child: const Text('Sign Out'),
);

return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SelectableText('My Demo App'),
signInButton,
signOutButton,
],
),
),
);
}
}

处理认证 (Authentication) 状态

Logto SDK 提供了一个异步方法来检查认证 (Authentication) 状态。该方法是 logtoClient.isAuthenticated。该方法返回一个布尔值,如果用户已认证 (Authentication),则返回 true,否则返回 false

在示例中,我们根据认证 (Authentication) 状态有条件地渲染登录和登出按钮。现在让我们更新 Widget 中的 render 方法以处理状态变化:

lib/main.dart
class _MyHomePageState extends State<MyHomePage> {
// ...
bool? isAuthenticated = false;

void render() {
setState(() async {
isAuthenticated = await logtoClient.isAuthenticated;
});
}


Widget build(BuildContext context) {
// ...

return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SelectableText('My Demo App'),
isAuthenticated == true ? signOutButton : signInButton,
],
),
),
);
}
}

检查点:测试你的应用程序

现在,你可以测试你的应用程序:

  1. 运行你的应用程序,你将看到登录按钮。
  2. 点击登录按钮,SDK 将初始化登录过程并将你重定向到 Logto 登录页面。
  3. 登录后,你将被重定向回你的应用程序,并看到登出按钮。
  4. 点击登出按钮以清除令牌存储并登出。

Add Microsoft Entra ID SAML enterprise SSO connector

To simplify access management and gain enterprise-level safeguards for your big clients, connect with Flutter as a federated identity provider. The Logto enterprise SSO connector helps you establish this connection in minutes by allowing several parameter inputs.

To add an enterprise SSO connector, simply follow these steps:

  1. Navigate to Logto console > Enterprise SSO.

SSO page

  1. Click "Add enterprise connector" button and choose your SSO provider type. Choose from prebuilt connectors for Microsoft Entra ID (Azure AD), Google Workspace, and Okta, or create a custom SSO connection using the standard OpenID Connect (OIDC) or SAML protocol.
  2. Provide a unique name (e.g., SSO sign-in for Acme Company).

Select your SSO provider

  1. Configure the connection with your IdP in the "Connection" tab. Check the guides above for each connector types.

SSO connection

  1. Customize the SSO experience and enterprise’s email domain in the "Experience" tab. Users sign in with the SSO-enabled email domain will be redirected to SSO authentication.

SSO experience

  1. Save changes.

Set up Azure AD SSO 应用程序

步骤 1:创建 Azure AD 单点登录 (SSO) 应用程序

开始 Azure AD 单点登录 (SSO) 集成,首先在 Azure AD 端创建一个 SSO 应用程序。

  1. 访问 Azure 门户 并以管理员身份登录。
  2. 选择 Microsoft Entra ID 服务。
  3. 使用侧边菜单导航到 企业应用程序。点击 新建应用程序,然后选择 创建你自己的应用程序

Azure AD create application.webp

  1. 输入应用程序名称并选择 集成任何其他在库中找不到的应用程序(非库)
  2. 选择 设置单点登录 > SAML

Azure AD set up SSO.webp

  1. 按照说明进行操作,第一步,你需要使用 Logto 提供的以下信息填写基本的 SAML 配置。

Azure AD SP config

  • 受众 (Audience) URI(SP 实体 ID):它表示为你的 Logto 服务的全局唯一标识符,在向身份提供商 (IdP) 发送认证请求时作为 SP 的 EntityId。此标识符对于在 IdP 和 Logto 之间安全交换 SAML 断言和其他认证相关数据至关重要。
  • ACS URL:断言消费者服务 (ACS) URL 是通过 POST 请求发送 SAML 断言的位置。此 URL 由 IdP 用于将 SAML 断言发送到 Logto。它充当回调 URL,Logto 期望在此接收和消费包含用户身份信息的 SAML 响应。

点击 保存 以继续。

步骤 2:在 Logto 配置 SAML 单点登录 (SSO)

要使 SAML 单点登录 (SSO) 集成正常工作,你需要将 IdP 元数据提供给 Logto。让我们切换回 Logto 端,导航到你的 Azure AD SSO 连接器的 Connection 选项卡。

Logto 提供了三种不同的方法来配置 IdP 元数据。最简单的方法是提供 Azure AD SSO 应用程序的 metadata URL

从你的 Azure AD SSO 应用程序的 SAML Certificates section 中复制 App Federation Metadata Url,并将其粘贴到 Logto 的 Metadata URL 字段中。

Azure AD Metadata URL.webp

Logto 将从该 URL 获取元数据,并自动配置 SAML 单点登录 (SSO) 集成。

步骤 3:配置用户属性映射

Logto 提供了一种灵活的方法,将从身份提供商 (IdP) 返回的用户属性映射到 Logto 中的用户属性。Logto 默认会从 IdP 同步以下用户属性:

  • id:用户的唯一标识符。Logto 将从 SAML 响应中读取 nameID 声明作为用户 SSO 身份 id。
  • email:用户的电子邮件地址。Logto 默认将从 SAML 响应中读取 email 声明作为用户的主电子邮件。
  • name:用户的姓名。

你可以在 Azure AD 端或 Logto 端管理用户属性映射逻辑。

  1. 在 Logto 端将 AzureAD 用户属性映射到 Logto 用户属性。

    访问你的 Azure AD SSO 应用程序的 Attributes & Claims 部分。

    复制以下属性名称(带有命名空间前缀)并粘贴到 Logto 中的相应字段。

    • http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress
    • http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name(建议:将此属性值映射更新为 user.displayname 以获得更好的用户体验)

Azure AD 默认属性映射.webp

  1. 在 AzureAD 端将 AzureAD 用户属性映射到 Logto 用户属性。

    访问你的 Azure AD SSO 应用程序的 Attributes & Claims 部分。

    点击 Edit,并根据 Logto 用户属性设置更新 Additional claims 字段:

    • 根据 Logto 用户属性设置更新声明名称值。
    • 移除命名空间前缀。
    • 点击 Save 继续。

    最终应得到以下设置:

Azure AD_Logto 属性映射.webp

你还可以在 Azure AD 端指定其他用户属性。Logto 将在用户的 sso_identity 字段下记录从 IdP 返回的原始用户属性。

步骤 4:将用户分配到 Azure AD 单点登录 (SSO) 应用程序

访问 Azure AD SSO 应用程序的 Users and groups 部分。点击 Add user/group 将用户分配到 Azure AD SSO 应用程序。只有分配到你的 Azure AD SSO 应用程序的用户才能通过 Azure AD SSO 连接器进行认证 (Authentication)。

Azure AD assign users.webp

步骤 5:设置电子邮件域并启用 SSO 连接器

在 Logto 的连接器 SSO 体验 选项卡中提供你组织的 电子邮件域。这将启用 SSO 连接器作为这些用户的认证 (Authentication) 方法。

具有指定域电子邮件地址的用户将被重定向使用 SAML SSO 连接器作为他们唯一的认证 (Authentication) 方法。

请查看 Azure AD 的官方文档以获取有关 Azure AD SSO 集成的更多详细信息。

Save your configuration

仔细检查你是否在 Logto 连接器配置区域填写了必要的值。点击“保存并完成”(或“保存更改”),Microsoft Entra ID SAML enterprise SSO 连接器现在应该可用了。

Enable Microsoft Entra ID SAML enterprise SSO connector in Sign-in Experience

You don’t need to configure enterprise connectors individually, Logto simplifies SSO integration into your applications with just one click.

  1. Navigate to: Console > Sign-in experience > Sign-up and sign-in.
  2. Enable the "Enterprise SSO" toggle.
  3. Save changes.

Once enabled, a "Single Sign-On" button will appear on your sign-in page. Enterprise users with SSO-enabled email domains can access your services using their enterprise identity providers (IdPs).

Auto detect SSO sign-in via email domain Navigate to SSO sign-in via manually click link button

To learn more about the SSO user experience, including SP-initiated SSO and IdP-initiated SSO, refer to User flows: Enterprise SSO.

Testing and Validation

返回到你的 Flutter 应用。你现在应该可以使用 Microsoft Entra ID SAML enterprise SSO 登录了。享受吧!

Further readings

终端用户流程:Logto 提供开箱即用的认证 (Authentication) 流程,包括多因素认证 (MFA) 和企业单点登录 (SSO),以及强大的 API,用于灵活实现账户设置、安全验证和多租户体验。

授权 (Authorization):授权 (Authorization) 定义了用户在被认证 (Authentication) 后可以执行的操作或访问的资源。探索如何保护你的 API 以用于原生和单页应用程序,并实现基于角色的访问控制 (RBAC)。

组织 (Organizations):在多租户 SaaS 和 B2B 应用中特别有效,组织功能支持租户创建、成员管理、组织级 RBAC 和即时供应。

客户 IAM 系列:我们关于客户(或消费者)身份和访问管理的系列博客文章,从 101 到高级主题及更深入的内容。