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.

Comments
  • 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
  • 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
  • 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
  • Support implicit grant flow

    Support implicit grant flow

    Currently this package does not work with Google (e.g. Google Workspace) as IdP for a web app, because accounts.google.com only supports the authorization code flow with PKCE for mobile clients (iOS and Android). If you create an OAuth-ClientId of type "Web-Application" and configure the plugin with:

    final configuration = await OpenIdConnect.getConfiguration(
          '${request.issuer}/.well-known/openid-configuration',
    );
    
    final result = await OpenIdConnect.authorizeInteractive(
      context: request.context,
      title: "Login",
      request: await InteractiveAuthorizationRequest.create(
        clientId: clientId, // Client ID optained from google cloud console
        redirectUrl: 'https://example.com/callback', // URL of my flutter app
        scopes: request.scopes,
        configuration: configuration
      ),
    );
    

    The request fails with an error, that grant_type is an unsupported parameter. If I alter the code of this plugin to omit the grant_type parameter the, login screen is shown correctly but the code exchange on the token endpoint fails, because it expects a Client ID.

    opened by fdaugs 0
  • Problem in navigate to login page after redirect

    Problem in navigate to login page after redirect

    I place callback.html in the web folder and when I try to run in localhost after login user in the identity server(SSO) gets this error and the login goes incomplete.

    Could not navigate to initial route. The requested route name was: "/callback.html?code=3FB8C2350B5BAB64BA451D1AB7DA3D6DC64972068FEB54D9A0F9F04236788603&scope=openid%20profile%20email%20roles%20offline_access&session_state=pnUxDeiG5WF-1Devzs7829Rwnf9ZxxjPvA-1okPvgBI.BDF625AA8B19E06D8D8FE69B0CEF6E5E" There was no corresponding route in the app, and therefore the initial route specified will be ignored and "/" will be used instead.

    opened by majidebraa 0
  • nullpointer fix

    nullpointer fix

    Not all Open Id Connect providers follow the standard up to 100%. When calling the discovery endpoint, our provider does not provide information about the "claims_supported". This leads to a null pointer exception. This pull request would fix the error by making the claims_supported optional.

    opened by peach12345 0
  • In-app browser or separate user agent?

    In-app browser or separate user agent?

    It's not clear to me if this is using a user agent separate from the app on mobile. Is it using chrome tabs for example on Android, or using an in-app browser when communicating to the idp?

    opened by markphillips100 1
  • Can not retrieve users info with UseWebPopup = false

    Can not retrieve users info with UseWebPopup = false

    I'm working on authentication with Azure, on a web app. When I set the useWebPopup to false, the auth page opens normally to authenticate with Azure, but after the whole application is refreshed, and I still find myself on the authentication page.

    I've tried with the example project provided in this package and I have the same behavior, after the authentication flow, I come back to the auth page instead of being redirected to the page with the user information ( token, username, etc...

    [Starting point - 1]

    Capture d’écran 2022-08-05 à 15 32 35 )

    [Select Interactive with use Web Popup disabled]

    Capture d’écran 2022-08-05 à 15 32 48

    [o365 Auth Flow]

    Capture d’écran 2022-08-05 à 15 33 29

    [I'm back to the step one]

    Capture d’écran 2022-08-05 à 15 33 45

    Normally I should see the page with usage information as in the case with UseWebPopup is true.

    How can I have the same behavior in Popup mode ? Thanks

    opened by angelo98-dev 0
  • Authorize code - step by step to display the device code

    Authorize code - step by step to display the device code

    In the authorize code method the identification & authorization is completed in one step which does not allow displaying the device code. Without the device code the user can not verify if the authentication is as intended (UX Issue). This commit creates two methods that split the authorizeCode method in two. This allows first getting the response with the device code and then going for the authentication afterwards.

    Example usage

                     final codeResponse =
                            await OpenIdConnect.authorizeDeviceGetDeviceCodeResponse(request: request);
    
                       // dsplay the user device code
                        setState(() {
                          deviceIdentification = codeResponse.userCode;
                        });
    
                        final response =
                            await OpenIdConnect.authorizeDeviceCompleteDeviceCodeResponseRequest(
                          request: request,
                          codeResponse: codeResponse,
                        );
    
    

    example_zszdgAPUu5

    Names could probably be chosen better :-)

    opened by MSchmack 0
