Skip to content

Keycloak Config

Andre Pestana edited this page Dec 6, 2024 · 45 revisions

Useful links

Instances

SSO Team

BSCS Integration

Configuring a Keycloak instance

Getting access

  1. Access the master instance with your IDIR account (SSO Team needed to provide access).
  2. Configure the IDIR identity provider and give realm administrator access to your own user.
  3. Access the console link to execute further configurations.

Reference: https://stackoverflow.developer.gov.bc.ca/questions/939/940

Identity Providers

IDIR

This is the only IDP that must be configured while in the master instance.

  • Create a new identity provider as shown below.

image

  • Set the below properties and leave the others with the default values, setting [dev/test] accordingly to the environment.
    • Alias: idir
    • Display name: idir
    • First login flow: first broker login
    • Sync Mode: force
    • Authorization URL: https://[dev/test].loginproxy.gov.bc.ca/auth/realms/standard/protocol/openid-connect/auth?kc_idp_hint=idir
    • Token URL: https://[dev/test].loginproxy.gov.bc.ca/auth/realms/standard/protocol/openid-connect/token
    • Logout URL: https://[dev/test].loginproxy.gov.bc.ca/auth/realms/standard/protocol/openid-connect/logout
    • User Info URL: https://[dev/test].loginproxy.gov.bc.ca/auth/realms/standard/protocol/openid-connect/userinfo
    • Client Authentication: Client secret sent as post
    • Client ID: provided using the Common Hosted Single Sign-on portal (how to get client/secret).
    • Client Secret: provided using the Common Hosted Single Sign-on portal (how to get client/secret).
    • Validate Signatures: true
    • Use JWKS URL: true
    • JWKS URL: https://[dev/test].loginproxy.gov.bc.ca/auth/realms/standard/protocol/openid-connect/certs
  • Once the IDIR identity provider is configured, find the user and associate the /Realm Administrator role to it. image
  • The remaining configurations can be done using the console link.

Where to find credentials (Client ID/Secret)

Access the BCeID - Common Hosted Single Sign-on (CSS) and look for the below information.

image

Configuring mappers

  • identity_provider
    • name: identity_provider
    • Sync Mode: force,
    • Mapper Type: Attribute Importer
    • Claim: identity_provider
    • User Attribute Name: identityProvider

BCeID (basic/business)

  • Create a new identity provider as shown below.

image

  • Set the below properties and leave the others with the default values. As per team decision DEV/TEST is pointing to TEST.
    • Alias: bceidboth
    • Display name: bceidboth
    • First login flow: first broker login
    • Sync Mode: force
    • Authorization URL: https://[dev/test].loginproxy.gov.bc.ca/auth/realms/standard/protocol/openid-connect/auth?kc_idp_hint=bceidboth
    • Token URL: https://[dev/test].loginproxy.gov.bc.ca/auth/realms/standard/protocol/openid-connect/token
    • Logout URL: https://[dev/test].loginproxy.gov.bc.ca/auth/realms/standard/protocol/openid-connect/logout
    • User Info URL: https://[dev/test].loginproxy.gov.bc.ca/auth/realms/standard/protocol/openid-connect/userinfo
    • Client Authentication: Client secret sent as post
    • Client ID: provided using the Common Hosted Single Sign-on portal (how to get client/secret).
    • Client Secret: provided using the Common Hosted Single Sign-on portal (how to get client/secret).
    • Validate Signatures: true
    • Use JWKS URL: true
    • JWKS URL: https://[dev/test].loginproxy.gov.bc.ca/auth/realms/standard/protocol/openid-connect/certs

Configuring mappers

  • identity_provider
    • name: identity_provider
    • Sync Mode: force,
    • Mapper Type: Attribute Importer
    • Claim: identity_provider
    • User Attribute Name: identity_provider
  • bceid_username
    • name: bceid_username
    • Sync Mode: force,
    • Mapper Type: Attribute Importer
    • Claim: bceid_username
    • User Attribute Name: idp_user_name
  • bceid_business_guid
    • name: bceid_business_guid
    • Sync Mode: force,
    • Mapper Type: Attribute Importer
    • Claim: bceid_business_guid
    • User Attribute Name: bceid_business_guid

BCSC

  • Create a new identity provider as shown below.

image

