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

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

Azure Active Directory OAuth

这个Flutter插件用于通过Azure Active Directory的OAuth2 v2.0端点进行用户认证。它支持授权码流(包括刷新令牌流)。

使用方法

要使用这个库,你需要在Azure应用注册门户创建一个Azure应用程序。使用本地应用作为平台类型(回调URL为https://login.live.com/oauth20_desktop.srf)。

初始化库的方式如下:

final Config config = Config(
        azureTenantId: "$TENANT_ID", // 租户ID
        clientId: "$CLIENT_ID",       // 客户端ID
        scope: "$scope",              // 作用域
        redirectUri: "$redirectUri",  // 重定向URI
        responseType: "$responseType" // 响应类型
);
final AadOAuth oauth = AadOAuth(config);

这允许你传入租户ID、客户端ID、作用域和重定向URL。

四个重要事项:
  1. 移动端的响应类型通常是"code",而Web端通常是"id_token + token";
  2. Flutter Web的重定向URI解释如下。
  3. nonce是Web流程的一个可选参数。
  4. 为了保存多个令牌,需要在FlutterAadOauth构造函数中传递tokenIdentifier。该参数用于定义存储中的不同名称,避免覆盖数据。

然后,一旦你有一个OAuth实例,你可以调用login()并随后调用getAccessToken()getIdToken()getRefreshToken()来检索访问令牌或ID令牌或刷新令牌:

await oauth.login(); // 登录
String accessToken = await oauth.getAccessToken(); // 获取访问令牌
String idToken = await oauth.getIdToken(); // 获取ID令牌
String refreshToken = await oauth.getRefreshToken(); // 获取刷新令牌
String tokenType = await oauth.getTokenType(); // 获取令牌类型
DateTime issueTimeStamp = await oauth.getIssueTimeStamp(); // 获取发行时间戳
DateTime expireTimeStamp = await oauth.getExpireTimeStamp(); // 获取过期时间戳
int expiresIn = await oauth.getExpiresIn(); // 获取令牌过期时间

你也可以直接调用getAccessToken()getIdToken()getRefreshToken()getTokenType()getIssueTimeStamp()getExpireTimeStamp()getExpiresIn()。它们会自动登录并检索相应的令牌信息。

令牌存储在iOS的Keychain或Android的Keystore中。要销毁令牌,可以调用logout()

await oauth.logout(); // 注销

Flutter Web

要在Flutter Web上实现认证流程,有以下步骤:

  1. 项目必须在根目录下有一个web文件夹(Flutter 2.0);
  2. 在此文件夹内需要创建authRedirect.html文件,作为请求令牌时的重定向页面。这个HTML文件需要包含一个带有POST方法的脚本,如下所示:
<script>
    window.opener.postMessage(window.location.href, '*');
</script>
  1. 重定向URL必须预先在Azure中注册,因此应用程序必须始终在同一端口上运行。为此只需在flutter run中使用--web-port=3000标志,或在launch.json文件(VsCode)中添加args,如下所示:
"args": ["--web-port", "3000"],
  1. 在这个包的仓库中,有一个示例文件夹,包含一个使用此库进行移动和Web身份验证的Flutter项目。
获取重定向URI的示例:
final currentUri = Uri.base;
redirectUri = Uri(
  host: currentUri.host,
  scheme: currentUri.scheme,
  port: currentUri.port,
  path: '/authRedirect.html',
);

Flutter Web支持基于这篇文章。

完整示例Demo

以下是完整的Flutter应用示例代码:

import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:flutter/material.dart';
import 'package:flutter_aad_oauth/flutter_aad_oauth.dart';
import 'package:flutter_aad_oauth/model/config.dart';

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

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

  [@override](/user/override)
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  [@override](/user/override)
  initState() {
    super.initState();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'AAD OAuth Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'AAD OAuth Home'),
    );
  }
}

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

  [@override](/user/override)
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  static const String TENANT_ID = 'YOUR_TENANT_ID'; // 替换为你的租户ID
  static const String CLIENT_ID = 'YOUR_CLIENT_ID'; // 替换为你的客户端ID

  late Config config;
  late FlutterAadOauth oauth = FlutterAadOauth(config);

  [@override](/user/override)
  initState() {
    Object redirectUri;
    late String scope;
    late String responseType;

    if (kIsWeb) {
      scope = 'openid profile email offline_access user.read';
      responseType = 'id_token+token';
      final currentUri = Uri.base;
      redirectUri = Uri(
        host: currentUri.host,
        scheme: currentUri.scheme,
        port: currentUri.port,
        path: '/authRedirect.html',
      );
    } else {
      scope = 'openid profile offline_access';
      responseType = 'code';
      redirectUri = 'https://login.live.com/oauth20_desktop.srf';
    }

    config = Config(
        azureTenantId: TENANT_ID,
        clientId: CLIENT_ID,
        scope: scope,
        redirectUri: '$redirectUri',
        responseType: responseType);

    oauth = FlutterAadOauth(config);
    oauth.setContext(context);
    checkIsLogged();
    super.initState();
  }

  [@override](/user/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.headline5,
            ),
          ),
          ListTile(
            leading: const Icon(Icons.launch),
            title: const Text('Login'),
            onTap: () {
              login();
            },
          ),
          ListTile(
            leading: const Icon(Icons.delete),
            title: const Text('Logout'),
            onTap: () {
              logout();
            },
          ),
        ],
      ),
    );
  }

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

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

  void checkIsLogged() async {
    if (await oauth.tokenIsValid()) {
      String? accessToken = await oauth.getAccessToken();
      showMessage('Access token: $accessToken');
    }
  }

  void login() async {
    try {
      await oauth.login(); // 登录
      String? accessToken = await oauth.getAccessToken(); // 获取访问令牌
      showMessage('Logged in successfully, your access token: $accessToken');
    } catch (e) {
      showError(e);
    }
  }

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

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

