Giter Club home page Giter Club logo

msal-flutter's Introduction

Project moved

This project has been moved to https://github.com/Muljin/msal-flutter

UPDATES IN PROGRESS

Please note updates are currently in progress. We are not currently accepting any PRs.

VERSION 1.0.0+ WARNING

Version 1.0.0 uses the updated MSAL Libraries and moves to Android-X. 1.0.0 IS NOT compatiable with older versions. Please only update to 1.0.+ if you are ready to migrate your android app and change how you call the constructor. Version 1+ is however required to use MSAL on iOS 13+

It is also not recommended to use the login.microsoftonline.com authority and endpoints, as old appear to be being deprecated and do not seperate saved passwords due to domain being the same for all tenants. The new authority template is https://<tenant>.b2clogin.com/tfp/<tenant>.onmicrosoft.com/<user-flow> e.g. https://msalfluttertest.b2clogin.com/tfp/msalfluttertest.onmicrosoft.com/B2C_1_sisu

For troubleshooting known bugs in the new build, please scroll down to the bottom of the page where all bugs and fixes we find will be noted.

MSAL Wrapper Library for Flutter

Please note this product is in very early alpha release and subject to change and bugs.

The Microsoft Authentication Library Flutter Wrapper is a wrapper that uses that MSAL libraries for Android and IOS. Currently only the public client application functionality is supported, using the implicit workflow. If you have a requirement for additional functionality however please let me know.

Setup

To use MSAL Flutter in your library, first setup an Azure AD B2C tenant and mobile client if you have not done so already, for which detailed instructions can be found at https://docs.microsoft.com/en-us/azure/active-directory-b2c/

Flutter

Import the Msal Flutter package into your flutter application by adding it to the list of dependencies in your pubsec.yaml file.

dependencies:
    msal_flutter: ^1.0.0+2

Android (Kotlin)

NOTE: Due to a known kotlin issue kotlin please ensure you are using Kotlin version 1.3.50 or later. To set this, goto your app's android folder, open the build.gradle file, and under buildscript:ext.kotlin_version change the version to 1.3.50 or later.

This section is mostly copied and modified from the official android MSAL library github repository. Visit the repository for more details and information on how to use it with authentication brokers.

  1. Give youyr app internet permissions
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
  1. In your AndroidManifest.xml file add the following intent filter, replacing the placeholder <YOUR-CLIENT-ID> for your azure b2c application's client id where indicated below. The default redirect url is msal<YOUR-CLIENT-ID>://auth however this can now be changed for android. If you have changed your redirect url to something else, please set the below activity settings to match your own.
<activity
    android:name="com.microsoft.identity.client.BrowserTabActivity">
    <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="msal<YOUR-CLIENT-ID>"
            android:host="auth" />
    </intent-filter>
