Flutter Azure AD 认证插件azure_ad_authentication的使用

发布于 1周前 作者 eggper 来自 Flutter

Flutter Azure AD 认证插件 azure_ad_authentication 使用指南

azure_ad_authentication 是一个用于在 Android、iOS 和 macOS 平台上实现 Azure AD 登录的 Flutter 插件。它可以帮助开发者获取用户的认证信息和令牌,并管理会话过期时间。

注册你的应用程序

  1. 使用工作或学校账户登录 Azure 门户
  2. 在左侧导航栏中选择 Azure Active Directory,然后选择 应用注册
  3. 点击页面顶部左上角的 新注册 按钮完成应用程序的注册。

Android 配置

版本要求

  • MSAL 版本 4.+

添加网络安全性配置

为了确保 MSAL 4.+ 的正常运行,你需要为 Android 应用添加网络安全性配置文件:

创建 network_security_config.xml

res/xml/network_security_config.xml 文件中添加以下内容:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <debug-overrides>
        <trust-anchors>
            <!-- Trust preinstalled CAs -->
            <certificates src="system" />
            <!-- Trust user added CAs while debuggable only -->
            <certificates src="user" />
        </trust-anchors>
    </debug-overrides>
</network-security-config>

并在 AndroidManifest.xml 中引用该配置文件:

<application
   android:networkSecurityConfig="@xml/network_security_config"

生成重定向 URI

要集成与代理的应用程序,需要生成一个兼容代理的重定向 URI。格式如下:

msauth://yourpackagename/base64urlencodedsignature

你可以使用以下命令生成 Base64 编码的签名哈希:

  • Linux 和 macOS:
keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore | openssl sha1 -binary | openssl base64
  • Windows:
keytool -exportcert -alias androiddebugkey -keystore %HOMEPATH%\.android\debug.keystore | openssl sha1 -binary | openssl base64

然后将此哈希值用于生成重定向 URI,并在 Azure 门户中进行注册。

更新 AndroidManifest.xml

添加以下 <activity> 标签到 AndroidManifest.xml 文件中:

<activity
    android:name="com.microsoft.identity.client.BrowserTabActivity">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data
            android:scheme="msauth"
            android:host="<YOUR_PACKAGE_NAME>"
            android:path="/<YOUR_BASE64_ENCODED_PACKAGE_SIGNATURE>" />
    </intent-filter>
</activity>

build.gradle 配置

确保你的 build.gradle 文件包含正确的签名配置:

signingConfigs {
    debug {
        storeFile file("Keystore/debug.keystore")
        storePassword 'android'
        keyAlias 'androiddebugkey'
        keyPassword 'android'
    }
}

buildTypes {
    release {
        signingConfig signingConfigs.release
    }
    debug {
        signingConfig signingConfigs.debug
    }
}

msal_default_config.json 示例

创建 res/raw/msal_default_config.json 文件,并根据你的应用需求填写以下内容:

{
  "client_id": "xxxxxxxxxxx",
  "authorization_user_agent": "DEFAULT",
  "redirect_uri": "msauth://xxxxxxxxxx/U5rbvBLdFUbEazWhQfDgt6oRa24%3D",
  "account_mode": "MULTIPLE",
  // 其他配置项...
}

iOS 配置

版本要求

  • MSAL 版本 1.2.9
  • 最低支持 iOS 14

添加 URL 类型

Info.plist 文件中添加以下代码以支持重定向 URI:

<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>msauth.$(PRODUCT_BUNDLE_IDENTIFIER)</string>
        </array>
    </dict>
</array>

添加 LSApplicationQueriesSchemes

为了允许调用 Microsoft Authenticator(如果已安装),请添加以下代码:

<key>LSApplicationQueriesSchemes</key>
<array>
    <string>msauthv2</string>
    <string>msauthv3</string>
</array>

macOS 配置

版本要求

  • MSAL 版本 1.2.9

步骤 1:配置应用程序 Info.plist

Info.plist 文件中添加 URI 方案:

<key>CFBundleURLTypes</key>
<array>
  <dict>
    <key>CFBundleURLSchemes</key>
    <array>
      <string>msauth.[app_bundle_id]</string>
    </array>
  </dict>
</array>

步骤 2:配置 Xcode 项目设置

在项目的 Signing & Capabilities 中添加一个新的 Keychain 组。Keychain 组应为 com.microsoft.identity.universalstorage

示例 Demo

下面是一个简单的 Flutter 示例应用,演示如何使用 azure_ad_authentication 插件:

import 'package:azure_ad_authentication/azure_ad_authentication.dart';
import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

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

  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  static const String _authority =
      "https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize";
  static const String _redirectUriMacos = "msauth.msal2794d211-4e3f-4010-9f37-250f928d19c5://auth";
  static const String _clientId = "2794d211-4e3f-4010-9f37-250f928d19c5";

  String _output = 'NONE';
  static const List<String> kScopes = [
    "https://graph.microsoft.com/user.read",
    "https://graph.microsoft.com/Calendars.ReadWrite",
  ];

  Future<void> _acquireToken() async {
    await getResult();
  }

  Future<void> _acquireTokenSilently() async {
    await getResult(isAcquireToken: false);
  }

  Future<String> getResult({bool isAcquireToken = true}) async {
    AzureAdAuthentication pca = await intPca();
    String? res;
    try {
      if (isAcquireToken) {
        var userAdModel = await pca.acquireToken(scopes: kScopes);
        res = userAdModel.toJson().toString();
      } else {
        var userAdModel = await pca.acquireTokenSilent(scopes: kScopes);
        res = userAdModel.toJson().toString();
      }
    } catch (e) {
      res = e.toString();
    }

    setState(() {
      _output = res!;
    });
    return res!;
  }

  Future<AzureAdAuthentication> intPca() async {
    var _redirectUri = Platform.isIOS ? null : _redirectUriMacos;
    return await AzureAdAuthentication.createPublicClientApplication(
        clientId: _clientId, authority: _authority, redirectUri: _redirectUri);
  }

  Future _logout() async {
    AzureAdAuthentication pca = await intPca();
    String res;
    try {
      await pca.logout();
      res = "Account removed";
    } catch (e) {
      res = e.toString();
    }

    setState(() {
      _output = res;
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Plugin example app'),
        ),
        body: SingleChildScrollView(
          child: Center(
            child: Column(
              children: <Widget>[
                Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: ElevatedButton(
                    onPressed: _acquireToken,
                    child: const Text('AcquireToken()'),
                  ),
                ),
                ElevatedButton(
                    onPressed: _acquireTokenSilently,
                    child: const Text('AcquireTokenSilently()')),
                Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: ElevatedButton(
                      onPressed: _logout, child: const Text('Logout')),
                ),
                Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: Text(
                    _output.replaceAll(",", ",\n").replaceAll("{", "{\n").replaceAll("}", "\n}"),
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

以上示例展示了如何初始化插件并调用其方法来获取访问令牌,以及如何处理用户注销操作。请确保根据自己的应用程序需求调整配置文件中的参数。


更多关于Flutter Azure AD 认证插件azure_ad_authentication的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter Azure AD 认证插件azure_ad_authentication的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个使用 azure_ad_authentication 插件在 Flutter 应用中实现 Azure AD 认证的代码示例。这个插件允许你使用 Azure AD 进行用户身份验证。

首先,确保你已经在 pubspec.yaml 文件中添加了 azure_ad_authentication 依赖:

dependencies:
  flutter:
    sdk: flutter
  azure_ad_authentication: ^最新版本号  # 请替换为最新版本号

然后,运行 flutter pub get 来获取依赖。

接下来,你需要在 Azure 门户中注册你的应用,并获取客户端 ID 和租户 ID。确保你已经配置好重定向 URI。

下面是一个完整的 Flutter 应用示例,展示如何使用 azure_ad_authentication 插件进行认证:

import 'package:flutter/material.dart';
import 'package:azure_ad_authentication/azure_ad_authentication.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Azure AD Authentication',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  String? authenticationResult;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Azure AD Authentication'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'Authentication Result:',
              style: TextStyle(fontSize: 20),
            ),
            SizedBox(height: 20),
            Text(
              authenticationResult ?? 'Not Authenticated',
              style: TextStyle(fontSize: 18),
            ),
            SizedBox(height: 40),
            ElevatedButton(
              onPressed: () async {
                // 替换为你的客户端 ID 和租户 ID
                final clientId = 'your-client-id';
                final tenantId = 'your-tenant-id';
                final redirectUri = 'your-redirect-uri'; // 确保这个 URI 在 Azure 门户中注册过

                AzureAdAuthentication azureAdAuth = AzureAdAuthentication(
                  clientId: clientId,
                  tenantId: tenantId,
                  redirectUri: redirectUri,
                );

                try {
                  String result = await azureAdAuth.login();
                  setState(() {
                    authenticationResult = result;
                  });
                } catch (e) {
                  setState(() {
                    authenticationResult = 'Error: ${e.message}';
                  });
                }
              },
              child: Text('Login with Azure AD'),
            ),
          ],
        ),
      ),
    );
  }
}

在这个示例中:

  1. 我们创建了一个简单的 Flutter 应用,包含一个按钮用于触发 Azure AD 登录。
  2. 在按钮的 onPressed 回调中,我们实例化了 AzureAdAuthentication 类,并传入客户端 ID、租户 ID 和重定向 URI。
  3. 调用 azureAdAuth.login() 方法启动认证流程。
  4. 如果认证成功,我们将结果保存在 authenticationResult 状态变量中,并在 UI 中显示。如果认证失败,我们捕获异常并显示错误信息。

请确保你已经正确配置了 Azure AD 应用,并且客户端 ID、租户 ID 和重定向 URI 与你在 Azure 门户中设置的值匹配。此外,你可能需要在 Android 和 iOS 项目中进行一些额外的配置,以便正确处理重定向 URI。

回到顶部