Flutter Azure AD OAuth认证插件aad_oauth的使用

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

Flutter Azure AD OAuth认证插件aad_oauth的使用

Azure Active Directory OAuth

pub package License: MIT style: effective dart pub points Join the chat

Flutter OAuth包用于对Azure Active Directory OAuth2 v2.0端点执行用户身份验证。它派生自hitherejoe.FlutterOAuth

支持的身份验证流程包括:

使用方法

准备工作

  1. 创建Azure应用程序:您需要在Azure App注册门户上创建一个Azure应用程序,并选择原生应用作为平台类型,回调URL设置为https://login.live.com/oauth20_desktop.srf
  2. 配置Android环境:确保您的android/app/build.gradle文件中的minSdkVersion >= 20以支持webview_flutter。如果您的应用程序没有android.permission.INTERNET权限,请将其添加到AndroidManifest.xml中。
    <uses-permission android:name="android.permission.INTERNET"/>
    

初始化配置

final navigatorKey = GlobalKey<NavigatorState>();

static final Config config = Config(
  tenant: "YOUR_TENANT_ID",
  clientId: "YOUR_CLIENT_ID",
  scope: "openid profile offline_access",
  redirectUri: "your redirect url available in azure portal",
  navigatorKey: navigatorKey,
  webUseRedirect: true, // default is false - on web only, forces a redirect flow instead of popup auth
  loader: Center(child: CircularProgressIndicator()),
  postLogoutRedirectUri: 'http://your_base_url/logout', //optional
);

final AadOAuth oauth = AadOAuth(config);

配置MaterialApp

确保在MaterialApp中使用相同的navigatorKey以支持导航到登录路由进行交互式身份验证。

return MaterialApp(
  navigatorKey: navigatorKey,
  // ...
);

登录和获取访问令牌

final result = await oauth.login();
result.fold(
  (failure) => showError(failure.toString()),
  (token) => showMessage('Logged in successfully, your access token: $token'),
);
String accessToken = await oauth.getAccessToken();

注销

await oauth.logout();

Web使用说明

对于Web应用,您还需要在index.html中添加以下代码:

<head>
  <script type="text/javascript" src="https://alcdn.msauth.net/browser/2.13.1/js/msal-browser.min.js"
    integrity="sha384-2Vr9MyareT7qv+wLp1zBt78ZWB4aljfCTMUrml3/cxm0W81ahmDOC6uyNmmn0Vrc"
    crossorigin="anonymous"></script>
  <script src="assets/packages/aad_oauth/assets/msalv2.js"></script>
</head>

注意:当使用重定向流时,login()调用不会返回,因为页面被重定向且应用程序被销毁,直到登录完成。您的应用程序必须在重新加载后再次调用login()以完成登录过程。

B2C使用说明

  1. 设置B2C目录:Azure AD B2C Setup
  2. 注册应用程序:Azure AD B2C App Register
  3. 创建用户流:Azure AD B2C User Flows
  4. 配置main.dart中的参数:
    static final Config configB2Ca = Config(
      tenant: "YOUR_TENANT_NAME",
      clientId: "YOUR_CLIENT_ID",
      scope: "YOUR_CLIENT_ID offline_access",
      isB2C: true,
      policy: "YOUR_USER_FLOW___USER_FLOW_A",
      tokenIdentifier: "UNIQUE IDENTIFIER A",
      navigatorKey: navigatorKey,
    );
    

ADFS使用说明

此库仅支持Flutter移动应用程序的ADFS身份验证,不支持Web构建。

  1. 注册ADFS应用程序:Windows Server ADFS Application Setup
  2. 使用重定向URI:https://login.live.com/oauth20_desktop.srf
  3. 配置示例:
    static final Config adfsAuthConfig = Config(
      customAuthorizationUrl: 'https://adfs.your-domain.com/adfs/oauth2/authorize',
      customTokenUrl: 'https://adfs.your-domain.com/adfs/oauth2/token',
      clientId: 'YOUR_CLIENT_ID',
      scope: 'openid OTHER_SCOPES_YOU_NEED',
      navigatorKey: navigatorKey,
      loader: const SizedBox(),
    );
    

安装

将以下内容添加到pubspec.yaml的依赖项中:

dependencies:
  aad_oauth: "^0.4.4"

示例代码

以下是完整的示例代码:

import 'dart:developer';

import 'package:aad_oauth/aad_oauth.dart';
import 'package:aad_oauth/model/config.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

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

final navigatorKey = GlobalKey<NavigatorState>();

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'AAD OAuth Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'AAD OAuth Home'),
      navigatorKey: navigatorKey,
    );
  }
}

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

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