</activity>
  1. Copy the msal_default_config from this repository (or make your own if you know what you're doing) and place it into your flutter apps android/src/main/res/raw folder. By default/tradition the redirect URL is msal<YOUR-CLIENT-ID>://auth for android, however if you have selected a different redirect url please enter that. Note the redirect URL scheme and host combination MUST BE UNIQUE to your application and if you do change it it must also be changed in the activity intent filter in step 2.

WARNING DO NOT set the application type to single. the MSAL Flutter wrapper is only compatiable with the newer multiple account configuration.

For an example see the example apps usage here

  1. The minimum SDK version must be atleast 21. If you are starting from a new flutter app with the default 16 version, please change this in your gradle settings which can be found in android > app > build.gradle file, and then under the object android:defaultConfig>minSdkVersion

iOS (Swift)

This section is mostly copied and modified from Step 1 from the official iOS MSAL library github repository. Visit the repository for more details.

  1. Add your URL scheme for callbacks to your Info.plist file, replacing the placeholder for your azure b2c application's client id where indicated below.
<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>msauth.[BUNDLE-ID]</string>
        </array>
    </dict>
</array>
  1. Add LSApplicationQueriesSchemes to allow making call to Microsoft Authenticator if installed (For Authentication broker)
<key>LSApplicationQueriesSchemes</key>
<array>
	<string>msauthv2</string>
	<string>msauthv3</string>
</array>
  1. Open the app's iOS project in xcode, click on the Runner app to open up the configuration, and under capabilities, expand Keychain Sharing and add the keychain group com.microsoft.adalcache

  2. Import the MSAL library in your AppDelegate.swift by adding the following at the top of the file

import MSAL

  1. Add the following function to your AppDelegate class
override func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {    
guard let sourceApplication = options[UIApplication.OpenURLOptionsKey.sourceApplication] as? String else {
    return false
}  
return MSALPublicClientApplication.handleMSALResponse(url, sourceApplication: sourceApplication)
}
  1. Trouble shooting It is possible that you may get errors such as with the minimum iOS deployment being too low. MSAL Flutter requires a minimum iOS version of 11.0 To set this, add platform :ios, '11.0' on the first line of your Podfile file which can be found in the root of your ios folder.

When upgrading from older versions of MSAL Flutter, you might also need to delete your Podfile.lock file, which is also in the iOS folder.

How To Use

  1. In flutter, import the package import 'package:msal_flutter/msal_flutter.dart';

  2. Use the static factory method createPublicClientApplication to asyncronously create a new instance of the object, by providing your client id, and optionally the authority to authenticate again.

    With default authority:

    var pca = await PublicClientApplication.createPublicClientApplication("YOUR-CLIENT-ID");

    Specifying authroity:

    var pca = await PublicClientApplication.createPublicClientApplication("YOUR-CLIENT-ID", authority: "https://<tenant>.b2clogin.com/tfp/<tenant>.onmicrosoft.com/<user-flow>");

    If this is null the default authority will be used, as defined by the relevant MSAL library implementation, which currently is the common endpoint.

  3. To retrieve a token interactivity, call the acquireToken function passing the scopes you wish to acquire the token for. Note that this function will throw an error on failure and should be surrounded by a try catch block as per the example below

    DO NOT include the openid or user_impersonation scopes which are added by default

try{
   String token = await pca.acquireToken(["https://msalfluttertest.onmicrosoft.com/msalbackend/user_impersonation"]);
} on MsalException {
   //error handling logic here
}
  1. Once a user has logged in atleast once, to retrieve a token silently call the acquireTokenSilent function, passing the scopes you wish to acquire the token for. Note that this function will throw an error on failure and should be surrounded by a try catch block as per the example below

    DO NOT include the openid or user_impersonation scopes which are added by default

try{
    String token = await pca.acquireTokenSilent(["https://msalfluttertest.onmicrosoft.com/msalbackend/user_impersonation"]);
} on MsalException{
    // error handling logic here
}
  1. To logout, call the logout method
try{
    await pca.logout();
} on MsalException{
    // error handling logic here
}

List of exceptions that can be thrown

Exception Description
MsalException Base exception, inhertied by all other exceptions. Used for general or unknwon errors
MsalChangedClientIdException Attempt to initialize a second client id with a different clientid
MsalInitializationException Error initializing client. Most likely do to incorrect configuration files
MsalInvalidConfigurationException Configuration error in setting up Public Client Application, such as invalid clientid or authority
MsalInvalidScopeException Invalid scope or no scope supplied. Currently only supported in android
MsalNoAccountException User has not previously logged, has logged out or refresh token has expired and and acquire token silently cannot be performed
MsalUninitializedException Client method called before client has been initialized
MsalUserCancelledException Login request cancelled by user. Only currently supported in Android, for iOS a MsalException is thrown instead

Trouble Shooting

Please note there is currently an issue that seems to occur with Android which uses slightly older versions of kotlin. If you get the error when attemtping to acquire a token, along the lines of "static member msalApp not found", goto your app's android folder, open the build.gradle file, and on the second line change the version of kotlin from 1.3.10 to 1.3.50. For more information take a look at issue #4. A fix will be implemented shortly.

msal-flutter's People

Contributors

ericgkr avatar michaelmairegger avatar mswehli avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

msal-flutter's Issues

Invalid configuration error keeps coming

I tried using the plugin configured everything as required but when try to login nothing happens with the sample code.

With the same configuration however iOS app works fine.

No static field msalApp

I do not know what I am doing wrong. I followed the readme file but I get the following exception

E/flutter (19355): [ERROR:flutter/shell/platform/android/platform_view_android_jni.cc(39)] java.lang.NoSuchFieldError: No static field msalApp of type Lcom/microsoft/identity/client/IMultipleAccountPublicClientApplication; in class Luk/co/moodio/msal_flutter/MsalFlutterPlugin$Companion; or its superclasses (declaration of 'uk.co.moodio.msal_flutter.MsalFlutterPlugin$Companion' appears in /data/app/com.example.flutter_app1-swehphgquUI3YKtyjLgW9A==/base.apk!classes3.dex)

MsalClientException is thrown,which can't be handled

MsalClientException is thrown if there is no connection and token is expired and it can't be handled.
here is full stacktrace

[ +276 ms] E/AndroidRuntime( 9658): FATAL EXCEPTION: Thread-2
[ ] E/AndroidRuntime( 9658): Process: com.example.myonpu, PID: 9658
[ ] E/AndroidRuntime( 9658): com.microsoft.identity.client.exception.MsalClientException: Connection is not available to refresh token
[ ] E/AndroidRuntime( 9658): at com.microsoft.identity.client.internal.controllers.MsalExceptionAdapter.msalExceptionFromBaseException(MsalExceptionAdapter.java:49)
[ ] E/AndroidRuntime( 9658): at com.microsoft.identity.client.PublicClientApplication$9.onError(PublicClientApplication.java:1621)
[ ] E/AndroidRuntime( 9658): at com.microsoft.identity.common.internal.controllers.ApiDispatcher$4$1.run(ApiDispatcher.java:424)
[ ] E/AndroidRuntime( 9658): at android.os.Handler.handleCallback(Handler.java:751)
[ ] E/AndroidRuntime( 9658): at android.os.Handler.dispatchMessage(Handler.java:95)
[ ] E/AndroidRuntime( 9658): at android.os.Looper.loop(Looper.java:154)
[ ] E/AndroidRuntime( 9658): at android.app.ActivityThread.main(ActivityThread.java:6682)
[ ] E/AndroidRuntime( 9658): at java.lang.reflect.Method.invoke(Native Method)
[ ] E/AndroidRuntime( 9658): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
[ ] E/AndroidRuntime( 9658): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)
[ ] E/AndroidRuntime( 9658): Caused by: com.microsoft.identity.common.exception.ClientException: Connection is not available to refresh token
[ ] E/AndroidRuntime( 9658): at com.microsoft.identity.common.adal.internal.net.HttpWebRequest.throwIfNetworkNotAvailable(HttpWebRequest.java:201)
[ ] E/AndroidRuntime( 9658): at com.microsoft.identity.common.internal.controllers.BaseController.performSilentTokenRequest(BaseController.java:328)
[ ] E/AndroidRuntime( 9658): at com.microsoft.identity.common.internal.controllers.BaseController.renewAccessToken(BaseController.java:204)
[ ] E/AndroidRuntime( 9658): at com.microsoft.identity.client.internal.controllers.LocalMSALController.acquireTokenSilent(LocalMSALController.java:252)
[ ] E/AndroidRuntime( 9658): at com.microsoft.identity.common.internal.controllers.TokenCommand.execute(TokenCommand.java:89)
[ ] E/AndroidRuntime( 9658): at com.microsoft.identity.common.internal.controllers.ApiDispatcher$4.run(ApiDispatcher.java:401)
[ ] E/AndroidRuntime( 9658): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
[ ] E/AndroidRuntime( 9658): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
[ ] E/AndroidRuntime( 9658): at java.lang.Thread.run(Thread.java:762)

