Skip to content
This repository has been archived by the owner on Nov 16, 2022. It is now read-only.

KeycloakAPIAuthenticationFlow ID not set #445

Closed
Robbilie opened this issue Jan 13, 2022 · 4 comments
Closed

KeycloakAPIAuthenticationFlow ID not set #445

Robbilie opened this issue Jan 13, 2022 · 4 comments
Assignees
Labels

Comments

@Robbilie
Copy link
Contributor

Describe the bug

When defining a KeycloakAPIAuthenticationFlow on the Realm object there is a property to define the ID. When configuring that and applying the Realm Ressource (not existing prior to that) the Flow is created but the ID is a different one from the configured one.

Sadly that makes overwriting the default flow on a client impossible…

Version

15.1.1

Expected behavior

The Flow in Keycloak has the configured ID.

Actual behavior

The Flow in Keycloak has a newly generated ID.

How to Reproduce?

Apply this yaml and check the x509 flow:

apiVersion: keycloak.org/v1alpha1
kind: KeycloakRealm
metadata:
  name: testrealm
  labels:
    realm: testrealm
spec:
  realm:
    realm: "testrealm"
    enabled: True
    displayName: "testrealm Realm"
    userManagedAccessAllowed: true
    clientScopes:
      - name: web-origins
        description: OpenID Connect scope for add allowed web origins to the access token
        protocol: openid-connect
        attributes:
          include.in.token.scope: 'false'
          display.on.consent.screen: 'false'
          consent.screen.text: ''
        protocolMappers:
          - name: allowed web origins
            protocol: openid-connect
            protocolMapper: oidc-allowed-origins-mapper
            consentRequired: false
            config: {}
      - name: email
        description: 'OpenID Connect built-in scope: email'
        protocol: openid-connect
        attributes:
          include.in.token.scope: 'true'
          display.on.consent.screen: 'true'
          consent.screen.text: "${emailScopeConsentText}"
        protocolMappers:
          - name: email verified
            protocol: openid-connect
            protocolMapper: oidc-usermodel-property-mapper
            consentRequired: false
            config:
              userinfo.token.claim: 'true'
              user.attribute: emailVerified
              id.token.claim: 'true'
              access.token.claim: 'true'
              claim.name: email_verified
              jsonType.label: boolean
          - name: email
            protocol: openid-connect
            protocolMapper: oidc-usermodel-property-mapper
            consentRequired: false
            config:
              userinfo.token.claim: 'true'
              user.attribute: email
              id.token.claim: 'true'
              access.token.claim: 'true'
              claim.name: email
              jsonType.label: String
      - name: role_list
        description: SAML role list
        protocol: saml
        attributes:
          consent.screen.text: "${samlRoleListScopeConsentText}"
          display.on.consent.screen: 'true'
        protocolMappers:
          - name: role list
            protocol: saml
            protocolMapper: saml-role-list-mapper
            consentRequired: false
            config:
              single: 'false'
              attribute.nameformat: Basic
              attribute.name: Role
      - name: mqtt
        description: OpenID Connect scope to allow connecting to the mqtt broker
        protocol: openid-connect
        attributes:
          include.in.token.scope: 'true'
          display.on.consent.screen: 'false'
      - name: roles
        description: OpenID Connect scope for add user roles to the access token
        protocol: openid-connect
        attributes:
          include.in.token.scope: 'false'
          display.on.consent.screen: 'true'
          consent.screen.text: "${rolesScopeConsentText}"
        protocolMappers:
          - name: realm roles
            protocol: openid-connect
            protocolMapper: oidc-usermodel-realm-role-mapper
            consentRequired: false
            config:
              user.attribute: foo
              access.token.claim: 'true'
              claim.name: realm_access.roles
              jsonType.label: String
              multivalued: 'true'
          - name: audience resolve
            protocol: openid-connect
            protocolMapper: oidc-audience-resolve-mapper
            consentRequired: false
            config: {}
          - name: client roles
            protocol: openid-connect
            protocolMapper: oidc-usermodel-client-role-mapper
            consentRequired: false
            config:
              user.attribute: foo
              access.token.claim: 'true'
              claim.name: resource_access.${client_id}.roles
              jsonType.label: String
              multivalued: 'true'
      - name: microprofile-jwt
        description: Microprofile - JWT built-in scope
        protocol: openid-connect
        attributes:
          include.in.token.scope: 'true'
          display.on.consent.screen: 'false'
        protocolMappers:
          - name: groups
            protocol: openid-connect
            protocolMapper: oidc-usermodel-realm-role-mapper
            consentRequired: false
            config:
              multivalued: 'true'
              user.attribute: foo
              id.token.claim: 'true'
              access.token.claim: 'true'
              claim.name: groups
              jsonType.label: String
          - name: upn
            protocol: openid-connect
            protocolMapper: oidc-usermodel-property-mapper
            consentRequired: false
            config:
              userinfo.token.claim: 'true'
              user.attribute: username
              id.token.claim: 'true'
              access.token.claim: 'true'
              claim.name: upn
              jsonType.label: String
      - name: phone
        description: 'OpenID Connect built-in scope: phone'
        protocol: openid-connect
        attributes:
          include.in.token.scope: 'true'
          display.on.consent.screen: 'true'
          consent.screen.text: "${phoneScopeConsentText}"
        protocolMappers:
          - name: phone number verified
            protocol: openid-connect
            protocolMapper: oidc-usermodel-attribute-mapper
            consentRequired: false
            config:
              userinfo.token.claim: 'true'
              user.attribute: phoneNumberVerified
              id.token.claim: 'true'
              access.token.claim: 'true'
              claim.name: phone_number_verified
              jsonType.label: boolean
          - name: phone number
            protocol: openid-connect
            protocolMapper: oidc-usermodel-attribute-mapper
            consentRequired: false
            config:
              userinfo.token.claim: 'true'
              user.attribute: phoneNumber
              id.token.claim: 'true'
              access.token.claim: 'true'
              claim.name: phone_number
              jsonType.label: String
      - name: offline_access
        description: 'OpenID Connect built-in scope: offline_access'
        protocol: openid-connect
        attributes:
          consent.screen.text: "${offlineAccessScopeConsentText}"
          display.on.consent.screen: 'true'
      - name: address
        description: 'OpenID Connect built-in scope: address'
        protocol: openid-connect
        attributes:
          include.in.token.scope: 'true'
          display.on.consent.screen: 'true'
          consent.screen.text: "${addressScopeConsentText}"
        protocolMappers:
          - name: address
            protocol: openid-connect
            protocolMapper: oidc-address-mapper
            consentRequired: false
            config:
              user.attribute.formatted: formatted
              user.attribute.country: country
              user.attribute.postal_code: postal_code
              userinfo.token.claim: 'true'
              user.attribute.street: street
              id.token.claim: 'true'
              user.attribute.region: region
              access.token.claim: 'true'
              user.attribute.locality: locality
      - name: profile
        description: 'OpenID Connect built-in scope: profile'
        protocol: openid-connect
        attributes:
          include.in.token.scope: 'true'
          display.on.consent.screen: 'true'
          consent.screen.text: "${profileScopeConsentText}"
        protocolMappers:
          - name: nickname
            protocol: openid-connect
            protocolMapper: oidc-usermodel-attribute-mapper
            consentRequired: false
            config:
              userinfo.token.claim: 'true'
              user.attribute: nickname
              id.token.claim: 'true'
              access.token.claim: 'true'
              claim.name: nickname
              jsonType.label: String
          - name: gender
            protocol: openid-connect
            protocolMapper: oidc-usermodel-attribute-mapper
            consentRequired: false
            config:
              userinfo.token.claim: 'true'
              user.attribute: gender
              id.token.claim: 'true'
              access.token.claim: 'true'
              claim.name: gender
              jsonType.label: String
          - name: website
            protocol: openid-connect
            protocolMapper: oidc-usermodel-attribute-mapper
            consentRequired: false
            config:
              userinfo.token.claim: 'true'
              user.attribute: website
              id.token.claim: 'true'
              access.token.claim: 'true'
              claim.name: website
              jsonType.label: String
          - name: picture
            protocol: openid-connect
            protocolMapper: oidc-usermodel-attribute-mapper
            consentRequired: false
            config:
              userinfo.token.claim: 'true'
              user.attribute: picture
              id.token.claim: 'true'
              access.token.claim: 'true'
              claim.name: picture
              jsonType.label: String
          - name: zoneinfo
            protocol: openid-connect
            protocolMapper: oidc-usermodel-attribute-mapper
            consentRequired: false
            config:
              userinfo.token.claim: 'true'
              user.attribute: zoneinfo
              id.token.claim: 'true'
              access.token.claim: 'true'
              claim.name: zoneinfo
              jsonType.label: String
          - name: family name
            protocol: openid-connect
            protocolMapper: oidc-usermodel-property-mapper
            consentRequired: false
            config:
              userinfo.token.claim: 'true'
              user.attribute: lastName
              id.token.claim: 'true'
              access.token.claim: 'true'
              claim.name: family_name
              jsonType.label: String
          - name: updated at
            protocol: openid-connect
            protocolMapper: oidc-usermodel-attribute-mapper
            consentRequired: false
            config:
              userinfo.token.claim: 'true'
              user.attribute: updatedAt
              id.token.claim: 'true'
              access.token.claim: 'true'
              claim.name: updated_at
              jsonType.label: String
          - name: username
            protocol: openid-connect
            protocolMapper: oidc-usermodel-property-mapper
            consentRequired: false
            config:
              userinfo.token.claim: 'true'
              user.attribute: username
              id.token.claim: 'true'
              access.token.claim: 'true'
              claim.name: preferred_username
              jsonType.label: String
          - name: given name
            protocol: openid-connect
            protocolMapper: oidc-usermodel-property-mapper
            consentRequired: false
            config:
              userinfo.token.claim: 'true'
              user.attribute: firstName
              id.token.claim: 'true'
              access.token.claim: 'true'
              claim.name: given_name
              jsonType.label: String
          - name: middle name
            protocol: openid-connect
            protocolMapper: oidc-usermodel-attribute-mapper
            consentRequired: false
            config:
              userinfo.token.claim: 'true'
              user.attribute: middleName
              id.token.claim: 'true'
              access.token.claim: 'true'
              claim.name: middle_name
              jsonType.label: String
          - name: profile
            protocol: openid-connect
            protocolMapper: oidc-usermodel-attribute-mapper
            consentRequired: false
            config:
              userinfo.token.claim: 'true'
              user.attribute: profile
              id.token.claim: 'true'
              access.token.claim: 'true'
              claim.name: profile
              jsonType.label: String
          - name: birthdate
            protocol: openid-connect
            protocolMapper: oidc-usermodel-attribute-mapper
            consentRequired: false
            config:
              userinfo.token.claim: 'true'
              user.attribute: birthdate
              id.token.claim: 'true'
              access.token.claim: 'true'
              claim.name: birthdate
              jsonType.label: String
          - name: full name
            protocol: openid-connect
            protocolMapper: oidc-full-name-mapper
            consentRequired: false
            config:
              id.token.claim: 'true'
              access.token.claim: 'true'
              userinfo.token.claim: 'true'
          - name: locale
            protocol: openid-connect
            protocolMapper: oidc-usermodel-attribute-mapper
            consentRequired: false
            config:
              userinfo.token.claim: 'true'
              user.attribute: locale
              id.token.claim: 'true'
              access.token.claim: 'true'
              claim.name: locale
              jsonType.label: String
    authenticationFlows:
      - alias: Account verification options
        description: Method with which to verity the existing account
        providerId: basic-flow
        topLevel: false
        builtIn: true
        authenticationExecutions:
          - authenticator: idp-email-verification
            authenticatorFlow: false
            requirement: ALTERNATIVE
            priority: 10
            userSetupAllowed: false
          - authenticatorFlow: true
            requirement: ALTERNATIVE
            priority: 20
            flowAlias: Verify Existing Account by Re-authentication
            userSetupAllowed: false
      - alias: Authentication Options
        description: Authentication options.
        providerId: basic-flow
        topLevel: false
        builtIn: true
        authenticationExecutions:
          - authenticator: basic-auth
            authenticatorFlow: false
            requirement: REQUIRED
            priority: 10
            userSetupAllowed: false
          - authenticator: basic-auth-otp
            authenticatorFlow: false
            requirement: DISABLED
            priority: 20
            userSetupAllowed: false
          - authenticator: auth-spnego
            authenticatorFlow: false
            requirement: DISABLED
            priority: 30
            userSetupAllowed: false
      - alias: Browser - Conditional OTP
        description: Flow to determine if the OTP is required for the authentication
        providerId: basic-flow
        topLevel: false
        builtIn: true
        authenticationExecutions:
          - authenticator: conditional-user-configured
            authenticatorFlow: false
            requirement: REQUIRED
            priority: 10
            userSetupAllowed: false
          - authenticator: auth-otp-form
            authenticatorFlow: false
            requirement: REQUIRED
            priority: 20
            userSetupAllowed: false
      - alias: Direct Grant - Conditional OTP
        description: Flow to determine if the OTP is required for the authentication
        providerId: basic-flow
        topLevel: false
        builtIn: true
        authenticationExecutions:
          - authenticator: conditional-user-configured
            authenticatorFlow: false
            requirement: REQUIRED
            priority: 10
            userSetupAllowed: false
          - authenticator: direct-grant-validate-otp
            authenticatorFlow: false
            requirement: REQUIRED
            priority: 20
            userSetupAllowed: false
      - alias: First broker login - Conditional OTP
        description: Flow to determine if the OTP is required for the authentication
        providerId: basic-flow
        topLevel: false
        builtIn: true
        authenticationExecutions:
          - authenticator: conditional-user-configured
            authenticatorFlow: false
            requirement: REQUIRED
            priority: 10
            userSetupAllowed: false
          - authenticator: auth-otp-form
            authenticatorFlow: false
            requirement: REQUIRED
            priority: 20
            userSetupAllowed: false
      - alias: Handle Existing Account
        description: Handle what to do if there is existing account with same email/username
          like authenticated identity provider
        providerId: basic-flow
        topLevel: false
        builtIn: true
        authenticationExecutions:
          - authenticator: idp-confirm-link
            authenticatorFlow: false
            requirement: REQUIRED
            priority: 10
            userSetupAllowed: false
          - authenticatorFlow: true
            requirement: REQUIRED
            priority: 20
            flowAlias: Account verification options
            userSetupAllowed: false
      - alias: Reset - Conditional OTP
        description: Flow to determine if the OTP should be reset or not. Set to REQUIRED
          to force.
        providerId: basic-flow
        topLevel: false
        builtIn: true
        authenticationExecutions:
          - authenticator: conditional-user-configured
            authenticatorFlow: false
            requirement: REQUIRED
            priority: 10
            userSetupAllowed: false
          - authenticator: reset-otp
            authenticatorFlow: false
            requirement: REQUIRED
            priority: 20
            userSetupAllowed: false
      - alias: User creation or linking
        description: Flow for the existing/non-existing user alternatives
        providerId: basic-flow
        topLevel: false
        builtIn: true
        authenticationExecutions:
          - authenticatorConfig: create unique user config
            authenticator: idp-create-user-if-unique
            authenticatorFlow: false
            requirement: ALTERNATIVE
            priority: 10
            userSetupAllowed: false
          - authenticatorFlow: true
            requirement: ALTERNATIVE
            priority: 20
            flowAlias: Handle Existing Account
            userSetupAllowed: false
      - alias: Verify Existing Account by Re-authentication
        description: Reauthentication of existing account
        providerId: basic-flow
        topLevel: false
        builtIn: true
        authenticationExecutions:
          - authenticator: idp-username-password-form
            authenticatorFlow: false
            requirement: REQUIRED
            priority: 10
            userSetupAllowed: false
          - authenticatorFlow: true
            requirement: CONDITIONAL
            priority: 20
            flowAlias: First broker login - Conditional OTP
            userSetupAllowed: false
      - alias: browser
        description: browser based authentication
        providerId: basic-flow
        topLevel: true
        builtIn: true
        authenticationExecutions:
          - authenticator: auth-cookie
            authenticatorFlow: false
            requirement: ALTERNATIVE
            priority: 10
            userSetupAllowed: false
          - authenticator: auth-spnego
            authenticatorFlow: false
            requirement: DISABLED
            priority: 20
            userSetupAllowed: false
          - authenticator: identity-provider-redirector
            authenticatorFlow: false
            requirement: ALTERNATIVE
            priority: 25
            userSetupAllowed: false
          - authenticatorFlow: true
            requirement: ALTERNATIVE
            priority: 30
            flowAlias: forms
            userSetupAllowed: false
      - alias: clients
        description: Base authentication for clients
        providerId: client-flow
        topLevel: true
        builtIn: true
        authenticationExecutions:
          - authenticator: client-secret
            authenticatorFlow: false
            requirement: ALTERNATIVE
            priority: 10
            userSetupAllowed: false
          - authenticator: client-jwt
            authenticatorFlow: false
            requirement: ALTERNATIVE
            priority: 20
            userSetupAllowed: false
          - authenticator: client-secret-jwt
            authenticatorFlow: false
            requirement: ALTERNATIVE
            priority: 30
            userSetupAllowed: false
          - authenticator: client-x509
            authenticatorFlow: false
            requirement: ALTERNATIVE
            priority: 40
            userSetupAllowed: false
      - alias: direct grant
        description: OpenID Connect Resource Owner Grant
        providerId: basic-flow
        topLevel: true
        builtIn: true
        authenticationExecutions:
          - authenticator: direct-grant-validate-username
            authenticatorFlow: false
            requirement: REQUIRED
            priority: 10
            userSetupAllowed: false
          - authenticator: direct-grant-validate-password
            authenticatorFlow: false
            requirement: REQUIRED
            priority: 20
            userSetupAllowed: false
          - authenticatorFlow: true
            requirement: CONDITIONAL
            priority: 30
            flowAlias: Direct Grant - Conditional OTP
            userSetupAllowed: false
      - alias: docker auth
        description: Used by Docker clients to authenticate against the IDP
        providerId: basic-flow
        topLevel: true
        builtIn: true
        authenticationExecutions:
          - authenticator: docker-http-basic-authenticator
            authenticatorFlow: false
            requirement: REQUIRED
            priority: 10
            userSetupAllowed: false
      - alias: first broker login
        description: Actions taken after first broker login with identity provider account,
          which is not yet linked to any Keycloak account
        providerId: basic-flow
        topLevel: true
        builtIn: true
        authenticationExecutions:
          - authenticatorConfig: review profile config
            authenticator: idp-review-profile
            authenticatorFlow: false
            requirement: REQUIRED
            priority: 10
            userSetupAllowed: false
          - authenticatorFlow: true
            requirement: REQUIRED
            priority: 20
            flowAlias: User creation or linking
            userSetupAllowed: false
      - alias: forms
        description: Username, password, otp and other auth forms.
        providerId: basic-flow
        topLevel: false
        builtIn: true
        authenticationExecutions:
          - authenticator: auth-username-password-form
            authenticatorFlow: false
            requirement: REQUIRED
            priority: 10
            userSetupAllowed: false
          - authenticatorFlow: true
            requirement: CONDITIONAL
            priority: 20
            flowAlias: Browser - Conditional OTP
            userSetupAllowed: false
      - alias: http challenge
        description: An authentication flow based on challenge-response HTTP Authentication
          Schemes
        providerId: basic-flow
        topLevel: true
        builtIn: true
        authenticationExecutions:
          - authenticator: no-cookie-redirect
            authenticatorFlow: false
            requirement: REQUIRED
            priority: 10
            userSetupAllowed: false
          - authenticatorFlow: true
            requirement: REQUIRED
            priority: 20
            flowAlias: Authentication Options
            userSetupAllowed: false
      - alias: registration
        description: registration flow
        providerId: basic-flow
        topLevel: true
        builtIn: true
        authenticationExecutions:
          - authenticator: registration-page-form
            authenticatorFlow: true
            requirement: REQUIRED
            priority: 10
            flowAlias: registration form
            userSetupAllowed: false
      - alias: registration form
        description: registration form
        providerId: form-flow
        topLevel: false
        builtIn: true
        authenticationExecutions:
          - authenticator: registration-user-creation
            authenticatorFlow: false
            requirement: REQUIRED
            priority: 20
            userSetupAllowed: false
          - authenticator: registration-profile-action
            authenticatorFlow: false
            requirement: REQUIRED
            priority: 40
            userSetupAllowed: false
          - authenticator: registration-password-action
            authenticatorFlow: false
            requirement: REQUIRED
            priority: 50
            userSetupAllowed: false
          - authenticator: registration-recaptcha-action
            authenticatorFlow: false
            requirement: DISABLED
            priority: 60
            userSetupAllowed: false
      - alias: reset credentials
        description: Reset credentials for a user if they forgot their password or something
        providerId: basic-flow
        topLevel: true
        builtIn: true
        authenticationExecutions:
          - authenticator: reset-credentials-choose-user
            authenticatorFlow: false
            requirement: REQUIRED
            priority: 10
            userSetupAllowed: false
          - authenticator: reset-credential-email
            authenticatorFlow: false
            requirement: REQUIRED
            priority: 20
            userSetupAllowed: false
          - authenticator: reset-password
            authenticatorFlow: false
            requirement: REQUIRED
            priority: 30
            userSetupAllowed: false
          - authenticatorFlow: true
            requirement: CONDITIONAL
            priority: 40
            flowAlias: Reset - Conditional OTP
            userSetupAllowed: false
      - alias: saml ecp
        description: SAML ECP Profile Authentication Flow
        providerId: basic-flow
        topLevel: true
        builtIn: true
        authenticationExecutions:
          - authenticator: http-basic-authenticator
            authenticatorFlow: false
            requirement: REQUIRED
            priority: 10
            userSetupAllowed: false
      - alias: x509 direct grant
        id: 96f2c609-7966-4887-a51a-e647e14a3605
        description: X509 Direct Grant
        providerId: basic-flow
        topLevel: true
        builtIn: false
        authenticationExecutions:
          - authenticator: direct-grant-auth-x509-username
            authenticatorConfig: x509 config
            authenticatorFlow: false
            requirement: REQUIRED
            userSetupAllowed: false
    authenticatorConfig:
      - alias: create unique user config
        config:
          require.password.update.after.registration: 'false'
      - alias: review profile config
        config:
          update.profile.on.first.login: missing
      - alias: x509 config
        config:
          x509-cert-auth.canonical-dn-enabled: "false"
          x509-cert-auth.crldp-checking-enabled: "false"
          x509-cert-auth.mapper-selection: "Username or Email"
          x509-cert-auth.mapping-source-selection: "Subject's Common Name"
          x509-cert-auth.regular-expression: "(.*?)(?:$)"
          x509-cert-auth.serialnumber-hex-enabled: "false"
          x509-cert-auth.timestamp-validation-enabled: "false"
  instanceSelector:
    matchLabels:
      app: keycloak

Anything else?

No response

@andreaTP
Copy link
Contributor

Hi @Robbilie ,
there is no "special treatment" of the id field from the the operator and it's directly translated to a REST API call to Keycloak, can you please verify the raw functionality using the Admin REST API of Keycloak?

@andreaTP andreaTP self-assigned this Jan 13, 2022
@Robbilie
Copy link
Contributor Author

Robbilie commented Jan 13, 2022

yeah sorry forgot to mention that, already tested and it worked as expected, that confused me too…
i didnt see any special treatment either, i dont have a second instance of the operator running though to test if the issue is specific to that instance…

EDIT: POST /auth/admin/realms/testrealm/authentication/flows that api

@Robbilie
Copy link
Contributor Author

i just tried using the import realm method and it ignores the ids aswell, i guess thats a keycloak and not an operator issue then…?

@andreaTP
Copy link
Contributor

Hey @Robbilie , yes, this is an issue for Keycloak, please file it there:
https://github.com/keycloak/keycloak/issues

Thanks in advance!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

2 participants