Flutter Azure AD 登录插件dart_azure_ad_sign_in的使用
Flutter Azure AD 登录插件 dart_azure_ad_sign_in
的使用
1. 平台支持
平台 | Dart | Flutter | 测试环境 |
---|---|---|---|
Android | ✖️ | ✔️ | Pixel 4 (模拟器) 和 Xiaomi 9T |
iOS | ✖️ | ➖ | 尚未测试,但应该可以工作 |
Linux | ✔️ | ✔️ | Ubuntu 22.04 LTS |
macOS | ➖ | ➖ | 尚未测试,但应该可以工作 |
Web | ✖️ | ✖️ | 使用 dart.io 的 HttpServer,无法在 Web 上工作 |
Windows | ✔️ | ✔️ | Windows 11 |
2. 功能
dart_azure_ad_sign_in
插件允许 Flutter 和 Dart 应用程序获取用于访问受保护资源(如 Azure Web API)的认证令牌。该插件可以无需任何配置即可使用,提供与 Azure CLI 相同的访问权限,也可以通过配置来修改访问权限。
3. 认证流程
4. 入门指南
4.1 安装
前往 Pub.dev 获取最新版本。
4.2 导入
在 Dart 文件中导入 dart_azure_ad_sign_in
包:
import 'package:dart_azure_ad_sign_in/dart_azure_ad_sign_in.dart';
4.3 Android 设置
4.3.1 网络设置
确保在 AndroidManifest.xml
中启用网络权限:
<manifest xmlns:android...>
...
<uses-permission android:name="android.permission.INTERNET" />
<application ...
</manifest>
4.3.2 明文流量
创建 res/xml/network_security_config.xml
文件并配置如下:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">localhost</domain>
</domain-config>
</network-security-config>
然后在 AndroidManifest.xml
中加载该文件:
<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
<application
...
android:networkSecurityConfig="@xml/network_security_config"
...>
...
</application>
</manifest>
4.4 iOS 设置
4.4.1 网络设置
iOS 不需要额外的网络设置。
4.4.2 明文流量
在 info.plist
中添加以下规则以允许本地主机的明文流量:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<false/>
<key>NSExceptionDomains</key>
<dict>
<key>localhost</key>
<dict>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSTemporaryExceptionMinimumTLSVersion</key>
<string>TLSv1.1</string>
</dict>
</dict>
</dict>
4.5 macOS 设置
4.5.1 网络设置
在 .entitlements
文件中启用网络权限:
<key>com.apple.security.network.client</key>
<true/>
4.5.2 明文流量
在 info.plist
中添加以下规则以允许本地主机的明文流量:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<false/>
<key>NSExceptionDomains</key>
<dict>
<key>localhost</key>
<dict>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSTemporaryExceptionMinimumTLSVersion</key>
<string>TLSv1.1</string>
</dict>
</dict>
</dict>
4.6 Windows 设置
无需额外设置。
4.7 Linux 设置
无需额外设置。
5. 使用方法
5.1 创建和配置 AzureSignIn
实例
AzureSignIn
类非常灵活,无需设置参数即可使用,默认会使用 Azure CLI 配置。有关所有可用变量的详细信息,请参阅 AzureSignIn 变量。
5.1.1 使用默认设置创建实例
final azureSignIn = AzureSignIn();
5.1.2 使用参数创建实例
如果需要,可以设置认证和本地 HTTP 服务器的参数:
final azureSignIn = AzureSignIn(
// 应用程序(客户端)ID,Azure 门户 - 应用注册页面分配给你的应用。
clientId: '04b07795-8ddb-461a-bbee-02f9e1bf7b46',
// 用户需要同意的权限范围。
scope: [
'https://management.core.windows.net//.default',
'offline_access',
'openid',
'profile',
],
// 本地 HTTP 服务器的端口,用于接收登录后的代码。
port: 5000,
// 登录成功后用户在浏览器中看到的响应。
serverSuccessResponse: '<h1>登录成功。</h1><p>可以关闭此窗口。</p>',
// 登录失败后用户在浏览器中看到的响应。
serverErrorResponse: '<h1>登录失败。</h1><p>请关闭此窗口并重试。</p>',
// 本地 HTTP 服务器等待用户登录的时间。
signInTimeoutDuration: Duration(minutes: 5),
);
5.2 登录
5.2.1 获取 Microsoft 登录页面 URL
用户需要在浏览器中登录,可以通过 signInUri
获取登录 URL。如果使用 Flutter,可以使用 url_launcher
插件打开该 URL。
// 打印登录 URL,用户需要在浏览器中打开。
print(azureSignIn.signInUri);
5.2.2 启动登录过程
启动登录过程将返回一个新的 Token
。在后台,会启动一个 HttpServer
,等待浏览器登录后接收到代码,然后调用 Microsoft Token Endpoint 获取令牌。
Token token = await azureSignIn.signIn();
5.3 取消登录过程
用户可以在需要时取消登录过程。azureSignIn.signIn()
将返回一个带有取消信息的 Token
。
// 取消登录过程。
await azureSignIn.cancelSignIn();
5.4 刷新令牌
当令牌过期时,可以通过提供现有的 Token
或刷新令牌字符串来刷新令牌。
5.4.1 使用现有 Token
刷新
// 使用现有令牌对象刷新令牌。
token = await azureSignIn.refreshToken(token: token);
5.4.2 使用刷新令牌字符串刷新
// 使用刷新令牌字符串刷新令牌。
token = await azureSignIn.refreshToken(refreshToken: refreshTokenString);
5.5 AzureSignIn
变量
名称 | 类型 | 默认值 | 是否可修改 | 描述 |
---|---|---|---|---|
azureSignIn.clientId |
String | 04b07795-8ddb-461a-bbee-02f9e1bf7b46 |
✓ | 应用程序(客户端)ID,默认使用 Azure CLI 客户端 ID。 |
azureSignIn.scope |
List<String> | ['https://management.core.windows.net//.default', 'offline_access', 'openid', 'profile'] |
✓ | 用户需要同意的权限范围,默认使用 Azure CLI 权限范围。 |
azureSignIn.grantType |
String | authorization_code |
✗ | 授权类型,必须为 authorization_code 。 |
azureSignIn.port |
int | 5000 |
✓ | 本地 HTTP 服务器的端口。 |
azureSignIn.signInTimeoutDuration |
Duration() | Duration(minutes: 5) |
✓ | 本地 HTTP 服务器等待用户登录的时间。 |
azureSignIn.serverSuccessResponse |
String | Sign In successful. This window can now be closed. |
✓ | 登录成功后用户在浏览器中看到的响应。 |
azureSignIn.serverErrorResponse |
String | Sign In failed. Close this window and try again. |
✓ | 登录失败后用户在浏览器中看到的响应。 |
azureSignIn.signInUri |
String | 生成的 Microsoft 登录 URL | ✗ | 获取 Microsoft 登录 URL。 |
azureSignIn.signOutUri |
String | https://login.microsoftonline.com/common/oauth2/v2.0/logout |
✗ | 用于登出的 Azure Auth URL。 |
5.6 Token
实体
名称 | 类型 | 示例值 | 描述 |
---|---|---|---|
token.tokenType |
String | Bearer |
表示令牌类型,Azure AD 支持的唯一类型是 Bearer 。 |
token.scope |
String | user_impersonation |
令牌有效的权限范围。 |
token.expiresIn |
String | 5084 |
令牌的有效时间(秒)。 |
token.extExpiresIn |
String | 5084 |
用于表示令牌的扩展生命周期。 |
token.expiresOn |
String | 1674580651 |
令牌过期的时间戳。 |
token.notBefore |
String | 1674575266 |
令牌生效的时间戳。 |
token.resource |
String | https://management.core.windows.net/ |
令牌访问的资源。 |
token.accessToken |
String | eyJ0eXAiOiJKV1QiLCJhbGciOiJS... |
访问令牌,应用程序可以使用此令牌访问受保护的资源。 |
token.refreshToken |
String | 0.AQUAjHBCWE0CK06v4qgD88sl3Z... |
OAuth 2.0 刷新令牌,用于在当前访问令牌过期后获取新的访问令牌。 |
token.idToken |
String | eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIs... |
JSON Web Token,应用程序可以解码此令牌以获取用户信息。 |
token.foci |
String | 1 |
使用 FOCI(客户端 ID 家族)访问 Microsoft Office 应用程序。 |
token.status |
int | 0: 成功<br>1: Azure API 错误<br>2: HttpServer 错误<br>3: 登录已取消 |
令牌授权代码流的结果状态。 |
token.error |
String | invalid_grant |
错误代码字符串,用于分类错误类型。 |
token.errorDescription |
String | AADSTS900144: The request body must contain the following parameter: 'code'... |
具体的错误消息,帮助开发者识别认证错误的根本原因。 |
token.errorCodes |
List<dynamic> | [900144] |
STS 特定的错误代码列表,用于诊断。 |
token.errorUri |
String | https://login.microsoftonline.com/error?code=900144 |
关于出现错误的 Microsoft 文档 URL。 |
6. 下一步
使用 token.accessToken
,你现在已经可以访问 Microsoft APIs。更多关于 Azure REST API 的信息可以参考 Azure Rest API 参考,或查看 常用 Microsoft 应用程序的应用 ID 以添加一些预定义的 azureSignIn.clientId
。
7. Bug 和问题
请在 GitHub Issues 提交功能请求和 bug。
完整示例 Demo
以下是一个完整的示例,展示了如何使用 dart_azure_ad_sign_in
插件进行 Azure AD 登录和令牌刷新:
// Copyright 2023 Patrick Hettich. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:dart_azure_ad_sign_in/dart_azure_ad_sign_in.dart';
void main(List<String> args) async {
// 创建 Azure SignIn 实例,所有参数都是可选的。
final azureSignIn = AzureSignIn();
// 打印登录 URL。
print(azureSignIn.signInUri);
// 启动 HTTP 服务器并等待用户登录。
// 也可以通过 azureSignIn.cancelSignIn() 取消登录。
Token token = await azureSignIn.signIn();
// 打印令牌信息
printToken(token: token, title: '初始令牌');
// 刷新过期的令牌
token = await azureSignIn.refreshToken(token: token);
// 打印更新后的令牌信息
printToken(token: token, title: '刷新后的令牌');
}
void printToken({required Token token, required String title}) {
print(
'------------------------------------------------------------------------------------------------------------------------------------');
print(title);
print(
'------------------------------------------------------------------------------------------------------------------------------------');
print('状态: ${token.status}');
print('错误: ${token.error}');
print('错误消息: ${token.errorDescription}');
print('访问令牌:');
print(token.accessToken);
print('刷新令牌:');
print(token.refreshToken);
}
更多关于Flutter Azure AD 登录插件dart_azure_ad_sign_in的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter Azure AD 登录插件dart_azure_ad_sign_in的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个使用 dart_azure_ad_sign_in
插件在 Flutter 应用中实现 Azure AD 登录的示例代码。请确保您已经按照插件的文档完成了相关的设置,包括在 Azure 门户中注册您的应用并获取所需的客户端 ID 和重定向 URI。
首先,您需要在 pubspec.yaml
文件中添加 dart_azure_ad_sign_in
依赖:
dependencies:
flutter:
sdk: flutter
dart_azure_ad_sign_in: ^x.y.z # 请替换为最新的版本号
然后,运行 flutter pub get
来获取依赖。
接下来,是主要的 Flutter 代码示例:
import 'package:flutter/material.dart';
import 'package:dart_azure_ad_sign_in/dart_azure_ad_sign_in.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Azure AD Login',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: AzureADLoginPage(),
);
}
}
class AzureADLoginPage extends StatefulWidget {
@override
_AzureADLoginPageState createState() => _AzureADLoginPageState();
}
class _AzureADLoginPageState extends State<AzureADLoginPage> {
final AzureADSignIn _azureADSignIn = AzureADSignIn(
clientId: 'YOUR_CLIENT_ID', // 替换为您的 Azure AD 应用的客户端 ID
redirectUri: 'YOUR_REDIRECT_URI', // 替换为您在 Azure 门户中设置的重定向 URI
tenantId: 'YOUR_TENANT_ID', // 替换为您的 Azure AD 租户 ID(如果需要特定租户)
);
String _userDisplayName = '';
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Azure AD Login'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'User Display Name: $_userDisplayName',
style: TextStyle(fontSize: 20),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () async {
try {
final result = await _azureADSignIn.signIn();
if (result != null) {
setState(() {
_userDisplayName = result.displayName;
});
}
} catch (e) {
print('Error during Azure AD login: $e');
}
},
child: Text('Sign In with Azure AD'),
),
],
),
),
);
}
}
在这个示例中,我们创建了一个简单的 Flutter 应用,其中包含一个按钮,用户点击该按钮后将触发 Azure AD 登录流程。登录成功后,我们将用户的显示名称显示在屏幕上。
请确保将 YOUR_CLIENT_ID
、YOUR_REDIRECT_URI
和 YOUR_TENANT_ID
替换为您在 Azure 门户中配置的实际值。
此外,您可能还需要在 Android 和 iOS 项目中进行一些额外的配置,以确保重定向 URI 能够正确处理。这通常涉及到修改 AndroidManifest.xml
文件和 iOS 的 Info.plist
文件,以及可能需要在 Xcode 和 Android Studio 中进行一些设置。具体步骤请参考 dart_azure_ad_sign_in
插件的官方文档。