Launching MS Authenticator

PublicClientApplication.acquireToken does not launch MS Authenticator.

Info.plist already contains the following:

	<key>LSApplicationQueriesSchemes</key>
	<array>
		<string>msauthv2</string>
		<string>msauthv3</string>
	</array>

Please note that authentication works. It brings up the web-based login form even if Authenticator has been installed on the device.

The device is running iOS 13.3.1. MSAL version 1.0.7 has been pulled with CocoaPods.

Is there something that I am missing?

Example does not work for iOS

Environment:
macOS Catalina 10.15.2
Xcode: 11.3

Ran example app only changing authority, clientID and scopes. The app asks for permission to use b2clogin and then strangely gives me the below:
Screen Shot 2019-12-26 at 8 29 22 PM

Thoughts?

Azure AD non B2C

Can I use this for Azure AD for organization? I'm having difficulties figuring the authorities since I always got null client/authority

Not able to trigger broker app

Hello every I want help regarding MSAL authentication using the broker app in ios I have all the required dependencies and code changes but am still note able to trigger the broker app (Microsoft authenticator app using MSAL package in ios)

upgrade to v1.0.0 fails to run

E/flutter ( 7384): [ERROR:flutter/shell/platform/android/platform_view_android_jni.cc(39)] java.lang.NoSuchFieldError: No field msalApp of type Lcom/microsoft/identity/client/IMultipleAccountPublicClientApplication; in class Luk/co/moodio/msal_flutter/MsalFlutterPlugin$Companion; or its superclasses (declaration of 'uk.co.moodio.msal_flutter.MsalFlutterPlugin$Companion' appears in /data/app/com.owltechindustries.shot_trac_mobile-NfV79bdW-1JQ0dob-YmbBw==/base.apk:classes7.dex)
E/flutter ( 7384): at uk.co.moodio.msal_flutter.MsalFlutterPlugin$Companion.isClientInitialized(MsalFlutterPlugin.kt:26)

