Skip to content

4D-Technologies/openidconnect_flutter

Repository files navigation

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 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.

Requirements

Package requirements

  • Dart SDK: >=3.8.0 <4.0.0
  • Flutter SDK: >=3.27.0

Platform minimums used by the endorsed implementations

  • Android: minSdkVersion 23
  • iOS: 13.0
  • macOS: 10.15
  • Linux / Windows / Web: no additional package-enforced OS floor beyond the Flutter toolchain you build with

Getting Started

  1. Add openidconnect to your pubspec.yaml file.
  2. Import package:openidconnect/openidconnect.dart.
  3. Call the various methods on OpenIdConnect, or use OpenIdConnectClient and subscribe to its events.
  4. If you still call initalizeEncryption(...) or pass encryptionKey into OpenIdConnectClient.create(...), you may keep doing so while upgrading. In 2.x those APIs are compatibility no-ops because endorsed secure storage handles persistence internally.
  5. Review the platform configuration notes below before testing interactive sign-in.

Platform configuration

Redirect URI rules

  • Android / iOS: usually a custom scheme such as my.app://callback
  • macOS: either a custom scheme or a loopback URL such as http://localhost:14100/callback
  • Linux / Windows: a loopback URL such as http://localhost:14100/callback
  • Web: an HTTPS callback page you host, typically /callback.html

Android

  • Requires Android minSdkVersion 23
  • Add the native_authentication callback receiver activity/intent filter for your redirect URI
  • Add INTERNET permission if your app does not already declare it
  • Configure Android App Links as well if you use HTTPS callbacks instead of a custom scheme

Helpful references:

The example Android manifest in this repository shows the callback activity wiring for CallbackReceiverActivity.

Custom-scheme manifest snippet:

<uses-permission android:name="android.permission.INTERNET" />

<application ...>
    <activity
        android:name="dev.celest.native_authentication.CallbackReceiverActivity"
        android:exported="true">
        <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="openidconnect.example"
                android:host="callback" />
        </intent-filter>
    </activity>
</application>

iOS

  • Requires iOS 13.0+
  • Add your custom callback scheme under CFBundleURLTypes in Info.plist, or configure Associated Domains for universal links
  • No OIDC-specific camera/microphone/photo/location permission strings are required by this package

Helpful references:

Custom-scheme Info.plist snippet:

<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleTypeRole</key>
        <string>Editor</string>
        <key>CFBundleURLName</key>
        <string>openidconnect.example</string>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>openidconnect.example</string>
        </array>
    </dict>
</array>

macOS

  • Requires macOS 10.15+
  • Add your custom callback scheme under CFBundleURLTypes in Info.plist, or configure Associated Domains for HTTPS callbacks
  • For sandboxed apps, enable the network entitlements you need, especially outbound client access and loopback/server access if you use localhost callbacks
  • No OIDC-specific privacy usage strings are required by this package

Helpful references:

Custom-scheme Runner/Info.plist snippet:

<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleTypeRole</key>
        <string>Editor</string>
        <key>CFBundleURLName</key>
        <string>openidconnect.example</string>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>openidconnect.example</string>
        </array>
    </dict>
</array>

Sandboxed macOS apps that use localhost callbacks should typically enable:

<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.network.server</key>
<true/>

Linux / Windows

  • Use a loopback redirect URI such as http://localhost:14100/callback
  • Register that exact redirect URI with your identity provider
  • No plist/manifest permission prompts are required by this package itself on these platforms

Web

  1. Copy callback.html from openidconnect_web into the web folder of your app.

  2. Register the exact callback URL, typically https://your-app.example.com/callback.html, with your IdP.

  3. Serve the app from https: or http://localhost so browser secure storage works.

  4. OpenIdConnect web supports both popup and same-tab redirect-loop interactive login. Use the popup flow when authentication starts from a direct user gesture. Use useWebPopup = false when a popup would be blocked, and complete the result via OpenIdConnect.processStartup(...) or OpenIdConnectClient.create(...) after the app reloads.

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. Add more end-to-end coverage around interactive login/logout flows.
  2. 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.

About

Complete Flutter OpenIdConnect Library

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors