'Using custom credential provider in Keycloak

I have created a custom credential provider PinCredentialProvider with a corresponding PinCredentialProviderFactory for Keycloak.

class PinCredentialProviderFactory: CredentialProviderFactory<PinCredentialProvider> {

  companion object {
    final val PROVIDER_ID = "pin"
  }

  override fun create(session: KeycloakSession): CredentialProvider<*> = PinCredentialProvider(session)

  override fun getId(): String = PROVIDER_ID


}
class PinCredentialProvider(
  private val session: KeycloakSession
): CredentialProvider<PinCredentialModel>, CredentialInputValidator {

  override fun getType(): String = PinCredentialModel.TYPE

  override fun createCredential(realm: RealmModel, user: UserModel, credentialModel: PinCredentialModel): CredentialModel {
    if(credentialModel.createdDate !is Long) {
      credentialModel.createdDate = Time.currentTimeMillis()
    }
    return getCredentialStore().createCredential(realm, user, credentialModel)
  }

  override fun deleteCredential(realm: RealmModel, user: UserModel, credentialId: String): Boolean =
    getCredentialStore().removeStoredCredential(realm, user, credentialId)

  override fun getCredentialFromModel(credentialModel: CredentialModel): PinCredentialModel =
    PinCredentialModel.createFromCredentialModel(credentialModel)

  override fun getCredentialTypeMetadata(context: CredentialTypeMetadataContext): CredentialTypeMetadata =
    CredentialTypeMetadata.builder()
      .type(type)
      .category(CredentialTypeMetadata.Category.BASIC_AUTHENTICATION) // TODO is this correct?
      .displayName(PinCredentialProviderFactory.PROVIDER_ID)
      .helpText("pin credential provider")
      //.createAction()
      //.removable(false)
      .build(session)

  override fun supportsCredentialType(credentialType: String): Boolean = type == credentialType

  override fun isConfiguredFor(realm: RealmModel, user: UserModel, credentialType: String): Boolean {
    if(supportsCredentialType(credentialType).not()) return false
    return getCredentialStore().getStoredCredentialsByTypeStream(realm, user, credentialType).count() > 0
  }

  override fun isValid(realm: RealmModel, user: UserModel, input: CredentialInput?): Boolean {
    return true
  }

  private fun getCredentialStore(): UserCredentialManager = session.userCredentialManager()

}

It works fine and the custom provider is displayed on the server info -> providers page of Keycloak. The question is now, how can I use the credential type for users: Keycloak user management console



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source