1 回复

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


当然,我可以为你提供一个关于如何使用 flutter_aad_oauth 插件进行 Azure AD OAuth 认证的代码案例。这个插件可以帮助你在 Flutter 应用中实现 Azure AD 的 OAuth 2.0 认证。

首先,你需要在你的 pubspec.yaml 文件中添加这个插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_aad_oauth: ^x.y.z  # 请替换为最新版本号

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

接下来,你需要在 Azure 门户中注册你的应用,并获取必要的客户端 ID 和重定向 URI。确保在 Azure AD 应用注册中配置正确的重定向 URI,它通常看起来像这样:msauth://<your_package_name>/<your_redirect_signature>

下面是一个简单的 Flutter 应用示例,演示如何使用 flutter_aad_oauth 进行 Azure AD OAuth 认证:

import 'package:flutter/material.dart';
import 'package:flutter_aad_oauth/flutter_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 _authToken = '';

  @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(
              'Auth Token:',
            ),
            Text(
              _authToken,
              style: TextStyle(fontSize: 20),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () async {
                // Replace these with your actual Azure AD client ID and tenant ID
                String clientId = 'your-client-id';
                String tenantId = 'your-tenant-id';
                String redirectUri = 'msauth://your.package.name/YOUR_SIGNATURE';

                final result = await FlutterAadOauth.authenticate(
                  clientId: clientId,
                  tenant: tenantId,
                  redirectUri: redirectUri,
                  scopes: ['User.Read'],  // The scopes you need
                );

                if (result != null && result.isAuthenticated) {
                  setState(() {
                    _authToken = result.accessToken;
                  });
                } else {
                  setState(() {
                    _authToken = 'Authentication failed';
                  });
                }
              },
              child: Text('Login with Azure AD'),
            ),
          ],
        ),
      ),
    );
  }
}

在这个示例中,我们创建了一个简单的 Flutter 应用,它有一个按钮用于启动 Azure AD OAuth 认证流程。用户成功登录后,将显示访问令牌。

注意事项

  1. 确保你在 Azure AD 应用注册中配置了正确的重定向 URI。
  2. 在实际使用中,请替换 clientIdtenantIdredirectUri 为你自己的值。
  3. 根据你的需求调整 scopes 列表。

这个示例提供了一个基本的框架,你可以根据需要进行扩展和自定义。

回到顶部