Complete Flutter OpenIdConnect Library

Overview

OpenIdConnect for Flutter

Standards compliant OpenIdConnect library for flutter that supports:

  1. Code flow with PKCE (the evolution of implicit flow). This allows poping a web browser (included) for authentication to any open id connect compliant IdP.
  2. Password flow. For use when you control the client and server and you wish to have your users login directly to your IdP.
  3. Device flow. For use typically with console applications and similar. Used currently for Windows, Linux and MacOs until WebView is supported on those platforms.
  4. Full OpenIdConnect Client library that encapsulates the entire process including refresh tokens, refreshing and publishes an event stream for your application.

The base library supports most of the basic OpenIdConnect functionality:

  1. Authorize/Login (for all 3 code flows)
  2. Logout
  3. Revoke Token
  4. Refresh Token
  5. User Info

In addition there is a complete OpenIdConnectClient which supports all 3 authorization flows AND automatically maintains login information in secure (ish, web is always the problem with this) storage and automatically refreshes tokens as needed.

Currently supports:

  1. iOS
  2. Android
  3. Web
  4. Windows
  5. MacOs
  6. Linux

Important

For Linux, Windows and macOS currently your IdP MUST support device code flow to function properly with interactive login. Otherwise you must use password flow. This is because webView is not yet supported on these environments.

Getting Started

  1. Add openidconnect to your pubspec.yaml file
  2. Import openidconnect: import 'package:openidconnect/openidconnect.dart';
  3. Call the various methods: on OpenIdConnect OR use OpenIdConnectClient and subscribe to the events
  4. Review the example project for details.

(more detailed instructions coming soon)

Web

  1. Copy the callback.html file from openidconnect_web (in this repo) into the web folder of your app. Make sure that your Idp has the proper redirect path https://{your_url_to_app/callback.html} as one of the accepted urls.

  2. OpenIdConnect web has 2 separate interactive login flows as a result of security restrictions in the browser. (Password and device flows are identical for all platforms) In most cases you'll want to use the default popup window to handle authentication as this keeps everything in process and doesn't require a reload of your flutter application. However, if you have to initiate interactive login outside of clicking a button on the page, your browser will block the popup and put a prompt up asking the user to allow it. This is a bad thing of course. Thus you can set useWebPopup = false on interactiveAuthorization when you need to initialize your authorization outside of a button click. This will result in a redirect in the same page and then the login page on your IdP will redirect back to /callback.html (see notes). This will then be processed using the OpenIdConnect.processStartup or by the OpenIdConnectClient on .create() and then your app will resume as normal including the url that it left off.

Note: It is VERY important to make sure you test on Firefox with the web, as it's behavior for blocking popups is significantly more restrictive than Chromium browsers.

TODO

Because of the ever changing nature of desktop support on flutter and incomplete plugin implementations the following are outstanding and will be updated when the functionality exists to do so:

  1. Use custom tabs and secure authentication popup on Android and IOS instead of WebView
  2. Use Secure authentication popup on windows (requires work from Tim Sneath on integration with Project Reunion on Windows and Dart)
  3. Switch macOs, and Linux to WebView and/or use secure authentication popup at least on macOs.
  4. More documentation!

Contributing

Pull requests most welcome to fix any bugs found or address any of the above TODOs. I'm not a C++, Kotlin or Swift developer, so custom implementations for various environments would be greatly appreciated.

If adding a custom environment other than android and iOS please follow the flutter best practices and add a separate implementation project with: flutter create --template=plugin --platforms={YourPlatformHere} openidconnect_{YourPlatformHere} and add your code as appropriate there and then update the example project to use the new implementation.

Your new implementation needs to import the platform interface which is exactly one entry. That entry passes in the url to display in the secure browser and the redirect url that you should watch for to respond accordingly. (You can ignore the redirect url on most platforms that support custom URLs such as Android, iOS etc.) You should return the entire redirected URL which should include the ?code= (and perhaps state) when complete.

Everything else is handled in native dart code so the implementation is very straight forward.