Configuring mappers

  • identity_provider
    • name: identity_provider
    • Sync Mode: force,
    • Mapper Type: Hardcoded Attribute
    • Claim: identity_provider
    • User Attribute Name: bcsc
  • birthdate
    • name: birthdate
    • Sync Mode: force,
    • Mapper Type: Attribute Importer
    • Claim: birthdate
    • User Attribute Name: birthdate
  • firstName
    • name: firstName
    • Sync Mode: force,
    • Mapper Type: Attribute Importer
    • Claim: given_names
    • User Attribute Name: firstName
  • lastName
    • name: lastName
    • Sync Mode: force,
    • Mapper Type: Attribute Importer
    • Claim: family_name
    • User Attribute Name: lastName
  • username
    • name: username
    • Sync Mode: force,
    • Mapper Type: Username Template Importer
    • Template: ${CLAIM.sub}@bcsc

Client Scopes

  • business-bceid
    • Settings
      • Name: business-bceid
      • Protocol: openid-connect
    • Mappers
      • BCeID Business Guid
        • Name: BCeID Business Guid
        • Mapper Type: User Attribute
        • Token Claim Name: bceid_business_guid
  • client-roles
    • Settings
      • Name: client-roles
      • Protocol: openid-connect
    • Mappers
      • client-roles
        • Name: BCeID Business Guid
        • Mapper Type: User Client Role
        • Token Claim Name: resource_access.${client_id}.roles
  • identity-provider
    • Settings
      • Name: identity-provider
      • Protocol: openid-connect
    • Mappers
      • idpUsername
        • Name: idpUsername
        • Mapper Type: User Attribute
        • User Attribute: idp_user_name
        • Token Claim Name: idp_user_name
        • Claim JSON Type: String
      • Identity Provider
        • Name: Identity Provider
        • Mapper Type: User Attribute
        • User Attribute: identity_provider
        • Token Claim Name: identity_provider
        • Claim JSON Type: String
  • default-name-scope
    • Settings
      • Name: default-name-scope
      • Protocol: openid-connect
    • Mappers
      • lastName
        • Name: lastName
        • Mapper Type: User Property
        • Property: lastName
        • Token Claim Name: lastName
        • Claim JSON Type: String
      • givenNames
        • Name: givenNames
        • Mapper Type: User Property
        • Property: firstName
        • Token Claim Name: givenNames
        • Claim JSON Type: String
  • username
    • Settings
      • Name: username
      • Protocol: openid-connect
    • Mappers
      • userName
        • Name: userName
        • Mapper Type: User Property
        • Property: username
        • Token Claim Name: userName
        • Claim JSON Type: String
  • sims-api-audience-scope
    • Settings
      • Name: sims-api-audience-scope
      • Protocol: openid-connect
    • Mappers
      • sims-api-audience
        • Name: sims-api-audience
        • Mapper Type: Audience
        • Included Custom Audience: sims-api
  • load-test-gateway-audience-scope(!!STRICTLY FOR DEV ENVIRONMENT ONLY!!)
    • Settings
      • Name: load-test-gateway-audience-scope
      • Protocol: openid-connect
    • Mappers
      • load-test-gateway
        • Name: load-test-gateway
        • Mapper Type: Audience
        • Included Custom Audience: load-test-gateway

Allowing mononymous names

By default, if the identity provider does not provide all information to create an account, the user will be redirected to a screen to provide the missing information. To allow users with mononymous names (where the first name is not present), we should disable this behavior, as shown below.

image

Clients

Ministry (AEST)

  • Create the client as below.

image

  • Set the below properties
    • Access Type: public
    • Valid Redirect URIs:
      • https://[dev/test].sims.studentaidbc.ca/*
      • https://[dev/test]-aest-sims.apps.silver.devops.gov.bc.ca/* (to be removed)
      • http://localhost:8080/* (do not add it for PROD)
    • Web Origins:
      • https://[dev/test].sims.studentaidbc.ca
      • https://[dev/test]-aest-sims.apps.silver.devops.gov.bc.ca (to be removed)
      • http://localhost:8080/* (do not add it for PROD)
    • Backchannel Logout Session Required: false
  • Disable "Full Scope Allowed" as shown below.

image

  • Configure Client Scopes as shown below.

image

Groups configurations

The Ministry client is the only one currently using Keycloak groups and roles. The list of groups and roles is kept in the internal Microsoft Teams files General>Files>Analisys>SIMS Users Profiles and Access Permissions.

The below mappers must be created to have "groups" presents on the token.

image image

The roles must be created as shown below.

image

The groups must be created as below.

image

For every group, the specific roles must be configured under the specific client, as shown below.

image

Institution

  • Create the client as below.

