Flutter: Authentication with Azure AD B2C returns result but with empty accesstoken - flutter

I try to build a Flutter app with Azure B2C authentication. To achive this I use the Flutter App Auth Plugin. At first sight everything seems to work as expected, but when I looked at the result the accesstoken is null. What am I missing? Obviously, I can get a connection to Azure and after entering the credentials a result is send back to my app. But why without token?
Debug session of the result:
Debug session of the result
My configuration:
configuration
I call the method like this:
Future<void> _login() async{
AuthorizationTokenResponse result;
try{
result = await _appauth.authorizeAndExchangeCode(
AuthorizationTokenRequest(_clientId, _redirectUrl,
discoveryUrl: _discoveryUrl,
scopes: _scopes),
);
}
catch(e){
print(e.toString());
}
if (result != null) {
_processAuthTokenResponse(result);
}
}
Does anybody know what I forgot?
Thanks!

You aren’t giving a scope to a resource so you don’t get an access token.
https://learn.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-access-tokens

Related

How to have multiple providers for one account?

Introduce the problem
I use an email to log in.
If I log out and try to log in to the same email using Google, the UID of the account changes. I can't change back to the old UID. How can I provide multiple providers for an account?
What I tried
I asked this question to ChatGPT but it didn't answer my question. I also googled this problem.
I have read this documentation and used its code, but it didn't work. Not sure if I'm using its code correctly.
I've read this question but it didn't help me.
A minimal, reproducible example
Future<void> signInWithEmailAndPassword(String email, String password) async {
try {
await firebaseAuth.signInWithEmailAndPassword(email: email, password: password);
final credential = EmailAuthProvider.credential(email: email, password: password);
await FirebaseAuth.instance.currentUser?.linkWithCredential(credential);
} on FirebaseAuthException catch (e) {
throw FirebaseAuthException(code: e.code, message: e.message);
}
}
You should be able to achieve this via the Firebase Console. The Firebase Authentication Settings tab allows you to link accounts with the same email.
https://console.firebase.google.com/u/0/project/yourprojectname/authentication/settings
Account linking works by first having a currently signed in user, and then linking an additional provider to it. In steps:
Sign in with the existing provider.
Check that currentUser isn't null.
Create credentials for the additional provider
Link the additional provider to the existing account by calling linkWithCredential.

my flutter app doesn't open authentication link

