Skip to content

Authentication

The apps using the Kamea libs must be authenticated through the identity provider of your choice in order to be able to get the token required to query the API. We're using the Oauth2 authentication flows to authenticate users.

Libs

The Kamea libs use angular-oauth2-oidc lib to manage the authentication process. See the repository for more details.

Front end flow

On startup, the AppComponent initiates the library for authentication like so:

this.authService.configure(environment.oidcConfig);
this.authService
    .loadDiscoveryDocument(environment.oidcWellKnown)
    .then(() => {
        return this.authService.tryLoginCodeFlow();
    })
    .then(() => {
        this.authInitService.initAppAuth$.next(true);
    });
this.authService.setupAutomaticSilentRefresh();

The important part here, is since the lib angular-oauth2-oidc has a bug, you need to set the 'initAppAuth$' to true after you called the loginFlow method.

After which, upon trying to access a protected route (or manually if you wish so), the app navigates to the login component. The login component starts the login flow by redirecting to the external login page. After the users succesfully logs in, the redirectUri is used by Azure, to redirect to the token component, with exchange the code contained in its state for a token that can be used to authenticate when making Kamea API calls.

When you want the user to logout, simply navigate to the logout component. The logout component will then redirect the user to the Azure logout endpoint as configured in your environment, which in turn redirect to the app login.

Mobile and desktop concerns

The authentication flow uses the same code for mobile and desktop. Except that on a Capacitor or Ionic app, you must add a few more elements in your app component, to configure the Deep Links and allow Azure to redirect properly to your application, like so:

  constructor(private authInitService: AuthInitService, private authService: OAuthService, private zone: NgZone, private platform: Platform, private router: Router) {
    if (this.isPlatformAMobileOne()) {
      environment.oidcConfig.redirectUri = "{CUSTOM_DEEP_LINK}://token";
      environment.oidcConfig.postLogoutRedirectUri = "{CUSTOM_DEEP_LINK}://login";
      environment.oidcConfig.openUri = (url) => {
        Browser.open({ url, windowName: "_self" });
      };
      this.initializeDeepLinks();
    }
  }

  initializeDeepLinks() {
    App.addListener('appUrlOpen', (event: URLOpenListenerEvent) => {
      this.zone.run(() => {
        if (!event.url.includes('login')) {
          const state = event.url.split("{CUSTOM_DEEP_LINK}://token/?state=").pop();
          if (state) {
              window.location.href = window.location.origin + "/token?state=" + state;
          }
        } else {
          window.location.href = window.location.origin + "/login";
        }
      });
    });
  }

  isPlatformAMobileOne() {
    for (let i = 0; i < possibleMobilePlatforms.length; i++) {
      if (this.platform.is(possibleMobilePlatforms[i] as any)) {
        return true
      }
    }
    return false;
  }

For mobile, the angular-oauth2-oidc lib has a bug that was avoided with a custom service, see the libs AuthInitService for more details.