image

  • Set the below properties
    • Access Type: public
    • Valid Redirect URIs:
      • https://[dev/test].sims.studentaidbc.ca/*
      • https://[dev/test]-aest-sims.apps.silver.devops.gov.bc.ca/* (to be removed)
      • http://localhost:8080/* (do not add it for PROD)
    • Web Origins:
      • https://[dev/test].sims.studentaidbc.ca
      • https://[dev/test]-aest-sims.apps.silver.devops.gov.bc.ca (to be removed)
      • http://localhost:8080 (do not add it for PROD)
    • Backchannel Logout Session Required: false
  • Configure Client Scopes as shown below.

image

Students

  • Create the client as below.

image

  • Set the below properties
    • Access Type: public
    • Valid Redirect URIs:
      • https://[dev/test].sims.studentaidbc.ca/*
      • https://[dev/test]-aest-sims.apps.silver.devops.gov.bc.ca/* (to be removed)
      • http://localhost:8080/* (do not add it for PROD)
    • Web Origins:
      • https://[dev/test].sims.studentaidbc.ca
      • https://[dev/test]-aest-sims.apps.silver.devops.gov.bc.ca (to be removed)
      • http://localhost:8080 (do not add it for PROD)
    • Backchannel Logout Session Required: false
  • Configure Client Scopes as shown below.

image

Supporting Users (Parent/Partners)

  • Create the client as below.

image

  • Set the below properties
    • Access Type: public
    • Valid Redirect URIs:
      • https://[dev/test].sims.studentaidbc.ca/*
      • https://[dev/test]-aest-sims.apps.silver.devops.gov.bc.ca/* (to be removed)
      • http://localhost:8080/* (do not add it for PROD)
    • Web Origins:
      • https://[dev/test].sims.studentaidbc.ca
      • https://[dev/test]-aest-sims.apps.silver.devops.gov.bc.ca (to be removed)
      • http://localhost:8080 (do not add it for PROD)
    • Backchannel Logout Session Required: false
  • Configure Client Scopes as shown below.

image

Load test gateway (!!STRICTLY FOR DEV ENVIRONMENT ONLY!!)

  • Create the client as below.

image

  • Set the below properties

    • Access Type: confidential
    • Service Accounts Enabled: ON
    • Valid Redirect URIs:
      • https://[dev/test]-aest-sims.apps.silver.devops.gov.bc.ca/*
  • Make sure in credentials tab the right client authenticator is selected image

  • Configure Client Scopes as shown below.

image

Allowing duplicated user emails

Out-of-box Keycloak is configured to prevent two users to be created using the same email. If the second user is tried to be created and the same email is already associated with a different user, the below error will be displayed on the screen.

image

For non-production environment tests users can share many times the same email. To allow the email duplication we need to explicitly have it configured as below.

image

External API access (service accounts)

This section explains how to create a service account for external clients to access external SIMS API endpoints (https://[dev/test].sims.studentaidbc.ca/external/swagger).

Required client scopes

Some specific client scopes are required for external service accounts. Please create them before creating the external service account.

external-azp-scope

  • Click on "Client scopes" and then on "Create client scope". Then fill in "Name" with "external-azp-scope".

image

  • Go to "Mappers" tab and click on "Configure a new mapper".;
  • Select "Hardcoded claim" in "Mapper type". In "Name" type "external-azp-mapper", in "Token Claim Name" type "azp", in "Claim value" type "external" and click on "Save";

image

sims-api-external-audience-scope

  • Click on "Client scopes" and then on "Create client scope". Then fill in "Name" with "sims-api-external-audience-scope".

image

  • Go to "Mappers" tab and click on "Configure a new mapper";
  • Select "Audience" in "Mapper type". In "Name" type "sims-api-external-audience", in "Included Custom Audience" type "sims-api-external" and click on "Save";

image

Service account client creation

  • On Keycloak, go to Clients and click on "Create client";
  • Type the client ID and click on "Next";

image

  • Turn "Client authentication" on, disable "Standard flow" and "Direct access grants", select "Service accounts roles" and click on "Next";

image

  • Click on "Save" button;

image

  • Select the "Client scopes" tab, remove all client scopes but <clientId>-dedicated and click on "Add client scope" button;
  • Select "sims-api-audience-scope", "sims-api-external-audience-scope", "external-azp-scope" and click on "Add" and select "Default";

image

  • The credentials can be obtained from the "Credentials" tab. The client ID is the service account name and the secret can be copied form "Client Secret" field or regenerated by clicking on "Regenerate" button.

image

Testing / Troubleshooting

  • Generate a token using the clientId/secret;

image

  • Go to https://jwt.io and paste the access token. The attribute "aud" should contain "sims-api" and "sims-api-external". The attribute "azp" should have the value "external";

image