Owner
null
GetDoctor is a complete app developed in Flutter, Firebase and Blazor,.Net Core API and SQL Server

GetDoctor ?? ?? ?? GetDoctor is a complete app developed in Flutter, Firebase and Blazor,DotNet Core API and SQL Server GetDoctor is a complete packag

Sunil Vijayan 69 Dec 19, 2022
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 31 Jan 1, 2023
A complete Flutter E-Commerce Book Store application built using firebase as backend

ecommerce A complete Flutter E-Commerce Book Store application built using firebase as backend. Features Add or remove item in cart Search products Ad

aakanksha 2 Sep 24, 2022
The most complete Chat UI for flutter highly customizable and helps developing chat UI faster.

⚠️ Dashchat v2 is available in v2 branch ⚠️ You can open issues for the v2 to indicate things we need to implement/fix. Also the API can change until

Fayeed Pawaskar 432 Dec 11, 2022
A complete Flutter chat UI kit

A complete Flutter chat UI kit This Flutter package provides you with a base structure as well as a set of tools that allow you to quickly build up a

null 102 Dec 25, 2022
A Complete Weather App Using Flutter

weather ?? A complete weather app Use this source code in your project Rate me ⭐ Thank you ☺ Platform Android ✔️ Preview About Work it with API Finde

Amirziya 3 May 18, 2022
Shopping-Trend - E-Commerce Complete App UI With Flutter

E-Commerce Complete App - Flutter UI In the first part of complete e-commerce ap

Ashirbad Swain 30 Dec 19, 2022
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 10 Oct 25, 2022
A simple todo app for keeping track of complete and incomplete tasks

bloc_todo_list A simple todo app built using bloc architecture and state management Getting Started This project is a starting point for a Flutter app

Olusesi Boluwatife Barry 0 Nov 29, 2021
Complete movie app with flutter_riverpod and moviedb api

movieapp A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you started if this

Manish Kumar Rajak 0 Nov 27, 2021
Provides a complete list of Philippine towns, cities, provinces and regions.

Philippines This provides a complete list of Philippine towns, cities, provinces and regions. References: http://en.wikipedia.org/wiki/Regions_of_the_

Roy Evan Sia 64 Oct 3, 2022
QR.Flutter is a Flutter library for simple and fast QR code rendering via a Widget or custom painter.

QR.Flutter is a Flutter library for simple and fast QR code rendering via a Widget or custom painter. Need help? Please do not submit an issue for a "

Yakka 612 Jan 4, 2023
Flutter library to create beautiful surveys (aligned with ResearchKit on iOS)

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

QuickBird Studios 90 Dec 28, 2022
🎞 Flutter media playback, broadcast & recording library for Windows, Linux & macOS. Written in C++ using libVLC & libVLC++. (Both audio & video)

dart_vlc Flutter media playback, broadcast, recording & chromecast library for Windows, Linux & macOS. Written in C++ using libVLC & libVLC++. Install

Hitesh Kumar Saini 417 Dec 29, 2022
Flutter example project to run Solidity smart contracts using web3Dart library

Fluthereum Description Flutter example project to run Solidity smart contracts using web3Dart library Dependencies web3dart: A dart library that conne

Marcos Carlomagno 72 Dec 27, 2022
Demo library index written in Flutter

demo_books A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you started if th

Nemanja Stošić 1 Sep 20, 2022
A playground for me to learn the Riverpod state management library in Flutter.

clothes_shop A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you started if

Benhenneda Majid 2 Oct 25, 2021
Playify is a Flutter plugin for play/pause/seek songs, fetching music metadata, and browsing music library.

Playify Playify is a Flutter plugin for play/pause/seek songs, fetching music metadata, and browsing music library. Playify was built using iOS's Medi

Ibrahim Berat Kaya 32 Dec 14, 2022
Flutter Screenshot Library

A simple package to capture widgets as Images. Now you can also capture the widgets that are not rendered on the screen! This package wraps your widge

Sachin 225 Dec 19, 2022