I am using firebase authentication and facebook authentication to facilitate users auth.
But when I click the button for face book auth it stops loading and nothing happens.
and in the release mode the link doesn't open.
I have tried all youtube videos to make facebook auth work.
This is my source code:
Future<UserCredential> signInWithFacebook() async {
// Trigger the sign-in flow
final LoginResult loginResult = await FacebookAuth.instance.login();
// Create a credential from the access token
final OAuthCredential facebookAuthCredential =
FacebookAuthProvider.credential(loginResult.accessToken!.token);
// Once signed in, return the UserCredential
return _auth.signInWithCredential(facebookAuthCredential);
}
Facebook have already updated their api for signin options.
try reading this links it might help
ff:
[https://pub.dev/packages/flutter_facebook_auth]
[https://medium.com/flutter-community/flutter-facebook-login-77fcd187242]
![and also for the fb api i have use a webview to fetch it and send the request to the post]

How do I fix an "Unable to parse JWT" error on Identity Aware Proxy?

I am trying to use a cloud run endpoint through GCP's Identity Aware Proxy and all of a sudden the IAP endpoint started throwing an error:
Invalid IAP credentials: Unable to parse JWT
I am using the extension_google_sign_in_as_googleapis_auth extension to create a Google client out of my existing Google/Firebase login.
The IAP works fine if I access the api with the browser directly (using the same GCP credentials directly as I am logged into the app with)
I am using the following code, which seems to be connecting to the backend: I see the network inspector fire the CORS head and then the call to the endpoint. The first is fine, the second errors with a 401 and the message above in the body.
getIAPAPI(String path) async {
Uri uri;
// make sure the Identity Aware Proxy is addressed authenticated
var _signIn = GoogleSignIn(
scopes: <String>[CloudIAPApi.cloudPlatformScope],
);
await _signIn.signInSilently();
// create a GCP client
final _client = await _signIn.authenticatedClient();
print('fetching ${path} from api');
try {
uri = Uri.https('iapapi.example.com', path);
var response = await _client?.get(uri);
return response?.body;
} catch (e) {
// print errors and pass back an empty json result
print(e);
return "{}";
}
}
Am I doing something wrong in my code? The really weird thing is that it seemed to work a week ago. I don't see anything in the IAP console settings that could help either.

How to sign a Azure AD user into Firebase in a Flutter mobile app?

For a Flutter mobile app I am trying to use a Microsoft OAuthProvider to get a Firebase credential with which to sign the user into Firebase with their Azure AD account.
The closest I got was using a third party Active Directory auth package to log the user in and get an access token. However the sign-in to Firebase fails with an error message that suggests the idToken is invalid.
final AadOAuth oauth = new AadOAuth(config);
await oauth.login();
// accessToken looks legit
String accessToken = await oauth.getAccessToken();
String idToken = await oauth.getIdToken();
OAuthProvider provider = OAuthProvider('microsoft.com');
// Also tried the constructor without the idToken
OAuthCredential credential = provider.credential(accessToken: accessToken, idToken: idToken);
// app fails here:
await FirebaseAuth.instance.signInWithCredential(credential);
// this works fine, but only on web platform:
await FirebaseAuth.instance.signInWithPopup(provider);
Because it is a platform specific error (iOS in this case), the exception details are not surfaced. All I get is:
PlatformException(internal-error, ) nativeErrorCode: 17999
Here is my app settings in the Azure portal:
Full manifest here
Has anyone been successful in using Microsoft Auth to sign a user in to Firebase in a Flutter mobile app?
You can use Firebase Auth OAuth package for it.
And sign in to the firebase using the Microsoft Auth provider.
User user = await FirebaseAuthOAuth().openSignInFlow(
"microsoft.com", ["email openid"], {'tenant': 'your-tenent-id'});
This integrates nicely with firebase so, firebase authStateChange also works with this method.
You have just to not receiving idToken, just verify that you have add the id_token for the response_type and also openid scope like
provider.addScope('openid');
Also check weather you have allowed implicit flow with id token in the Azure portal app settings (you sould check ID tokens on the Authentication tab under Implicit grant section).
Ok than have you added Microsoft as a authentication provider in the firebase authentication configuration Sign-in method page? And also have you tried to authenticate with Auth, after getCredentials method as stated in the documentation?
provider.getCredentialWith(nil) { credential, error in
if error != nil {
// Handle error.
}
if credential != nil {
Auth().signIn(with: credential) { authResult, error in
if error != nil {
// Handle error.
}
// User is signed in.
// IdP data available in authResult.additionalUserInfo.profile.
// OAuth access token can also be retrieved:
// authResult.credential.accessToken
// OAuth ID token can also be retrieved:
// authResult.credential.idToken
}
}
}
firebase authentication package has a method called signInWithPopup so you don't need firebase_auth_oauth anymore. here my code:
Future<UserCredential?> loginWithMicrosoft() async {
OAuthProvider provider = OAuthProvider('microsoft.com');
provider.setCustomParameters({
"tenant": "your-tenant-id",
});
provider.addScope('user.read');
provider.addScope('profile');
try {
final userCredential = await FirebaseAuth.instance.signInWithPopup(provider);
return userCredential;
} on FirebaseAuthException catch(err) {
debugPrint(err.message);
// Handle FirebaseAuthExceptions
// ex: firebase_auth/account-exists-with-different-credential
}
}
Remeber add the redirect URI and enable de scopes in Azure Portal.

Flutter - How to link social account using Firebase facebook and google plugin

I have a flutter app and would like the user to authenticate both with FB and Google. I do not want multiple accounts, just a single account that links both.
I am using :
firebase_auth 0.15.1
google_sign_in 4.0.14
facebook_plugin 3.0.0
I am not able to get the email address of the user when the user's account already exist with a different provider. The email is needed in order to get the list of providers for that user using the API call "fetchSignInMethodsForEmail"
Here is an example:
1: User login with Google credentials. The account is created in firebase and google is linked.
2: The user now logoff
3: The user now tries to login with FB with the same email.
-- User get the following error
code:"ERROR_ACCOUNT_EXISTS_WITH_DIFFERENT_CREDENTIAL"
details: null
message: "An account already exists with the same email address but different sign-in credentials. Sign in using a provider associated with this email address., **null**))
As you can see the email is null. I need the email in order to get a list of providers. Then I can redirect the user to correct provider
here is a snippet of my code
Future<FirebaseUser> signInWithFacebook({bool isIos}) async {
AuthCredential credential;
try {
final FacebookLoginResult result = await facebookLogin.logIn(['email']);
if (result.accessToken != null) {
credential = FacebookAuthProvider.getCredential(
accessToken: result.accessToken.token
);
AuthResult authResult = await _firebaseAuth.signInWithCredential(
credential,
);
firebaseUser = authResult.user;
return firebaseUser;
} catch (e) {
throw Exception(e);
}
return null;
}
Thanks for your help