keycloak-scim/securing_apps/topics/oidc/java/client-authentication.adoc

65 lines
4.2 KiB
Text

[[_client_authentication_adapter]]
==== Client Authentication
When a confidential OIDC client needs to send a backchannel request (for example, to exchange code for the token, or to refresh the token) it needs to authenticate against the {{book.project.name}} server. By default, there are two ways to authenticate the client: client ID and client secret, or client authentication with signed JWT.
===== Client ID and Client Secret
This is the traditional method described in the OAuth2 specification. The client has a secret, which needs to be known to both the adapter (application) and the {{book.project.name}} server.
You can generate the secret for a particular client in the {{book.project.name}} administration console, and then paste this secret into the `keycloak.json` file on the application side:
[source]
----
"credentials": {
"secret": "19666a4f-32dd-4049-b082-684c74115f28"
}
----
===== Client Authentication with Signed JWT
This is based on the https://tools.ietf.org/html/rfc7523[RFC7523] specification. It works this way:
* The client must have the private key and certificate. For {{book.project.name}} this is available through the traditional `keystore` file, which is either available on the client application's classpath or somewhere on the file system.
* Once the client application is started, it allows to download it's public key in https://self-issued.info/docs/draft-ietf-jose-json-web-key.html[JWKS] format using a URL such as \http://myhost.com/myapp/k_jwks, assuming that \http://myhost.com/myapp is the base URL of your client application. This URL can be used by {{book.project.name}} (see below).
* During authentication, the client generates a JWT token and signs it with its private key and sends it to {{book.project.name}} in
the particular backchannel request (for example, code-to-token request) in the `client_assertion` parameter.
* {{book.project.name}} must have the public key or certificate of the client so that it can verify the signature on JWT. In {{book.project.name}} you need to configure client credentials for your client. First you need to choose `Signed JWT` as the method of authenticating your client in the tab `Credentials` in administration console.
Then you can choose to either:
** Configure the JWKS URL where {{book.project.name}} can download the client's public keys. This can be a URL such as \http://myhost.com/myapp/k_jwks (see details above). This option is the most flexible, since the client can rotate its keys anytime and {{book.project.name}} then always downloads new keys when needed without needing to change the configuration. More accurately, {{book.project.name}} downloads new keys when it sees the token signed by an unknown `kid` (Key ID).
** Upload the client's public key or certificate, either in PEM format, in JWK format, or from the keystore. With this option, the public key is hardcoded and must be changed when the client generates a new key pair.
You can even generate your own keystore from the {{book.project.name}} admininstration console if you don't have your own available.
For more details on how to set up the {{book.project.name}} administration console see {{book.adminguide.link}}[{{book.adminguide.name}}].
For set up on the adapter side you need to have something like this in your `keycloak.json` file:
[source]
----
"credentials": {
"jwt": {
"client-keystore-file": "classpath:keystore-client.jks",
"client-keystore-type": "JKS",
"client-keystore-password": "storepass",
"client-key-password": "keypass",
"client-key-alias": "clientkey",
"token-expiration": 10
}
}
----
With this configuration, the keystore file `keystore-client.jks` must be available on classpath in your WAR. If you do not use the prefix `classpath:`
you can point to any file on the file system where the client application is running.
{% if book.community %}
For inspiration, you can take a look at the examples distribution into the main demo example into the `product-portal` application.
===== Add Your Own Client Authentication Method
You can add your own client authentication method as well. You will need to implement both client-side and server-side providers. For more details see the `Authentication SPI` section in link:{{book.developerguide.link}}[{{book.developerguide.name}}].
{% endif %}