Flutter Azure AD B2C认证插件aad_b2c_webview的使用

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

Flutter Azure AD B2C认证插件aad_b2c_webview的使用

Azure AD B2C Embedded Webview 是一个非常简单的Flutter包,用于展示如何使用嵌入式web视图通过Azure AD B2C登录用户。目前使用的Flutter包如flutter_appauthflutter_azure_b2c会重定向到浏览器,并不提供应用内体验。该包使用flutter_appview嵌入用户流端点的web视图,并根据onRedirect回调方法重定向用户。

特性

  • 提供应用内的Azure AD B2C嵌入式web视图体验。
  • 在成功登录后重定向到指定的路由。
  • 使用flutter secure storage安全地存储id令牌或访问令牌。
  • 登录成功后导航到应用程序中的屏幕。

入门指南

要在Flutter应用中使用此包,请在main.dart文件中添加以下依赖:

dependencies:
  aad_b2c_webview: <latest_version>

使用示例

简单内置登录按钮

要添加易于使用的微软登录按钮,只需使用AADLoginButton小部件,就会显示一个漂亮的登录按钮。

首先,在/android/app/src/main/AndroidManifest.xml中添加以下内容:

<meta-data android:name="flutter_deeplinking_enabled" android:value="true" />
<intent-filter android:autoVerify="true">
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="https" android:host="myurl.com" />
</intent-filter>

更改Flutter代码中的重定向URL为https://myurl.com/myappname,并在Azure AD B2C项目中添加此作为重定向URL。

更新后的main.dart文件如下所示:

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

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

onRedirect(BuildContext context) {
  Navigator.of(context).pushNamedAndRemoveUntil('/myappname', (Route<dynamic> route) => false);
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primaryColor: const Color(0xFF2F56D2),
        textTheme: const TextTheme(
          headlineLarge: TextStyle(
            color: Colors.black,
            fontSize: 32,
            fontWeight: FontWeight.w700,
            fontFamily: 'UberMove',
          ),
          bodyLarge: TextStyle(
            color: Color(0xFF8A8A8A),
            fontSize: 17,
            fontWeight: FontWeight.w400,
            fontFamily: 'UberMoveText',
          ),
          displayMedium: TextStyle(
            fontSize: 18,
            color: Colors.black,
            fontWeight: FontWeight.w700,
            fontFamily: 'UberMove',
          ),
        ),
      ),
      debugShowCheckedModeBanner: false,
      initialRoute: '/',
      routes: {
        '/': (context) => const LoginPage(),
        '/myappname': (context) => const CounterDemo(),
      },
    );
  }
}

class LoginPage extends StatefulWidget {
  const LoginPage({super.key});

  @override
  State<LoginPage> createState() => _LoginPageState();
}

class _LoginPageState extends State<LoginPage> {
  String? jwtToken;
  String? refreshToken;

  @override
  Widget build(BuildContext context) {
    const aadB2CClientID = "<app-id>";
    const aadB2CRedirectURL = "https://myurl.com/myappname";
    const aadB2CUserFlowName = "B2C_1_APPNAME_Signin";
    const aadB2CScopes = ['openid', 'offline_access'];
    const aadB2TenantName = "<tenantName>";
    const aadB2CUserAuthFlow =
        "https://$aadB2TenantName.b2clogin.com/$aadB2TenantName.onmicrosoft.com";

    return Scaffold(
      appBar: AppBar(
        title: const Text("AAD B2C Login"),
        backgroundColor: const Color(0xFF2F56D2)
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            AADLoginButton(
              userFlowUrl: aadB2CUserAuthFlow,
              clientId: aadB2CClientID,
              userFlowName: aadB2CUserFlowName,
              redirectUrl: aadB2CRedirectURL,
              context: context,
              scopes: aadB2CScopes,
              onAnyTokenRetrieved: (Token anyToken) {},
              onIDToken: (Token token) {
                jwtToken = token.value;
              },
              onAccessToken: (Token token) {},
              onRefreshToken: (Token token) {
                refreshToken = token.value;
              },
              onRedirect: (context) => onRedirect(context),
            ),
            TextButton(
              onPressed: () async {
                if (refreshToken != null) {
                  AzureTokenResponse? response =
                      await ClientAuthentication.refreshTokens(
                    refreshToken: refreshToken!,
                    tenant: aadB2TenantName,
                    policy: aadB2CUserAuthFlow,
                    clientId: aadB2CClientID,
                  );
                  if (response != null) {
                    refreshToken = response.refreshToken;
                    jwtToken = response.idToken;
                  }
                }
              },
              child: const Text("Refresh my token"),
            ),
            TextButton(
              onPressed: () async {
                Navigator.pushNamed(context, '/myappname');
              },
              child: const Text("Go To Counter Demo"),
            )
          ],
        ),
      ),
    );
  }
}

