2-Step Login

Two-step login can be enforced for users of a certain client in two ways. The first one is configuring the client in the resource registry to do so. In this case, the edu-ID OP requires two factors for each user of the client, no matter what is specified in the authentication request.

However, the edu-ID OIDC implementation also supports the use of essential id_token claim request for acr. By adding the following parameter to the OIDC authentication request, a Relying Party can enforce Two-Step Login for users that want to access the service:

claims=%7B%22id_token%22%3A%7B%22acr%22%3A%20%7B%22essential%22%3A%20true%2C%22values%22%3A%20%5B%22https%3A%2F%2Frefeds.org%2Fprofile%2Fmfa%22%5D%7D%7D%7D

URL-encoded version of:

claims = 
{
  "id_token":
  {
    "acr": 
{ "essential": true, "values": ["https://refeds.org/profile/mfa"] } } }

Reference 5.5.1.1 Requesting the 'acr' claim

Like this, a client is able to enforce 2FA only in some situations or for some users while not enforcing it for others.

We provide examples extending the configurations from above:

Just enable the OIDCProviderAuthorizationEndpoint in the configuration file:

OIDCProviderAuthorizationEndpoint https://login.test.eduid.ch/idp/profile/oidc/authorize?claims=%7B%22id_token%22%3A%7B%22acr%22%3A%20%7B%22essential%22%3A%20true%2C%22values%22%3A%20%5B%22https%3A%2F%2Frefeds.org%2Fprofile%2Fmfa%22%5D%7D%7D%7D

To enforce two-step login, add the above acr claim to the original authentication request. This also works for users already authenticated in the service for whom the second factor is subsequently requested.

Specify the authorization URI in addition to the issuer URI.

spring:
  security:
    oauth2:
      client:
        registration:
          eduid:
            client-id: my_unique_client_id
            scope: openid,profile,email
            authorization-grant-type: authorization_code
            redirect-uri: https://example.com/protected/redirect_uri
            client-authentication-method: private_key_jwt
            client-name: my_client_name
        provider:
          eduid:
            issuer-uri: https://login.test.eduid.ch/
            authorization-uri: https://login.test.eduid.ch/idp/profile/oidc/authorize?claims=%7B%22id_token%22%3A%7B%22acr%22%3A%20%7B%22essential%22%3A%20true%2C%22values%22%3A%20%5B%22https%3A%2F%2Frefeds.org%2Fprofile%2Fmfa%22%5D%7D%7D%7D
ngOnInit(): void {
    this.oauthService.configure(authCodeFlowConfig);
    this.oauthService.loadDiscoveryDocument();

    // Need to adjust the login URL after loading the Discovery Document (.well-known/openid-configuration)
    this.oauthService.loginUrl = 'https://login.test.eduid.ch/idp/profile/oidc/authorize?claims=%7B%22id_token%22%3A%7B%22acr%22%3A%20%7B%22essential%22%3A%20true%2C%22values%22%3A%20%5B%22https%3A%2F%2Frefeds.org%2Fprofile%2Fmfa%22%5D%7D%7D%7D',

    this.oauthService.initLoginFlow();

    // Automatically load user profile
    this.oauthService.events
      .pipe(filter((e) => e.type === 'token_received'))
      .subscribe((_) => this.oauthService.loadUserProfile());
  }