class _MyHomePageState extends State<MyHomePage> {
  static final Config config = Config(
    tenant: 'YOUR_TENANT_ID',
    clientId: 'YOUR_CLIENT_ID',
    scope: 'openid profile offline_access',
    navigatorKey: navigatorKey,
    loader: SizedBox(),
    appBar: AppBar(
      title: Text('AAD OAuth Demo'),
    ),
    onPageFinished: (String url) {
      log('onPageFinished: $url');
    },
  );
  final AadOAuth oauth = AadOAuth(config);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: ListView(
        children: <Widget>[
          ListTile(
            title: Text(
              'AzureAD OAuth',
              style: Theme.of(context).textTheme.headlineSmall,
            ),
          ),
          ListTile(
            leading: Icon(Icons.launch),
            title: Text('Login${kIsWeb ? ' (web popup)' : ''}'),
            onTap: () {
              login(false);
            },
          ),
          if (kIsWeb)
            ListTile(
              leading: Icon(Icons.launch),
              title: Text('Login (web redirect)'),
              onTap: () {
                login(true);
              },
            ),
          ListTile(
            leading: Icon(Icons.data_array),
            title: Text('HasCachedAccountInformation'),
            onTap: () => hasCachedAccountInformation(),
          ),
          ListTile(
            leading: Icon(Icons.logout),
            title: Text('Logout'),
            onTap: () {
              logout();
            },
          ),
        ],
      ),
    );
  }

  void showError(dynamic ex) {
    showMessage(ex.toString());
  }

  void showMessage(String text) {
    var alert = AlertDialog(content: Text(text), actions: <Widget>[
      TextButton(
          child: const Text('Ok'),
          onPressed: () {
            Navigator.pop(context);
          })
    ]);
    showDialog(context: context, builder: (BuildContext context) => alert);
  }

  void login(bool redirect) async {
    config.webUseRedirect = redirect;
    final result = await oauth.login();
    result.fold(
      (l) => showError(l.toString()),
      (r) => showMessage('Logged in successfully, your access token: $r'),
    );
    var accessToken = await oauth.getAccessToken();
    if (accessToken != null) {
      ScaffoldMessenger.of(context).hideCurrentSnackBar();
      ScaffoldMessenger.of(context)
          .showSnackBar(SnackBar(content: Text(accessToken)));
    }
  }

  void hasCachedAccountInformation() async {
    var hasCachedAccountInformation = await oauth.hasCachedAccountInformation;
    ScaffoldMessenger.of(context).hideCurrentSnackBar();
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        content: Text('HasCachedAccountInformation: $hasCachedAccountInformation'),
      ),
    );
  }

  void logout() async {
    await oauth.logout();
    showMessage('Logged out');
  }
}

通过以上步骤和示例代码,您可以实现基于Flutter的Azure AD OAuth认证功能。希望这对您有所帮助!如果有任何问题或需要进一步的帮助,请随时提问。


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

1 回复

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


在Flutter项目中集成Azure AD OAuth认证,可以使用aad_oauth插件。下面是一个基本的代码示例,展示了如何使用这个插件来进行Azure AD的OAuth认证。

1. 添加依赖

首先,在你的pubspec.yaml文件中添加aad_oauth依赖:

dependencies:
  flutter:
    sdk: flutter
  aad_oauth: ^x.y.z  # 请使用最新版本号替换x.y.z

然后运行flutter pub get来安装依赖。

2. 配置插件

你需要配置一些必要的参数,比如你的Azure AD客户端ID、租户ID、重定向URI等。这些通常可以在Azure门户的App注册中找到。

3. 编写认证代码

以下是一个简单的示例,展示了如何使用aad_oauth插件进行认证:

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

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

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

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

class _MyHomePageState extends State<MyHomePage> {
  String? accessToken;
  String? errorMessage;

  void _performOAuth() async {
    // 配置Azure AD OAuth参数
    final aadOAuth = AadOAuth(
      clientId: 'your-client-id',
      tenant: 'your-tenant-id',
      redirectUri: 'your-redirect-uri',
      scopes: ['openid', 'profile', 'offline_access'],  // 根据需要添加scope
    );

    try {
      // 执行OAuth认证
      final result = await aadOAuth.login();
      if (result != null) {
        setState(() {
          accessToken = result.accessToken;
          errorMessage = null;
        });
      }
    } catch (e) {
      setState(() {
        accessToken = null;
        errorMessage = e.toString();
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Azure AD OAuth Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'Access Token: ${accessToken ?? 'N/A'}',
              style: TextStyle(fontSize: 18),
            ),
            SizedBox(height: 20),
            if (errorMessage != null)
              Text(
                'Error: $errorMessage',
                style: TextStyle(color: Colors.red, fontSize: 16),
              ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _performOAuth,
              child: Text('Login with Azure AD'),
            ),
          ],
        ),
      ),
    );
  }
}

4. 注意事项

  • 确保你的Azure AD应用注册中的重定向URI与你在代码中配置的一致。
  • 你可以根据需要在scopes参数中添加更多的权限。
  • 处理用户认证结果时,确保你的应用能够安全地存储和使用访问令牌。

这个示例展示了如何使用aad_oauth插件在Flutter应用中集成Azure AD OAuth认证。你可以根据实际需求对代码进行扩展和修改。

回到顶部