App crashing with null safety version

We are experiencing crashes when using this lib in the current null safety version:

E/AndroidRuntime( 7973): java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.Boolean.booleanValue()' on a null object reference
E/AndroidRuntime( 7973): 	at com.microsoft.identity.client.internal.CommandParametersAdapter.createCommandParameters(CommandParametersAdapter.java:65)
E/AndroidRuntime( 7973): 	at com.microsoft.identity.client.PublicClientApplication.create(PublicClientApplication.java:913)
E/AndroidRuntime( 7973): 	at com.microsoft.identity.client.PublicClientApplication.access$000(PublicClientApplication.java:202)
E/AndroidRuntime( 7973): 	at com.microsoft.identity.client.PublicClientApplication$3.run(PublicClientApplication.java:365)
E/AndroidRuntime( 7973): 	at java.lang.Thread.run(Thread.java:923)

The method causing this is

await PublicClientApplication.createPublicClientApplication(
      azureAppID,
      authority: _authority,
    )

Authentication error when receive redirect from acquireToken

I tried to follow the document & an example in this plugin. User can sign in in b2c but it always in the redirect step with the exception Authentication error.
My redirect url: msauth.com.my.package://auth
I also set the CFBundleURLTypes & LSApplicationQueriesSchemes like the document & example, but still doesn't work.
My code:

Future<String> acquireToken() async {
    if (pca == null) {
      pca = await PublicClientApplication.createPublicClientApplication(
          _clientId,
          authority: _authority);
    }
    try{
    await pca.logout();
    } on MsalException catch(e){
        LogUtil.e(e);
    }

    try {
      return await pca.acquireToken([
        "https://mytenant.onmicrosoft.com/b2capi/user_impersonation"
      ]);
    } on MsalUserCancelledException catch(e) {
      LogUtil.e(e);
    } on MsalNoAccountException catch(e){
      LogUtil.e(e);
    } on MsalInvalidConfigurationException catch(e){
      LogUtil.e(e);
    } on MsalInvalidScopeException catch(e){
      LogUtil.e(e);
    } on MsalChangedClientIdException catch(e){
      LogUtil.e(e);
    }on MsalUninitializedException catch(e){
      LogUtil.e(e);
    }on MsalInitializationException catch(e){
      LogUtil.e(e);
    } on MsalException catch(e){
      LogUtil.e(e);
    }
  }

Do you have any idea to debug the detail problem?

Errors running and even the sample does not run