自定义登录

可以简单调用页面直接或使用自定义构建的登录按钮来调用web视图页面:

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

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

  @override
  Widget build(BuildContext context) {
    const aadB2CClientID = "<clientId>";
    const aadB2CRedirectURL = "<azure_active_directory_url_redirect>";
    const aadB2CUserFlowName = "B2C_<name_of_userflow>";
    const aadB2CScopes = ['openid', 'offline_access'];
    const aadB2CUserAuthFlow =
        "https://<tenant-name>.b2clogin.com/<tenant-name>.onmicrosoft.com"; 
    const aadB2TenantName = "<tenant-name>";

    return Scaffold(
      body: ADB2CEmbedWebView(
        tenantBaseUrl: aadB2CUserAuthFlow,
        userFlowName: aadB2CUserFlowName,
        clientId: aadB2CClientID,
        redirectUrl: aadB2CRedirectURL,
        scopes: aadB2CScopes,
        onAnyTokenRetrieved: (Token anyToken) {},
        onIDToken: (Token token) {},
        onAccessToken: (Token token) {},
        onRefreshToken: (Token token) {},
      ),
    );
  }
}

发送可选参数

AADLoginButton小部件中,可以通过optionalParameters参数发送可选参数来定制URL。例如:

optionalParameters: [
  OptionalParam(key: "parameter1", value: "value1"),
  OptionalParam(key: "parameter2", value: "value2"),
],

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

1 回复

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


当然,以下是一个关于如何在Flutter应用中使用aad_b2c_webview插件来实现Azure AD B2C认证的示例代码。这个插件允许你通过嵌入式WebView来完成认证流程,非常适合在移动应用中集成Azure AD B2C。

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

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

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

接下来,在你的Flutter应用中配置和使用aad_b2c_webview插件。以下是一个基本的实现步骤和代码示例:

  1. 配置Azure AD B2C信息

在你的Flutter项目中创建一个配置文件(例如config.dart),用于存储Azure AD B2C的相关信息:

// config.dart
class AzureADB2CConfig {
  static const String tenantId = 'your-tenant-id';
  static const String clientId = 'your-client-id';
  static const String policyName = 'your-sign-up-or-sign-in-policy';
  static const String authority = 'https://${tenantId}.b2clogin.com/${tenantId}.onmicrosoft.com/${policyName}';
  static const String redirectUri = 'your-redirect-uri'; // 确保与Azure AD B2C注册的一致
}
  1. 创建认证流程

在你的主应用文件(例如main.dart)中,使用aad_b2c_webview插件来启动认证流程:

import 'package:flutter/material.dart';
import 'package:aad_b2c_webview/aad_b2c_webview.dart';
import 'config.dart';

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

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

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

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

  void _startAuthentication() async {
    try {
      final result = await AADB2CWebView.authenticate(
        tenantId: AzureADB2CConfig.tenantId,
        clientId: AzureADB2CConfig.clientId,
        authority: AzureADB2CConfig.authority,
        redirectUri: AzureADB2CConfig.redirectUri,
        scopes: ['openid', 'offline_access'], // 根据需要调整
      );

      if (result != null) {
        setState(() {
          accessToken = result.accessToken;
        });
        print('Access Token: $accessToken');
      } else {
        print('Authentication failed or canceled.');
      }
    } catch (e) {
      print('Error: $e');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Azure AD B2C Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              accessToken ?? 'No Access Token',
              style: TextStyle(fontSize: 20),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _startAuthentication,
              child: Text('Authenticate'),
            ),
          ],
        ),
      ),
    );
  }
}

在上面的代码中,我们定义了一个简单的Flutter应用,其中包含一个按钮用于启动Azure AD B2C认证流程。认证成功后,将访问令牌存储在accessToken变量中,并在屏幕上显示。

  1. 运行应用

确保你已经正确配置了Azure AD B2C应用,并将必要的重定向URI添加到了Azure门户中。然后,运行你的Flutter应用,点击“Authenticate”按钮即可启动认证流程。

这个示例展示了如何在Flutter应用中使用aad_b2c_webview插件进行Azure AD B2C认证。根据实际需求,你可能需要调整认证策略、作用域等配置。

回到顶部