When using the preview token-exchange feature with the `openshit-v3` identity provider, a NPE is triggered, because it tries to extract the `metadata` field twice from the user profile:
```
13:17:13,667 ERROR [org.keycloak.services.error.KeycloakErrorHandler] (default task-7) Uncaught server error: java.lang.NullPointerException
at org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider.getJsonProperty(AbstractOAuth2IdentityProvider.java:357)
at org.keycloak.social.openshift.OpenshiftV3IdentityProvider.extractUserContext(OpenshiftV3IdentityProvider.java:61)
at org.keycloak.social.openshift.OpenshiftV3IdentityProvider.extractIdentityFromProfile(OpenshiftV3IdentityProvider.java:87)
at org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider.validateExternalTokenThroughUserInfo(AbstractOAuth2IdentityProvider.java:489)
at org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider.exchangeExternalUserInfoValidationOnly(AbstractOAuth2IdentityProvider.java:548)
at org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider.exchangeExternalImpl(AbstractOAuth2IdentityProvider.java:528)
at org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider.exchangeExternal(AbstractOAuth2IdentityProvider.java:519)
at org.keycloak.protocol.oidc.endpoints.TokenEndpoint.exchangeExternalToken(TokenEndpoint.java:917)
at org.keycloak.protocol.oidc.endpoints.TokenEndpoint.tokenExchange(TokenEndpoint.java:696)
at org.keycloak.protocol.oidc.endpoints.TokenEndpoint.processGrantRequest(TokenEndpoint.java:194)
.....
13:17:28,916 ERROR [org.keycloak.services.error.KeycloakErrorHandler] (default task-7) Uncaught server error: java.lang.NullPointerException
at org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider.getJsonProperty(AbstractOAuth2IdentityProvider.java:357)
at org.keycloak.social.openshift.OpenshiftV3IdentityProvider.extractUserContext(OpenshiftV3IdentityProvider.java:61)
at org.keycloak.social.openshift.OpenshiftV3IdentityProvider.extractIdentityFromProfile(OpenshiftV3IdentityProvider.java:87)
at org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider.validateExternalTokenThroughUserInfo(AbstractOAuth2IdentityProvider.java:489)
at org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider.exchangeExternalUserInfoValidationOnly(AbstractOAuth2IdentityProvider.java:548)
at org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider.exchangeExternalImpl(AbstractOAuth2IdentityProvider.java:528)
at org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider.exchangeExternal(AbstractOAuth2IdentityProvider.java:519)
at org.keycloak.protocol.oidc.endpoints.TokenEndpoint.exchangeExternalToken(TokenEndpoint.java:917)
at org.keycloak.protocol.oidc.endpoints.TokenEndpoint.tokenExchange(TokenEndpoint.java:696)
at org.keycloak.protocol.oidc.endpoints.TokenEndpoint.processGrantRequest(TokenEndpoint.java:194)
......
13:17:53,492 ERROR [org.keycloak.services.error.KeycloakErrorHandler] (default task-7) Uncaught server error: java.lang.NullPointerException
at org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider.getJsonProperty(AbstractOAuth2IdentityProvider.java:357)
at org.keycloak.social.openshift.OpenshiftV3IdentityProvider.extractUserContext(OpenshiftV3IdentityProvider.java:61)
at org.keycloak.social.openshift.OpenshiftV3IdentityProvider.extractIdentityFromProfile(OpenshiftV3IdentityProvider.java:87)
at org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider.validateExternalTokenThroughUserInfo(AbstractOAuth2IdentityProvider.java:489)
at org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider.exchangeExternalUserInfoValidationOnly(AbstractOAuth2IdentityProvider.java:548)
at org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider.exchangeExternalImpl(AbstractOAuth2IdentityProvider.java:528)
at org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider.exchangeExternal(AbstractOAuth2IdentityProvider.java:519)
at org.keycloak.protocol.oidc.endpoints.TokenEndpoint.exchangeExternalToken(TokenEndpoint.java:917)
at org.keycloak.protocol.oidc.endpoints.TokenEndpoint.tokenExchange(TokenEndpoint.java:696)
at org.keycloak.protocol.oidc.endpoints.TokenEndpoint.processGrantRequest(TokenEndpoint.java:194)
```
* [KEYCLOAK-8575] Allow to choose between basic auth and form auth for oidc idp
* uncomment ui and add tests
* move basic auth to abstract identity provider (except for getting refresh tokens)
* removed duplications
- automatically parses ${vault.<KEY>} expressions to obtain the key that contains the secret in the vault.
- enchances the capabilities of the VaultProvider by offering methods to convert the raw secrets into other types.
Update user identity sources and the way how X.509 certificates are mapped to the user to:
1. Include "Serial number + Issuer DN" as described in RFC 5280
2. Include "Certificate's SHA256-Thumbprint"
3. Exclude "Issuer DN"
4. Exclude "Issuer Email"
Add an option to represent serial number in hexadecimal format.
Documentation PR created: https://github.com/keycloak/keycloak-documentation/pull/714
KEYCLOAK-10785 - Documentation for new user identity source mappers