We noticed our usage of msal_flutter started to fail. As we went back to figure out what was wrong, we simply ran your example app and it errors out in the same way which makes us think it is an environment error. Here is the error when it is run:
D/MsalFlutter( 4843): Got scopes: null
D/MsalFlutter( 4843): Got cleintId: removed by me
D/MsalFlutter( 4843): Got authority: https://owltechindustries.b2clogin.com/tfp/owltechindustries.onmicrosoft.com/B2C_1_signin_signup
D/MsalFlutter( 4843): Authority not null
D/MsalFlutter( 4843): Creating with: removed by me - https://owltechindustries.b2clogin.com/tfp/owltechindustries.onmicrosoft.com/B2C_1_signin_signup
D/MsalFlutter( 4843): Getting the created listener
E/AndroidRuntime( 4843): FATAL EXCEPTION: pool-4-thread-1
E/AndroidRuntime( 4843): Process: uk.co.moodio.msal_flutter_example, PID: 4843
E/AndroidRuntime( 4843): java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.hashCode()' on a null object reference
E/AndroidRuntime( 4843): at com.microsoft.identity.common.internal.request.OperationParameters.hashCode(OperationParameters.java:252)
E/AndroidRuntime( 4843): at com.microsoft.identity.common.internal.controllers.BaseCommand.hashCode(BaseCommand.java:123)
E/AndroidRuntime( 4843): at java.util.HashMap.hash(HashMap.java:338)
E/AndroidRuntime( 4843): at java.util.LinkedHashMap.get(LinkedHashMap.java:464)
E/AndroidRuntime( 4843): at android.util.LruCache.get(LruCache.java:117)
E/AndroidRuntime( 4843): at com.microsoft.identity.common.internal.controllers.CommandResultCache.get(CommandResultCache.java:48)
E/AndroidRuntime( 4843): at com.microsoft.identity.common.internal.controllers.CommandDispatcher$1.run(CommandDispatcher.java:90)
E/AndroidRuntime( 4843): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
E/AndroidRuntime( 4843): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
E/AndroidRuntime( 4843): at java.lang.Thread.run(Thread.java:764)

Environment looks like:
Flutter: Flutter (Channel stable, v1.9.1+hotfix.4, on Mac OS X 10.15.1 19B88, locale en-US)
Dart version 2.5.0
Android Studio 3.5.3
Flutter plugin version 42.1.1
Dart plugin version 191.8593
Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405)
ext.kotlin_version = '1.3.50' (in. build.gradle)

Any thoughts appreciated as we are a little surprise it suddenly stopped working

Missing return statements after calls to result in SwiftMsalFlutterPlugin.swift

for example

at line 82, change:

      catch{
        result(FlutterError(code: "NO_ACCOUNT",  message: "Error retrieving an existing account", details: nil))
      }

to

      catch{
        result(FlutterError(code: "NO_ACCOUNT",  message: "Error retrieving an existing account", details: nil))
        return
      }

this code is only run when the keychain is not setup correctly and results in a crash

there are many other calls to result without returns following them

Flutter web support

Have you gotten this to work with Flutter web as well yet? I am thinking it should be easy to get it to work with Flutter web.

_acquireToken fails on Android

Hello,

I am new with flutter and while msal_flutter works for iOS when trying to configure MSAL authentication (AAD, B2B) on android it fails. Even the example provided - app does not work. Could you please assist. Thank you.

Screenshot 2020-06-13 at 23 38 12

Deprecated version

I'm facing this issue with this package, is there any way around this?

The plugin msal_flutter uses a deprecated version of the Android embedding.
To avoid unexpected runtime failures, or future build failures, try to see if this plugin supports the Android V2 embedding. Otherwise, consider removing it since a future release of
Flutter will remove these deprecated APIs.
If you are plugin author, take a look at the docs for migrating the plugin to the V2 embedding: https://flutter.dev/go/android-plugin-migration.

Azure AD B2C

Does this work with Azure AD B2C? I just see active directory listed.

type mismatch: inferred type is String? but String was expected

I'm having problems building the APP
I'm using
flutter 2.2.3 stable
dart 2.13.4
msal-flutter 1.0.0+3

C:\src\flutter\.pub-cache\hosted\pub.dartlang.org\msal_flutter-1.0.0\android\src\main\kotlin\uk\co\moodio\msal_flutter\MsalFlutterPlugin.kt: (51, 42): Type mismatch: inferred type is String? but String was expected


* What went wrong:
Execution failed for task ':msal_flutter:compileDebugKotlin'.
> Compilation error. See log for more details

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.