Git Product home page Git Product logo

ember-acmidm-login's Introduction

ember-acmidm-login

Ember addon providing an Ember Simple Auth authenticator for ACM/IDM in a semantic.works stack.

Tutorials

Install the addon in your application

To add the ember-acmidm-login addon to your application, execute the following install commands:

ember install @lblod/ember-acmidm-login
npm install ember-simple-auth@6

Make sure you've configured the acmidm-login-service (or any fork) correctly in your project. The addon currently requires the service endpoints to be available under /sessions.

Configure the following variables via ENV.acmidm in config/environment.js. The values must match the config provided to the backend login service.

// config/environment.js

module.exports = function (environment) {
  const ENV = {
    ...,
    acmidm: {
      clientId: 'your-client-id',
      baseUrl: 'https://authenticatie.vlaanderen.be/op/v1/auth',
      redirectUrl: 'https://myapp.vlaanderen.be/authorization/callback',
      logoutUrl: 'https://authenticatie.vlaanderen.be/op/v1/logout',
      scope: 'openid vo profile'
    }
  };
}

In your application route initialize the Ember Simple Auth session service:

// app/routes/application.js

import Route from '@ember/routing/route';
import { service } from '@ember/service';

export default class ApplicationRoute extends Route {
  @service session;

  beforeModel() {
    return this.session.setup();
  }
}

How-to guides

Add login to your app

First step is to create a login link/button which redirects to ACM/IDM. The login URL can be constructed as follows in the controller/component where you want to show a login button:

import Controller from '@ember/controller';
import ENV from 'your-app/config/environment';
import buildUrlFromConfig from '@lblod/ember-acmidm-login/utils/build-url-from-config';

export default class LoginController extends Controller {
  loginUrl = buildUrlFromConfig(ENV.acmidm);
}

In the template simply add the following:

<a href={{this.loginUrl}}>Login</a>

Next, set up a route and controller to handle the callback from ACM/IDM after authentication. The route must match the path of the redirect URL and will receive an authorization code as query param:

// app/routes/authentication/callback.js
import Route from '@ember/routing/route';
import { service } from '@ember/service';

export default class AuthenticationCallbackRoute extends Route {
  @service session;

  beforeModel() {
    // redirect to index if already authenticated
    this.session.prohibitAuthentication('index');
  }

  model(params) {
    this.session.authenticate('authenticator:acm-idm', params.code);
  }
}
// app/controllers/authentication/callback.js
import Controller from '@ember/controller';

export default class AuthenticationCallbackController extends Controller {
  queryParams = ['code'];
}

The model hook will pass the authorization code to the ACM/IDM authenticator which will on its turn communicate with the backend to log in the user.

Have a look at the Ember Simple Auth documentation to learn how to protect your routes from unauthenticated access.

Add a logout button to your app

Create a controller (or component) that injects the session service and handles a session invalidation action as follows:

// app/controllers/application.js
import Controller from '@ember/controller';
import { service } from '@ember/service';
import { action } from '@ember/object';

export default class ApplicationController extends Controller {
  @service session;

  @action
  async invalidateSession() {
    try {
      await this.session.invalidate();
    }
    catch(e) {
      // error handling
    }
  }
}

Next, show a logout button on your page if the user is logged in

{{!-- app/templates/application.hbs --}}
{{#if this.session.isAuthenticated}}
  <a {{on "click" this.invalidateSession}}>Logout</a>
{{/if}}

Finally, we need to make sure to terminate the session on the ACM/IDM side as well by redirecting the user to a logout URL when the session gets invalidated. To do so, extend Ember Simple Auth's session service to hook into the handleInvalidation event:

// app/services/session.js
import BaseSessionService from 'ember-simple-auth/services/session';
import ENV from 'your-app/config/environment';

export default class SessionService extends BaseSessionService {
  handleInvalidation() {
    const logoutUrl = ENV.acmidm.logoutUrl;
    super.handleInvalidation(logoutUrl);
  }
}

Load user information on authentication

Extend Ember Simple Auth's session service to hook into the handleAuthentication event and request some user info from the backend. For example:

// app/services/session.js
import { service } from '@ember/service';
import BaseSessionService from 'ember-simple-auth/services/session';

export default class SessionService extends BaseSessionService {
  @service userInfo;

  handleAuthentication(routeAfterAuthentication) {
    super.handleAuthentication(routeAfterAuthentication);
    // do anything you want to load user info from the backend
    this.userInfo.load();
  }
}

Switch sessions via ACM/IDM

Sometimes an app needs to allow users to switch their session (e.g. to another administrative unit they belong to). In this scenario, the session in our application will be ended and the user is redirected to an URL on ACM/IDM where he can execute the switch. ACM/IDM will then call the callback URL and the user gets logged in with his new identity as in the regular login flow.

First, add a switchUrl to the acmidm config in config/environment.js:

// config/environment.js 

  ENV.acmidm = {
    ... // other config
    switchRedirectUrl: 'url-to-your-callback-route'
  };

Next, set up a route authentication.switch which will redirect the user to the switch URL of ACM/IDM.

// app/routes/authentication/switch.js
import Route from '@ember/routing/route';
import { service } from '@ember/service';
import ENV from 'your-app/config/environment';
import buildSwitchUrlFromConfig from '@lblod/ember-acmidm-login/utils/build-switch-url-from-config';

export default class AuthenticationSwitchRoute extends Route {
  @service router;
  @service session;

  async beforeModel(transition) {
    // ensure the user is logged in
    this.session.requireAuthentication(transition, 'login');

    try {
      await this.session.invalidate();
      const switchURL = buildSwitchUrlFromConfig(ENV.acmidm);
      window.location.replace(switchURL);
    } catch (error) {
      // Handle error
    }
  }
}

Finally, add a link to the switch-route in your template

<LinkTo route="authentication.switch">Switch session</LinkTo>

Reference

Configuration

The following options can be configured via the ENV.acmidm object in config/environment.js. It's important that the values match the configuration of the backend login service.

The following options are required:

The following options can be optionally provided:

  • logoutUrl: ACM/IDM logout endpoint, typically https://authenticatie.vlaanderen.be/op/v1/logout
  • switchRedirectUrl: URL of the page ACM/IDM needs to redirect to after switching. You'll need to set up a route to capture this. Typically the same value as for redirectUrl can be used.

ember-acmidm-login's People

Contributors

erikap avatar nvdk avatar windvis avatar dependabot[bot] avatar claire-lovisa avatar mietcls avatar sergiofenoll avatar ember-tomster avatar madnificent avatar elpoelma avatar valenberghssven avatar

Stargazers

Youssef avatar Achraf Atauil avatar

Watchers

 avatar Pieter Colpaert avatar James Cloos avatar  avatar  avatar Dieter Peirs avatar  avatar Michaël Dierick avatar Dries Hugaerts avatar Ben avatar Sergey Andreev avatar Oscar Rodriguez Villalobos avatar Mehran Naghizadeh avatar  avatar

ember-acmidm-login's Issues

depends on webuniversum

this addon currently relies on the wu-button component provided by ember-webuniversum, we should either replace it with an appuniversum equivalent or use a regular button with the appropriate classes.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.