Dart & Keycloak

I am so excited to read that the Keycloak JavaScript adapter (see http://www.keycloak.org/downloads.html) now comes bundled with TypeScript definitions. In combination with https://github.com/dart-lang/js_facade_gen it should be possible to generate Dart bindings for the Keycloak adapter. This means easy usage of OpenID Connect and OAuth2 authentication and authorization in Dart web projects using Keycloak for identity and access management.

I haven’t tested the generated bindings yet but I want to demonstrate how to generate the bindings.

  1. Install js_facade_gen
    npm install -g dart_js_facade_gen
  2. Download the Keycloak JavaScript Adapter
    wget https://downloads.jboss.org/keycloak/3.1.0.Final/adapters/keycloak-oidc/keycloak-js-adapter-dist-3.1.0.Final.zip
  3. Unzip the adapterunzip keycloak-js-adapter-dist-3.1.0.Final.zip
  4. Change into the folder
    cd keycloak-js-adapter-dist-3.1.0.Final
  5. Generate the bindings
    dart_js_facade_gen keycloak.d.ts > keycloak.dart

And here we see the generated bindings in all their glory. At the moment, the only caveat is that I don’t know if the generated bindings are functional.

@JS()
library keycloak;

import "package:js/js.dart";

/// Copyright 2017 Red Hat, Inc. and/or its affiliates
/// and other contributors as indicated by the @author tags.
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
/// http://www.apache.org/licenses/LICENSE-2.0
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.

// Module KeycloakModule
@anonymous
@JS()
abstract class Promise {
external Promise success(Function callback);
external Promise error(Function callback);
}

/*export type ResponseModes = "query" | "fragment";*/
/*export type Flows = "standard" | "implicit" | "hybrid";*/
@anonymous
@JS()
abstract class InitOptions {
external bool get checkLoginIframe;
external set checkLoginIframe(bool v);
external num get checkLoginIframeInterval;
external set checkLoginIframeInterval(num v);
external String get onLoad;
external set onLoad(String v);
external String get adapter;
external set adapter(String v);
external String /*'query'|'fragment'*/ get responseMode;
external set responseMode(String /*'query'|'fragment'*/ v);
external String /*'standard'|'implicit'|'hybrid'*/ get flow;
external set flow(String /*'standard'|'implicit'|'hybrid'*/ v);
external String get token;
external set token(String v);
external String get refreshToken;
external set refreshToken(String v);
external String get idToken;
external set idToken(String v);
external num get timeSkew;
external set timeSkew(num v);
external factory InitOptions(
{bool checkLoginIframe,
num checkLoginIframeInterval,
String onLoad,
String adapter,
String /*'query'|'fragment'*/ responseMode,
String /*'standard'|'implicit'|'hybrid'*/ flow,
String token,
String refreshToken,
String idToken,
num timeSkew});
}

@anonymous
@JS()
abstract class LoginOptions {
external String get redirectUri;
external set redirectUri(String v);
external String get prompt;
external set prompt(String v);
external num get maxAge;
external set maxAge(num v);
external String get loginHint;
external set loginHint(String v);
external String get action;
external set action(String v);
external String get locale;
external set locale(String v);
external factory LoginOptions(
{String redirectUri,
String prompt,
num maxAge,
String loginHint,
String action,
String locale});
}

@anonymous
@JS()
abstract class RedirectUriOptions {
external String get redirectUri;
external set redirectUri(String v);
external factory RedirectUriOptions({String redirectUri});
}

@anonymous
@JS()
abstract class KeycloakClient {
external Promise init([InitOptions options]);
external Promise login([LoginOptions options]);
external String createLoginUrl([LoginOptions options]);
external Promise logout([RedirectUriOptions options]);
external String createLogoutUrl([RedirectUriOptions options]);
external Promise register([LoginOptions options]);
external String createRegisterUrl([RedirectUriOptions options]);
external Promise accountManagement();
external String createAccountUrl([RedirectUriOptions options]);
external bool hasRealmRole(String role);
external bool hasResourceRole(String role, [String resource]);
external Promise loadUserProfile();
external bool isTokenExpired(num minValidity);
external Promise updateToken(num minValidity);
external dynamic clearToken();
external String get realm;
external set realm(String v);
external String get clientId;
external set clientId(String v);
external String get authServerUrl;
external set authServerUrl(String v);
external String get token;
external set token(String v);
external dynamic get tokenParsed;
external set tokenParsed(dynamic v);
external String get refreshToken;
external set refreshToken(String v);
external dynamic get refreshTokenParsed;
external set refreshTokenParsed(dynamic v);
external String get idToken;
external set idToken(String v);
external dynamic get idTokenParsed;
external set idTokenParsed(dynamic v);
external dynamic get realmAccess;
external set realmAccess(dynamic v);
external dynamic get resourceAccess;
external set resourceAccess(dynamic v);
external bool get authenticated;
external set authenticated(bool v);
external String get subject;
external set subject(String v);
external num get timeSkew;
external set timeSkew(num v);
external String /*'query'|'fragment'*/ get responseMode;
external set responseMode(String /*'query'|'fragment'*/ v);
external String /*'standard'|'implicit'|'hybrid'*/ get flow;
external set flow(String /*'standard'|'implicit'|'hybrid'*/ v);
external String get responseType;
external set responseType(String v);
external Function get onReady;
external set onReady(Function v);
external Function get onAuthSuccess;
external set onAuthSuccess(Function v);
external Function get onAuthError;
external set onAuthError(Function v);
external Function get onAuthRefreshSuccess;
external set onAuthRefreshSuccess(Function v);
external Function get onAuthRefreshError;
external set onAuthRefreshError(Function v);
external Function get onAuthLogout;
external set onAuthLogout(Function v);
external Function get onTokenExpired;
external set onTokenExpired(Function v);
}

// End module KeycloakModule
@JS()
class Keycloak {
// @Ignore
Keycloak.fakeConstructor$();
external factory Keycloak([dynamic config]);
}

Next step: Build a sample app and test the generated bindings.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Time limit is exhausted. Please reload the CAPTCHA.