Issues
  • How to Use this with okta as IDP

    How to Use this with okta as IDP

    Can this be used with OKTA.

    I tried the PKCE flow with okta I get the below response for callback.html "The authentication request has an invalid 'state' parameter."

    opened by sohan99 3
  • Error when running example

    Error when running example

    I can get the reply with my url. image

    But hit error when clicking the Lookup button. image

    Error: Expected a value of type 'List', but got one of type 'Null' at Object.throw_ [as throw] (http://localhost:65418/dart_sdk.js:5041:11) at Object.castError (http://localhost:65418/dart_sdk.js:5014:15) at Object.cast [as as] (http://localhost:65418/dart_sdk.js:5323:17) at Function.as_C [as as] (http://localhost:65418/dart_sdk.js:4960:19) at Function.fromJson (http://localhost:65418/packages/openidconnect/openidconnect.dart.lib.js:1620:998) at getConfiguration (http://localhost:65418/packages/openidconnect/openidconnect.dart.lib.js:376:50) at getConfiguration.next () at http://localhost:65418/dart_sdk.js:37403:33 at _RootZone.runUnary (http://localhost:65418/dart_sdk.js:37274:59) at _FutureListener.thenAwait.handleValue (http://localhost:65418/dart_sdk.js:32530:29) at handleValueCallback (http://localhost:65418/dart_sdk.js:33057:49) at Function._propagateToListeners (http://localhost:65418/dart_sdk.js:33095:17) at _Future.new.[_completeWithValue] (http://localhost:65418/dart_sdk.js:32943:23) at async._AsyncCallbackEntry.new.callback (http://localhost:65418/dart_sdk.js:32964:35) at Object._microtaskLoop (http://localhost:65418/dart_sdk.js:37526:13) at _startMicrotaskLoop (http://localhost:65418/dart_sdk.js:37532:13) at http://localhost:65418/dart_sdk.js:33303:9

    May I know what am I missing? Thanks.

    opened by jasonlaw 3
  • OpenIdConnectClient is not mockable for testing

    OpenIdConnectClient is not mockable for testing

    I'm looking to mock the OpenIdConnectClient so as not to make API calls in my tests, but I'm not currently able to do so

    I can mock out the static method OpenIdConnectClient.create() by putting a wrapper around the class. However, the actual constructor has been made private, so a mockable instance of OpenIdConnectClient can't be created to be used in tests.

    opened by rjacobskind 0
  • Broken on iOS due to WebView on setting App Redirect URI

    Broken on iOS due to WebView on setting App Redirect URI

    https://github.com/flutter/flutter/issues/74987 https://github.com/Concerti-IO/openidconnect_flutter/blob/8a6d8c83063cf8dcedbf0520a5058e4b1408d805/openidconnect/lib/src/android_ios.dart#L30-L37

    opened by ThomasAunvik 0
  • How to access logged in user information using multiple browser tabs

    How to access logged in user information using multiple browser tabs

    Is there a way to get logged user in information across multiple browser tabs using openidconnect_flutter.

    Is there call backs for events like logged in and logged out

    opened by sohan99 0
  • Question: Mobile complete screen redirection to identity server instead of popup

    Question: Mobile complete screen redirection to identity server instead of popup

    Hello,

    I tried this package for the web it's working without any issues, i.e. if i disable usePopup for web then it redirects web to ideneity server login screen and on login it redirects to the app again.

    but for mobile view usePopup is by default true, is there any workaround or solution in this current package where i can achieve same for the mobile (android/IOS) devices, i.e. instead of loading/redirecting the identity server in popup it should redirect app to the identity server and then on success redirects back to app, like it's flutter_appauth package
    https://pub.dev/packages/flutter_appauth

    Is there any way to achieve above requirement with current package., by handling changes in plugin,

    can you atleast expose complete dialog height and width parameters, instead of applying the minumum width and height from the inputs https://github.com/Concerti-IO/openidconnect_flutter/blob/8a6d8c83063cf8dcedbf0520a5058e4b1408d805/openidconnect/lib/src/android_ios.dart#L27

    Thanks

    opened by SameerChorge94 0
  • authorizationInteractive on iOS Failed to redirect app

    authorizationInteractive on iOS Failed to redirect app

    Hi,

    Thanks for this lib! I succeed using it on flutter web app. But when testing on iOS, I have an error when the redirectURI is called by the webview

    flutter: Error Domain= Code=0 "Redirection to URL with a scheme that is not HTTP(S)" UserInfo={_WKRecoveryAttempterErrorKey=<WKReloadFrameErrorRecoveryAttempter: 0x6000024f9c80>, NSErrorFailingURLStringKey=com.myapp.test://login-callback?code=HvXMEgiCMbMhhBqU, NSErrorFailingURLKey=com.myapp.test://login-callback?code=HvXMEgiCMbMhhBqU, NSLocalizedDescription=Redirection to URL with a scheme that is not HTTP(S)}
    

    As the error says, webview doesn't redirect to non http(s) scheme. So the onPageFinished callback in android_ios.dart#OpenIdConnectAndroidiOS is never called.

    I managed to by pass this error adding

      navigationDelegate: (navigation) {
                    if (navigation.url.startsWith(redirectUrl)) {
                      Navigator.pop(dialogContext, navigation.url);
                      return flutterWebView.NavigationDecision.prevent;
                    }
                    return flutterWebView.NavigationDecision.navigate;
                  },
    

    I think, I'm not using correctly the lib for mobile app. What should I do to make it work without modifying the lib?

    My implementation is

    
    class Auth0Service {
      Future<AuthorizationResponse> login(
          BuildContext context, Auth0Configuration conf) async {
        final jsonConf = await OpenIdConnect.getConfiguration(
            "https://" + conf.auth0Domain + "/.well-known/openid-configuration");
    
        return OpenIdConnect.authorizeInteractive(
                context: context,
                title: "Interactive Login",
                request: await InteractiveAuthorizationRequest.create(
                  clientId: conf.auth0ClientID,
                  redirectUrl: conf.auth0RedirectURI,
                  scopes: ["openid", "offline_access"],
                  configuration: jsonConf,
                  autoRefresh: false,
                  useWebPopup: true,
                ))
            .asStream()
            .where((event) => event != null)
            .map((event) => event!)
            .first;
      }
    }
    
    class Auth0Configuration {
      final String auth0Domain;
      final String auth0ClientID;
      final String auth0RedirectURI;
      final String auth0Issuer;
    
      const Auth0Configuration(
          {required this.auth0Domain,
          required this.auth0ClientID,
          required this.auth0RedirectURI})
          : auth0Issuer = "https://" + auth0Domain;
    }
    
    

    Where the Auth0Service class is available in a flutter package that I would like to reuse in my different projects

    Best

    opened by benji-bou 0
  • Save identity for web sign in with redirect

    Save identity for web sign in with redirect

    When using web sign in with useWebPopup set to false, the identity was not getting saved because the app only gets the response after the redirect from the auth provider.

    This PR saves the identity after processStartup so the identity is stored after a redirect with a valid authentication response.

    opened by Jjagg 0
  • Include query parameters from authorization_endpoint

    Include query parameters from authorization_endpoint

    Hi! Thanks for creating this library. Authentication was one of the things I was dreading for porting my app to web and this will make things a lot easier :)

    I'm using AD B2C and they include the user flow in the authorization_endpoint as a query parameter. See for example the openid configuration from my app: https://projectpura.b2clogin.com/projectpura.onmicrosoft.com/v2.0/.well-known/openid-configuration?p=B2C_1A_Signup_Signin. This library fully replaced the query parameters so the URL was no longer correct.

    This PR adds the original query parameters from the authorization_endpoint to the full uri.

    opened by Jjagg 0
  • Define defaultClientSecret as Empty when using a PKCE

    Define defaultClientSecret as Empty when using a PKCE

    Hey ! Thank you for this example project and the associated lib. A quick improvement would be to define the defaultClientSecret value as Empty or Null when requesting a PKCE token. If the value is set to a placeholder, the data client_secret will be added in the authent query and it'll fail.

    opened by FDuhen 0
  • add user registration

    add user registration

    I added a function to register new users

    opened by ohayak 0
  • Fix refresh timer

    Fix refresh timer

    The refreshTime in the refresh() method was being calculated incorrectly, and therefore the token refresh was not taking place before the token expiration time. This fixes the problem by implementing a calculation similar to the one found in the same file in _setupAutoRenew()

    opened by rjacobskind 0
A complete grocery store developed with Flutter, .Net Core, Firebase, One Signal and SQL Server as backend

# Grocery-Store developed in Flutter,DotNet Core, Firebase, One-Signal, SQL-Server, Stripe, Razorpay, Paypal A complete grocery store developed with F

Sunil Vijayan 18 Oct 27, 2021
Weather app A complete simple weather application.

Weather app A complete simple weather application. Getting Started Get your own API key from: open weathe map aqicn Google Cloud Platform Setup for go

Yoad 7 Oct 19, 2021
Flutter library to create beautiful surveys (aligned with ResearchKit on iOS)

SurveyKit: Create beautiful surveys with Flutter (inspired by iOS ResearchKit Surveys)

QuickBird Studios 49 Nov 16, 2021
A type-safe command-line parsing library for Dart

plade Plade is a type-safe CLI parsing library for Dart. Highlights Fully type-safe and null-safe. Support for a variety of different parsing styles (

Ryan Gonzalez 6 Jul 28, 2021
Agent library for Internet Computer, in Dart

agent_dart An agent library built for Internet Computer, a plugin package for dart and flutter apps. Developers can build ones to interact with Dfinit

null 41 Nov 18, 2021
ThingsBoard PE API client library for Dart developers.

ThingsBoard PE API client library for Dart developers. It's compatible with TB PE 3.3.0. Usage A simple usage example: import 'package:thingsboard_pe_

ThingsBoard - Open-source IoT Platform 39 Nov 16, 2021
A Dart library for creating a Dart object to represent directory trees.

Directory Tree A Dart library for creating a Dart object to represent directory trees. Getting Started Import and initialize package import 'package:d

Chiziaruhoma Ogbonda 4 Jul 5, 2021
Flutter Music Player - First Open Source Flutter based material design music player with audio plugin to play local music files.

Flutter Music Player First Open Source Flutter based Beautiful Material Design Music Player(Online Radio will be added soon.) Demo App Play Store BETA

Pawan Kumar 1.3k Nov 17, 2021
a project for learning all Flutter Widgets , sync from flutter.dev the officia website.

Flutter Widgets Catalog (WIP) 计划 1、使用Flutter开发一个全平台的Flutter Widgets Catalog APP,并且开源。在这个APP中可以通过图形化的方式查看所有Widgets的介绍,示例,视频教程。 2、所有文档内容由前一天从flutter.dev

ezshine 28 Nov 23, 2021
A low-cost Flutter screen adaptation solution(一个极低成本的 Flutter 屏幕适配方案)

A low-cost Flutter screen adaptation solution(一个极低成本的 Flutter 屏幕适配方案) 100% 还原 UI,只需要按照设计图写的宽高写即可 先看图片,设置的标准宽度是 360 iPhone 8 --------------------------

聂志洋 80 Nov 26, 2021
A collection of Flutter examples and demos.

Flutter samples A collection of open source samples that illustrate best practices for Flutter. Visual samples index The easiest way to browse through

Flutter 10.9k Nov 30, 2021
Lime client built using flutter

** This project ist OUT OF DATE and I am currently not able to maintain it ** What we are building Lime is a social media app, which allows you to pos

Sebastian Sellmair 356 Nov 29, 2021
The Flutter Planets app tutorial with commits per lesson

flutter planets tutorial This project contains the steps followed on the tutorial on sergiandreplace.com. Each lesson will correspond to a single bran

Sergi Martínez 710 Nov 26, 2021
News App created in Flutter using News API for fetching realtime data and Firebase as the backend and authenticator.

News Buzz News App created in Flutter using News API for fetching realtime data and Firebase as the backend and authenticator. Features Custom news fe

Ankur Kedia 501 Nov 18, 2021
A Simple Todo app design in Flutter to keep track of your task on daily basis. Its build on BLoC Pattern. You can add a project, labels, and due-date to your task also you can sort your task on the basis of project, label, and dates

WhatTodo Life can feel overwhelming. But it doesn’t have to. A Simple To-do app design in flutter to keep track of your task on daily basis. You can a

Burhanuddin Rashid 908 Dec 2, 2021
A fully functional Instagram clone written in Flutter using Firebase / Firestore

Fluttergram A working Instagram clone written in Flutter using Firebase / Firestore Demo Download the release APK to try out Fluttergram I update Flut

Matthew Danics 1.9k Nov 25, 2021
Flutter clone of my "Cinematic" App

Flutter Cinematic This app is a Flutter port of the native Android App Cinematic. My intention in creating this app was understanding the intricacies

Aaron Oertel 828 Nov 27, 2021
A beer tracking app made with Flutter

Beer Me Up Beer Me Up is an iOS and Android app build with Flutter. The app is a personal beer logging that allows you to enter every beer you have to

Benoit Letondor 441 Nov 17, 2021