microsoft / aad_b2c_webview Goto Github PK
View Code? Open in Web Editor NEWAzure AD B2C Embedded Webview is a very simple Flutter package that demonstrates how to use the embedded web view to sign in users with Azure AD B2C.
License: MIT License
Azure AD B2C Embedded Webview is a very simple Flutter package that demonstrates how to use the embedded web view to sign in users with Azure AD B2C.
License: MIT License
I would like to know if support for webview_flutter ^4 is on the current roadmap.
If not, can I contribute a new version that supports webview_flutter ^4?
I need MSAL plugin for react native
Hi,
First of all thanks for this library
I have implemented the code given in the example in pubdev. After pressing the button, I am able to receive in the callbacks of the widget (onIDToken and onAnyTokenRetrieved) receiving correctly the token given by B2c auth. The callback onRedirect is also being call correctly and i am able to navigate to another screen (my home screen). My only issue, is that after logging in the browser can't find the redirect url of the schema, the message shown in the browser of the mobile phone after login is: .com.example/authapp://oauthredirect/?code........ could not be loaded because net::ERR_UNKNOWN_URL_SCHEME
I had created (in android) a schema in the manifest adding in the activity tag
<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="com.example.authapp"
android:host="oauthredirect"
/>
</intent-filter>
I tried to handle the url by installing the library uni_links and adding a listener in the main function :
class _MyAppState extends State<MyApp> {
@override
void initState() {
initUniLinks();
// TODO: implement initState
super.initState();
}
void initUniLinks() async {
getInitialLink().then((String? link) {
if (link != null) {
// Handle the link
}
});
linkStream.listen((String? link) {
if (link != null &&
link.startsWith('com.example.authapp://oauthredirect')) {
final Uri uri = Uri.parse(link);
final String code = uri.queryParameters['code']!;
// Now you have the code, proceed with your authentication flow
}
if (link != null) {
// Handle the link
}
}, onError: (err) {
// Handle the error
});
}
But when I debug the code, the breakpoint in the listener (breakpoint in line if (link != null &&
link.startsWith('com.example.authapp://oauthredirect')) ) is never reached.
I am a little bit lost what I need to do in order to show instead of a broken url text a loading progress or something like that during this fraction of second between the the token retrieved and the redirect callback that is sending the user to the home page.
Thanks.
hi there,
I configured and tested the Azure AD B2C setup for Microsoft and Google logins. It worked.
When i use the ADB2CEmbedWebView from my Android code, Microsoft login works, but Google login errors out with “403 disallowed_useragent,”.
On google's support website, it clearly states that "_Embedded WebViews puts your security at risk because they could let third parties access and change communications between you and Google.".
update: 7/3/24 - After enabling Facebook access, get the same message "logging in to Facebook from an embedded browser is disabled".
Does this mean its not a good practice to use Embedded webviews? @mohanajuhi166 would be keen to get your thoughts
Hey @mohanajuhi166 @microsoftopensource I was trying this official flutter package following is my code for azure b2c login.
const aadB2CClientID = 'random-95eb-val-a09b-token';
const aadB2CRedirectURL = 'https://login.live.com/oauth0_desktop.srf';
const aadB2CUserFlowName = 'B2C_1A_signin_Mobile_Dev';
const aadB2CScopes = ['openid', 'offline_access'];
const aadB2TenantName = 'testTenantName';
const aadB2CUserAuthFlow = 'https://<aadB2TenantName>.b2clogin.com/tfp/<aadB2TenantName>.onmicrosoft.com/';
return Scaffold(
body: ADB2CEmbedWebView(
tenantBaseUrl: aadB2CUserAuthFlow,
userFlowName: aadB2CUserFlowName,
clientId: aadB2CClientID,
redirectUrl: aadB2CRedirectURL,
scopes: aadB2CScopes,
onAnyTokenRetrieved: (Token anyToken) {},
onIDToken: (Token token) {
log('idToken==> ${token?.value ?? ''}');
},
onAccessToken: (Token token) {
accessToken = token.value;
log('accessToken==> ${accessToken ?? ''}');
},
onRefreshToken: (Token token) {
refreshToken = token.value;
log('refreshToken==> ${refreshToken ?? ''}');
},
optionalParameters: const [],
onRedirect: (context) {
log('accessToken==> ${accessToken ?? ''}');
log('refreshToken==> ${refreshToken ?? ''}');
return {
// Push user to new screen.
};
},
),
);
The whole flow is working perfectly fine, i'm getting accesstoken and refreshtoken both. So how can I manage the session for this user? How to logout user?
Can you please provide some solution on this?
Thanks.
Hi,
I'm having trouble even getting the very basic demo app to work correctly. The problem I'm having is that I can log in to AAD B2C (and I can see from the network traffic that the tokens are all coming back correctly) via the plugin code provided, but once I'm logged in I get the following error:
I am currently only trying to get the flutter demo counter page hidden behind a login screen. Below is my main.dart file. The only other change I've made is to add manifestPlaceholders += [ appAuthRedirectScheme: 'com.my.app.name' ]
to the defaultConfig section of the /android/app/build.gradle
file.
Any help you could provide would be amazing as we've been going round in circles on this a for a couple of days now.
import 'package:aad_b2c_webview/aad_b2c_webview.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
onRedirect(BuildContext context) {
Navigator.pushNamed(context, '/');
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
initialRoute: '/',
routes: {
'/': (context) => const MyLoginPage(),
'/oauthredirect/': (context) => const MyHomePage(title: 'Flutter Demo Redirect Route')
},
);
}
}
class MyLoginPage extends StatelessWidget {
const MyLoginPage({super.key});
@override
Widget build(BuildContext context) {
const aadB2CClientID = "################################";
const aadB2CRedirectURL = "com.my.app.name://oauthredirect/";
const aadB2CUserFlowName = "B2C_1_MyAppName_Signin";
const aadB2CScopes = ['openid', 'offline_access'];
const aadB2CUserAuthFlow =
"https://<tenantName>.b2clogin.com/<tenantName>.onmicrosoft.com";
const aadB2TenantName = "<tenantName>";
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) {},
optionalParameters: [],
onRedirect: (context) => const MyHomePage(title: 'Flutter Demo On Redirect'),
),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headlineMedium,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
),
);
}
}
Hi, first thanks for creating this library, great work and it's saving some time for us :)
After I tried to implement the web view in my app, I found issues related to it. I will try to explain it in detail and I hope you will not mind because I want to help you improve this package.
So you have the method onPageFinishedTasks(URL, response); that is being called inside of onPageFinished. That method for checking the URL is called only once when the login screen is initially loaded, and that's it. If I input the credentials for login nothing happens, because onPageFinished is calling onPageFinishedTasks(URL, response) only once, and that's the case when the login screen is being loaded.
Further debugging leads me to the conclusion that the right place to call the method onPageFinishedTasks(URL, response); is inside of navigationDelegate property because that field is being triggered every time the user interacts with the screen and tries to log in.
I tried this solution in my app and it's working perfectly, also I have tried your's and it's not working. If you have any questions or maybe I was not clear enough please text me I am open to help :)
Hi,
I've added Google as an identity provider to my Azure Entra instance. Unfortunately I faced the following error message from after trying to sign in via Google.
You'll find the description of the error message here:
https://support.google.com/accounts/answer/12917337?hl=en#403disallowed&zippy=%2Cdisallowed-useragent
It seems like an user agent is missing.
Hey @mohanajuhi166 @microsoftopensource @Baxi19 @Sleeknoah
I was recently wanted to add the feature option to enable keep me signed in feature using microsoft b2c login, But I don't find any support using this package. I've added changes to B2C policy as guided in the following official blog,
https://github.com/azure-ad-b2c/unit-tests/tree/main/session#enable-keep-me-signed-in-kmsi
So can you please help adding support from flutter side keep me signed in feature using this package?
Thanks
Hi guys, i have issue with redirection after login on IOS. Tried different redirect URI's and nothing is happening. In logs on azure I can see that user is successfully log in, but after i click Sign in button nothing is happening. Any idea how to solve redirection issue? Thank you
Thanks for making this useful package.
But I can't use this with flutter 3.0.5
The lower bound of "sdk: '>=2.3.0 <3.0.0'" must be 2.12.0 or higher to enable null safety.
I really want to use this package in my project, is there any solution?
Please let me know how I can contribute to this repository to make this possible.
Hallo everybody,
trying to Login with ADB2CEmbedWebView
using responseType: Constants.default or authCode (which is the same)
throws Dio exception.
responseType: idToken or accessToken works fine.
It comes to my understanding that the authCode is used to implement the UserFlow login and call and extract both idToken and refreshToken.
Thanks in advance and best regards.
[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: DioException [bad response]: This exception was thrown because the response has a status code of 400 and RequestOptions.validateStatus was configured to throw for this status code. E/flutter (11937): The status code of 400 has the following meaning: "Client error - the request contains bad syntax or cannot be fulfilled" E/flutter (11937): Read more about status codes at https://developer.mozilla.org/en-US/docs/Web/HTTP/Status E/flutter (11937): In order to resolve this exception you typically have either to verify and fix your request code or you have to fix the server code. E/flutter (11937): E/flutter (11937): #0 DioMixin.fetch.<anonymous closure> (package:dio/src/dio_mixin.dart:507:7) E/flutter (11937): #1 _FutureListener.handleError (dart:async/future_impl.dart:180:22) E/flutter (11937): #2 Future._propagateToListeners.handleError (dart:async/future_impl.dart:858:47) E/flutter (11937): #3 Future._propagateToListeners (dart:async/future_impl.dart:879:13) E/flutter (11937): #4 Future._completeError (dart:async/future_impl.dart:655:5) E/flutter (11937): #5 _SyncCompleter._completeError (dart:async/future_impl.dart:63:12) E/flutter (11937): #6 _Completer.completeError (dart:async/future_impl.dart:27:5) E/flutter (11937): #7 Future.any.onError (dart:async/future.dart:618:45) E/flutter (11937): #8 _RootZone.runBinary (dart:async/zone.dart:1666:54) E/flutter (11937): #9 _FutureListener.handleError (dart:async/future_impl.dart:177:22) E/flutter (11937): #10 Future._propagateToListeners.handleError (dart:async/future_impl.dart:858:47) E/flutter (11937): #11 Future._propagateToListeners (dart:async/future_impl.dart:879:13) E/flutter (11937): #12 Future._completeError (dart:async/future_impl.dart:655:5) E/flutter (11937): #13 Future._asyncCompleteError.<anonymous closure> (dart:async/future_impl.dart:745:7) E/flutter (11937): #14 _microtaskLoop (dart:async/schedule_microtask.dart:40:21) E/flutter (11937): #15 _startMicrotaskLoop (dart:async/schedule_microtask.dart:49:5) E/flutter (11937):
I am always getting access token as null, I can able to get IDToken and RefreshToken.
Could you please assist to resolve this issue
Good evening,
I was using the 0.0.51 version and it works fine on Android.
To make it work on iOS I had to upgrade it but now the same stopped working on Android.
After some tests I noticed iOS starts working after version 0.0.53 while Andrid stops working after 0.0.51
My implementation is pretty much linear
return ADB2CEmbedWebView( loadingReplacement: const Loading(), optionalParameters: const [], tenantBaseUrl: aadB2CUserAuthFlow, userFlowName: aadB2CUserFlowName, clientId: aadB2CClientID, redirectUrl: aadB2CRedirectURL, onRedirect: (context) => Loading.modalLoading(), scopes: aadB2CScopes, onAnyTokenRetrieved: (Token anyToken) { ... }, onIDToken: (Token token) { ... }, onAccessToken: (Token token) { ... }, onRefreshToken: (Token token) { ... }, );
Debugging inside the library the errors seems to be the following:
Response ({"error":"invalid_request","error_description":"AADB2C90117: The scope 'openid%20offline_access%20profile%20https://myWebSite.onmicrosoft.com/exm.be.webapi/access_as_user' provided in the request is not supported.\r\nCorrelation ID: 53dc1c3f-a814-428c-8adf-a3153d5eb8b3\r\nTimestamp: 2024-03-07 13:24:06Z\r\n"})
It's strange the scopes are the problem, because on iOS the login is working fine and on Android it's working until 0.0.52
Do I have to modify something when upgrading over 0.0.51 for Android to work?
I'm getting the resource you are looking for has been removed, had its name changed, or is temporarily unavailable on Android.
Dear Microsoft team
Is there any plan to release iOS platform support ?
Thank you
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.