Update documentation for Quarkus distribution (#1385)

This commit is contained in:
Stian Thorgersen 2022-02-08 14:07:16 +01:00 committed by GitHub
parent 6809b3ea59
commit 65287b7aef
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
95 changed files with 750 additions and 364 deletions

View file

@ -6,9 +6,10 @@ This library is based on the {project_name} JavaScript adapter, which can be int
You can obtain this library from a running a {project_name} Server instance by including the following `script` tag in your web page: You can obtain this library from a running a {project_name} Server instance by including the following `script` tag in your web page:
```html [source,html,subs="attributes+"]
<script src="http://.../auth/js/keycloak-authz.js"></script> ----
``` <script src="http://...{kc_js_path}/keycloak-authz.js"></script>
----
Once you do that, you can create a `KeycloakAuthorization` instance as follows: Once you do that, you can create a `KeycloakAuthorization` instance as follows:
```javascript ```javascript
@ -30,12 +31,13 @@ If a resource server is protected by a policy enforcer, it responds to client re
Typically, when you try to access a resource server with a bearer token that is lacking permissions to access a protected resource, the resource server Typically, when you try to access a resource server with a bearer token that is lacking permissions to access a protected resource, the resource server
responds with a *401* status code and a `WWW-Authenticate` header. responds with a *401* status code and a `WWW-Authenticate` header.
```bash [source,bash,subs="attributes+"]
----
HTTP/1.1 401 Unauthorized HTTP/1.1 401 Unauthorized
WWW-Authenticate: UMA realm="${realm}", WWW-Authenticate: UMA realm="${realm}",
as_uri="https://${host}:${port}/auth/realms/${realm}", as_uri="https://${host}:${port}{kc_realms_path}/${realm}",
ticket="016f84e8-f9b9-11e0-bd6f-0021cc6004de" ticket="016f84e8-f9b9-11e0-bd6f-0021cc6004de"
``` ----
See <<_service_uma_authorization_process, UMA Authorization Process>> for more information. See <<_service_uma_authorization_process, UMA Authorization Process>> for more information.

View file

@ -6,6 +6,21 @@ There is one caveat to this. You have to run a separate {appserver_name} instanc
To boot {project_name} Server: To boot {project_name} Server:
ifeval::["{kc_dist}" == "quarkus"]
.Linux/Unix
[source]
----
$ .../bin/kc.sh start-dev --http-port 8180
----
.Windows
[source]
----
> ...\bin\kc.bat start-dev --http-port 8180
----
endif::[]
ifeval::["{kc_dist}" == "wildfly"]
.Linux/Unix .Linux/Unix
[source] [source]
---- ----
@ -17,8 +32,9 @@ $ .../bin/standalone.sh -Djboss.socket.binding.port-offset=100
---- ----
> ...\bin\standalone.bat -Djboss.socket.binding.port-offset=100 > ...\bin\standalone.bat -Djboss.socket.binding.port-offset=100
---- ----
endif::[]
For more details about how to install and configure a {appserver_name}, please follow the steps on the link:{adapterguide_link}[{adapterguide_name}] tutorial. For more details about how to install and configure a {appserver_name}, please follow the steps on the link:{adapterguide_link}[{adapterguide_name}] tutorial.
After installing and booting both servers you should be able to access {project_name} Admin Console at http://localhost:8180/auth/admin/ and also the {appserver_name} instance at After installing and booting both servers you should be able to access {project_name} Admin Console at http://localhost:8180{kc_admins_path}/ and also the {appserver_name} instance at
http://localhost:8080. http://localhost:8080.

View file

@ -6,29 +6,31 @@
The discovery document can be obtained from: The discovery document can be obtained from:
```bash [source,bash,subs="attributes+"]
----
curl -X GET \ curl -X GET \
http://${host}:${port}/auth/realms/${realm}/.well-known/uma2-configuration http://${host}:${port}{kc_realms_path}/${realm}/.well-known/uma2-configuration
``` ----
Where `${host}:${port}` is the hostname (or IP address) and port where {project_name} is running and `${realm}` is the name of Where `${host}:${port}` is the hostname (or IP address) and port where {project_name} is running and `${realm}` is the name of
a realm in {project_name}. a realm in {project_name}.
As a result, you should get a response as follows: As a result, you should get a response as follows:
```bash [source,json,subs="attributes+"]
----
{ {
// some claims are expected here // some claims are expected here
// these are the main claims in the discovery document about Authorization Services endpoints location // these are the main claims in the discovery document about Authorization Services endpoints location
"token_endpoint": "http://${host}:${port}/auth/realms/${realm}/protocol/openid-connect/token", "token_endpoint": "http://${host}:${port}{kc_realms_path}/${realm}/protocol/openid-connect/token",
"token_introspection_endpoint": "http://${host}:${port}/auth/realms/${realm}/protocol/openid-connect/token/introspect", "token_introspection_endpoint": "http://${host}:${port}{kc_realms_path}/${realm}/protocol/openid-connect/token/introspect",
"resource_registration_endpoint": "http://${host}:${port}/auth/realms/${realm}/authz/protection/resource_set", "resource_registration_endpoint": "http://${host}:${port}{kc_realms_path}/${realm}/authz/protection/resource_set",
"permission_endpoint": "http://${host}:${port}/auth/realms/${realm}/authz/protection/permission", "permission_endpoint": "http://${host}:${port}{kc_realms_path}/${realm}/authz/protection/permission",
"policy_endpoint": "http://${host}:${port}/auth/realms/${realm}/authz/protection/uma-policy" "policy_endpoint": "http://${host}:${port}{kc_realms_path}/${realm}/authz/protection/uma-policy"
} }
``` ----
Each of these endpoints expose a specific set of capabilities: Each of these endpoints expose a specific set of capabilities:

View file

@ -9,12 +9,13 @@ grant type, clients can use any of these authentication methods:
Clients should send an access token as a Bearer credential in an HTTP Authorization header to the token endpoint. Clients should send an access token as a Bearer credential in an HTTP Authorization header to the token endpoint.
+ +
.Example: an authorization request using an access token to authenticate to the token endpoint .Example: an authorization request using an access token to authenticate to the token endpoint
```bash [source,bash,subs="attributes+"]
----
curl -X POST \ curl -X POST \
http://${host}:${port}/auth/realms/${realm}/protocol/openid-connect/token \ http://${host}:${port}{kc_realms_path}/${realm}/protocol/openid-connect/token \
-H "Authorization: Bearer ${access_token}" \ -H "Authorization: Bearer ${access_token}" \
--data "grant_type=urn:ietf:params:oauth:grant-type:uma-ticket" --data "grant_type=urn:ietf:params:oauth:grant-type:uma-ticket"
``` ----
+ +
This method is especially useful when the client is acting on behalf of a user. This method is especially useful when the client is acting on behalf of a user.
In this case, the bearer token is an access token previously issued by {project_name} to some client acting on behalf In this case, the bearer token is an access token previously issued by {project_name} to some client acting on behalf
@ -27,9 +28,10 @@ the resources and scopes to which User A has access.
Clients can use any of the client authentication methods supported by {project_name}. For instance, client_id/client_secret or JWT. Clients can use any of the client authentication methods supported by {project_name}. For instance, client_id/client_secret or JWT.
+ +
.Example: an authorization request using client id and client secret to authenticate to the token endpoint .Example: an authorization request using client id and client secret to authenticate to the token endpoint
```bash [source,bash,subs="attributes+"]
----
curl -X POST \ curl -X POST \
http://${host}:${port}/auth/realms/${realm}/protocol/openid-connect/token \ http://${host}:${port}{kc_realms_path}/${realm}/protocol/openid-connect/token \
-H "Authorization: Basic cGhvdGg6L7Jl13RmfWgtkk==pOnNlY3JldA==" \ -H "Authorization: Basic cGhvdGg6L7Jl13RmfWgtkk==pOnNlY3JldA==" \
--data "grant_type=urn:ietf:params:oauth:grant-type:uma-ticket" --data "grant_type=urn:ietf:params:oauth:grant-type:uma-ticket"
``` ----

View file

@ -94,36 +94,39 @@ If the authorization request does not map to any permission, a `403` HTTP status
Example of a authorization request when a client is seeking access to two resources protected by a resource server. Example of a authorization request when a client is seeking access to two resources protected by a resource server.
```bash [source,bash,subs="attributes+"]
----
curl -X POST \ curl -X POST \
http://${host}:${port}/auth/realms/${realm}/protocol/openid-connect/token \ http://${host}:${port}{kc_realms_path}/${realm}/protocol/openid-connect/token \
-H "Authorization: Bearer ${access_token}" \ -H "Authorization: Bearer ${access_token}" \
--data "grant_type=urn:ietf:params:oauth:grant-type:uma-ticket" \ --data "grant_type=urn:ietf:params:oauth:grant-type:uma-ticket" \
--data "audience={resource_server_client_id}" \ --data "audience={resource_server_client_id}" \
--data "permission=Resource A#Scope A" \ --data "permission=Resource A#Scope A" \
--data "permission=Resource B#Scope B" --data "permission=Resource B#Scope B"
``` ----
Example of a authorization request when a client is seeking access to any resource and scope protected by a resource server. Example of a authorization request when a client is seeking access to any resource and scope protected by a resource server.
```bash [source,bash,subs="attributes+"]
----
curl -X POST \ curl -X POST \
http://${host}:${port}/auth/realms/${realm}/protocol/openid-connect/token \ http://${host}:${port}{kc_realms_path}/${realm}/protocol/openid-connect/token \
-H "Authorization: Bearer ${access_token}" \ -H "Authorization: Bearer ${access_token}" \
--data "grant_type=urn:ietf:params:oauth:grant-type:uma-ticket" \ --data "grant_type=urn:ietf:params:oauth:grant-type:uma-ticket" \
--data "audience={resource_server_client_id}" --data "audience={resource_server_client_id}"
``` ----
Example of an authorization request when a client is seeking access to a UMA protected resource after receiving a permission ticket from Example of an authorization request when a client is seeking access to a UMA protected resource after receiving a permission ticket from
the resource server as part of the authorization process: the resource server as part of the authorization process:
```bash [source,bash,subs="attributes+"]
----
curl -X POST \ curl -X POST \
http://${host}:${port}/auth/realms/${realm}/protocol/openid-connect/token \ http://${host}:${port}{kc_realms_path}/${realm}/protocol/openid-connect/token \
-H "Authorization: Bearer ${access_token}" \ -H "Authorization: Bearer ${access_token}" \
--data "grant_type=urn:ietf:params:oauth:grant-type:uma-ticket" \ --data "grant_type=urn:ietf:params:oauth:grant-type:uma-ticket" \
--data "ticket=${permission_ticket} --data "ticket=${permission_ticket}
``` ----
If {project_name} assessment process results in issuance of permissions, it issues the RPT with which it has associated If {project_name} assessment process results in issuance of permissions, it issues the RPT with which it has associated
the permissions: the permissions:

View file

@ -7,16 +7,17 @@ claims available to your policies when evaluating permissions.
If you are obtaining permissions from the server *without* using a permission ticket (UMA flow), you can send If you are obtaining permissions from the server *without* using a permission ticket (UMA flow), you can send
an authorization request to the token endpoint as follows: an authorization request to the token endpoint as follows:
```bash [source,bash,subs="attributes+"]
----
curl -X POST \ curl -X POST \
http://${host}:${port}/auth/realms/${realm}/protocol/openid-connect/token \ http://${host}:${port}{kc_realms_path}/${realm}/protocol/openid-connect/token \
--data "grant_type=urn:ietf:params:oauth:grant-type:uma-ticket" \ --data "grant_type=urn:ietf:params:oauth:grant-type:uma-ticket" \
--data "claim_token=ewogICAib3JnYW5pemF0aW9uIjogWyJhY21lIl0KfQ==" \ --data "claim_token=ewogICAib3JnYW5pemF0aW9uIjogWyJhY21lIl0KfQ==" \
--data "claim_token_format=urn:ietf:params:oauth:token-type:jwt" \ --data "claim_token_format=urn:ietf:params:oauth:token-type:jwt" \
--data "client_id={resource_server_client_id}" \ --data "client_id={resource_server_client_id}" \
--data "client_secret={resource_server_client_secret}" \ --data "client_secret={resource_server_client_secret}" \
--data "audience={resource_server_client_id}" --data "audience={resource_server_client_id}"
``` ----
The `claim_token` parameter expects a BASE64 encoded JSON with a format similar to the example below: The `claim_token` parameter expects a BASE64 encoded JSON with a format similar to the example below:

View file

@ -16,12 +16,13 @@ The resource server sends a response back to the client with a permission `ticke
of a {project_name} server to where the ticket should be sent in order to obtain an RPT. of a {project_name} server to where the ticket should be sent in order to obtain an RPT.
.Resource server responds with a permission ticket .Resource server responds with a permission ticket
```bash [source,bash,subs="attributes+"]
----
HTTP/1.1 401 Unauthorized HTTP/1.1 401 Unauthorized
WWW-Authenticate: UMA realm="${realm}", WWW-Authenticate: UMA realm="${realm}",
as_uri="https://${host}:${port}/auth/realms/${realm}", as_uri="https://${host}:${port}{kc_realms_path}/${realm}",
ticket="016f84e8-f9b9-11e0-bd6f-0021cc6004de" ticket="016f84e8-f9b9-11e0-bd6f-0021cc6004de"
``` ----
The permission ticket is a special type of token issued by {project_name} Permission API. They represent the permissions being requested (e.g.: resources and scopes) The permission ticket is a special type of token issued by {project_name} Permission API. They represent the permissions being requested (e.g.: resources and scopes)
as well any other information associated with the request. Only resource servers are allowed to create those tokens. as well any other information associated with the request. Only resource servers are allowed to create those tokens.
@ -30,13 +31,14 @@ Now that the client has a permission ticket and also the location of a {project_
to obtain the location of the token endpoint and send an authorization request. to obtain the location of the token endpoint and send an authorization request.
.Client sends an authorization request to the token endpoint to obtain an RPT .Client sends an authorization request to the token endpoint to obtain an RPT
```bash [source,bash,subs="attributes+"]
----
curl -X POST \ curl -X POST \
http://${host}:${port}/auth/realms/${realm}/protocol/openid-connect/token \ http://${host}:${port}{kc_realms_path}/${realm}/protocol/openid-connect/token \
-H "Authorization: Bearer ${access_token}" \ -H "Authorization: Bearer ${access_token}" \
--data "grant_type=urn:ietf:params:oauth:grant-type:uma-ticket" \ --data "grant_type=urn:ietf:params:oauth:grant-type:uma-ticket" \
--data "ticket=${permission_ticket} --data "ticket=${permission_ticket}
``` ----
If {project_name} assessment process results in issuance of permissions, it issues the RPT with which it has associated If {project_name} assessment process results in issuance of permissions, it issues the RPT with which it has associated
the permissions: the permissions:

View file

@ -23,14 +23,15 @@ In some situations, client applications may want to start an asynchronous author
being requested decide whether or not access should be granted. For that, clients can use the `submit_request` request parameter along being requested decide whether or not access should be granted. For that, clients can use the `submit_request` request parameter along
with an authorization request to the token endpoint: with an authorization request to the token endpoint:
```bash [source,bash,subs="attributes+"]
----
curl -X POST \ curl -X POST \
http://${host}:${port}/auth/realms/${realm}/protocol/openid-connect/token \ http://${host}:${port}{kc_realms_path}/${realm}/protocol/openid-connect/token \
-H "Authorization: Bearer ${access_token}" \ -H "Authorization: Bearer ${access_token}" \
--data "grant_type=urn:ietf:params:oauth:grant-type:uma-ticket" \ --data "grant_type=urn:ietf:params:oauth:grant-type:uma-ticket" \
--data "ticket=${permission_ticket} \ --data "ticket=${permission_ticket} \
--data "submit_request=true" --data "submit_request=true"
``` ----
When using the `submit_request` parameter, {project_name} will persist a permission request for each resource to which access was denied. When using the `submit_request` parameter, {project_name} will persist a permission request for each resource to which access was denied.
Once created, resource owners can check their account and manage their permissions requests. Once created, resource owners can check their account and manage their permissions requests.

View file

@ -22,16 +22,17 @@ It is targeted for resource servers that want to access the different endpoints
The client configuration is defined in a ``keycloak.json`` file as follows: The client configuration is defined in a ``keycloak.json`` file as follows:
```json [source,json,subs="attributes+"]
----
{ {
"realm": "hello-world-authz", "realm": "hello-world-authz",
"auth-server-url" : "http://localhost:8080/auth", "auth-server-url" : "http://localhost:8080{kc_base_path}",
"resource" : "hello-world-authz-service", "resource" : "hello-world-authz-service",
"credentials": { "credentials": {
"secret": "secret" "secret": "secret"
} }
} }
``` ----
* *realm* (required) * *realm* (required)
+ +
@ -39,7 +40,7 @@ The name of the realm.
* *auth-server-url* (required) * *auth-server-url* (required)
+ +
The base URL of the {project_name} server. All other {project_name} pages and REST service endpoints are derived from this. It is usually in the form https://host:port/auth. The base URL of the {project_name} server. All other {project_name} pages and REST service endpoints are derived from this. It is usually in the form https://host:port{kc_base_path}.
* *resource* (required) * *resource* (required)
+ +

View file

@ -3,9 +3,10 @@
Resource servers using the UMA protocol can use a specific endpoint to manage permission requests. This endpoint provides a UMA-compliant flow for registering permission requests and obtaining a permission ticket. Resource servers using the UMA protocol can use a specific endpoint to manage permission requests. This endpoint provides a UMA-compliant flow for registering permission requests and obtaining a permission ticket.
``` [source,subs="attributes+"]
http://${host}:${port}/auth/realms/${realm_name}/authz/protection/permission ----
``` http://${host}:${port}{kc_realms_path}/${realm_name}/authz/protection/permission
----
A <<_overview_terminology_permission_ticket, permission ticket>> is a special security token type representing a permission request. Per the UMA specification, a permission ticket is: A <<_overview_terminology_permission_ticket, permission ticket>> is a special security token type representing a permission request. Per the UMA specification, a permission ticket is:
@ -34,9 +35,10 @@ privacy and user controlled access to their resources.
To create a permission ticket, send an HTTP POST request as follows: To create a permission ticket, send an HTTP POST request as follows:
```bash [source,bash,subs="attributes+"]
----
curl -X POST \ curl -X POST \
http://${host}:${port}/auth/realms/${realm_name}/authz/protection/permission \ http://${host}:${port}{kc_realms_path}/${realm_name}/authz/protection/permission \
-H 'Authorization: Bearer '$pat \ -H 'Authorization: Bearer '$pat \
-H 'Content-Type: application/json' \ -H 'Content-Type: application/json' \
-d '[ -d '[
@ -47,13 +49,14 @@ curl -X POST \
] ]
} }
]' ]'
``` ----
When creating tickets you can also push arbitrary claims and associate these claims with the ticket: When creating tickets you can also push arbitrary claims and associate these claims with the ticket:
```bash [source,bash,subs="attributes+"]
----
curl -X POST \ curl -X POST \
http://${host}:${port}/auth/realms/${realm_name}/authz/protection/permission \ http://${host}:${port}{kc_realms_path}/${realm_name}/authz/protection/permission \
-H 'Authorization: Bearer '$pat \ -H 'Authorization: Bearer '$pat \
-H 'Content-Type: application/json' \ -H 'Content-Type: application/json' \
-d '[ -d '[
@ -67,7 +70,7 @@ curl -X POST \
} }
} }
]' ]'
``` ----
Where these claims will be available to your policies when evaluating permissions for the resource and scope(s) associated Where these claims will be available to your policies when evaluating permissions for the resource and scope(s) associated
with the permission ticket. with the permission ticket.
@ -78,9 +81,10 @@ with the permission ticket.
To grant permissions for a specific resource with id {resource_id} to a user with id {user_id}, as an owner of the resource send an HTTP POST request as follows: To grant permissions for a specific resource with id {resource_id} to a user with id {user_id}, as an owner of the resource send an HTTP POST request as follows:
```bash [source,bash,subs="attributes+"]
----
curl -X POST \ curl -X POST \
http://${host}:${port}/auth/realms/${realm_name}/authz/protection/permission/ticket \ http://${host}:${port}{kc_realms_path}/${realm_name}/authz/protection/permission/ticket \
-H 'Authorization: Bearer '$access_token \ -H 'Authorization: Bearer '$access_token \
-H 'Content-Type: application/json' \ -H 'Content-Type: application/json' \
-d '{ -d '{
@ -89,14 +93,15 @@ curl -X POST \
"granted": true, "granted": true,
"scopeName": "view" "scopeName": "view"
}' }'
``` ----
=== Getting permission tickets === Getting permission tickets
```bash [source,bash,subs="attributes+"]
curl http://${host}:${port}/auth/realms/${realm_name}/authz/protection/permission/ticket \ ----
curl http://${host}:${port}{kc_realms_path}/${realm_name}/authz/protection/permission/ticket \
-H 'Authorization: Bearer '$access_token -H 'Authorization: Bearer '$access_token
``` ----
You can use any of these query parameters: You can use any of these query parameters:
@ -111,9 +116,10 @@ You can use any of these query parameters:
=== Updating permission ticket === Updating permission ticket
```bash [source,bash,subs="attributes+"]
----
curl -X PUT \ curl -X PUT \
http://${host}:${port}/auth/realms/${realm_name}/authz/protection/permission/ticket \ http://${host}:${port}{kc_realms_path}/${realm_name}/authz/protection/permission/ticket \
-H 'Authorization: Bearer '$access_token \ -H 'Authorization: Bearer '$access_token \
-H 'Content-Type: application/json' \ -H 'Content-Type: application/json' \
-d '{ -d '{
@ -123,11 +129,12 @@ curl -X PUT \
"granted": false, "granted": false,
"scopeName": "view" "scopeName": "view"
}' }'
``` ----
=== Deleting permission ticket === Deleting permission ticket
```bash [source,bash,subs="attributes+"]
curl -X DELETE http://${host}:${port}/auth/realms/${realm_name}/authz/protection/permission/ticket/{ticket_id} \ ----
curl -X DELETE http://${host}:${port}{kc_realms_path}/${realm_name}/authz/protection/permission/ticket/{ticket_id} \
-H 'Authorization: Bearer '$access_token -H 'Authorization: Bearer '$access_token
``` ----

View file

@ -7,9 +7,10 @@ servers on behalf of their users.
The Policy API is available at: The Policy API is available at:
``` [source,subs="attributes+"]
http://${host}:${port}/auth/realms/${realm_name}/authz/protection/uma-policy/{resource_id} ----
``` http://${host}:${port}{kc_realms_path}/${realm_name}/authz/protection/uma-policy/{resource_id}
----
This API is protected by a bearer token that must represent a consent granted by the user to the resource server to manage permissions on his behalf. The bearer token can be a regular access token obtained from the This API is protected by a bearer token that must represent a consent granted by the user to the resource server to manage permissions on his behalf. The bearer token can be a regular access token obtained from the
token endpoint using: token endpoint using:
@ -22,9 +23,10 @@ where audience is the resource server
To associate a permission with a specific resource you must send a HTTP POST request as follows: To associate a permission with a specific resource you must send a HTTP POST request as follows:
```bash [source,bash,subs="attributes+"]
----
curl -X POST \ curl -X POST \
http://localhost:8180/auth/realms/photoz/authz/protection/uma-policy/{resource_id} \ http://localhost:8180{kc_realms_path}/photoz/authz/protection/uma-policy/{resource_id} \
-H 'Authorization: Bearer '$access_token \ -H 'Authorization: Bearer '$access_token \
-H 'Cache-Control: no-cache' \ -H 'Cache-Control: no-cache' \
-H 'Content-Type: application/json' \ -H 'Content-Type: application/json' \
@ -34,16 +36,17 @@ curl -X POST \
"scopes": ["read"], "scopes": ["read"],
"roles": ["people-manager"] "roles": ["people-manager"]
}' }'
``` ----
In the example above we are creating and associating a new permission to a resource represented by `resource_id` where In the example above we are creating and associating a new permission to a resource represented by `resource_id` where
any user with a role `people-manager` should be granted with the `read` scope. any user with a role `people-manager` should be granted with the `read` scope.
You can also create policies using other access control mechanisms, such as using groups: You can also create policies using other access control mechanisms, such as using groups:
```bash [source,bash,subs="attributes+"]
----
curl -X POST \ curl -X POST \
http://localhost:8180/auth/realms/photoz/authz/protection/uma-policy/{resource_id} \ http://localhost:8180{kc_realms_path}/photoz/authz/protection/uma-policy/{resource_id} \
-H 'Authorization: Bearer '$access_token \ -H 'Authorization: Bearer '$access_token \
-H 'Cache-Control: no-cache' \ -H 'Cache-Control: no-cache' \
-H 'Content-Type: application/json' \ -H 'Content-Type: application/json' \
@ -53,13 +56,14 @@ curl -X POST \
"scopes": ["read"], "scopes": ["read"],
"groups": ["/Managers/People Managers"] "groups": ["/Managers/People Managers"]
}' }'
``` ----
Or a specific client: Or a specific client:
```bash [source,bash,subs="attributes+"]
----
curl -X POST \ curl -X POST \
http://localhost:8180/auth/realms/photoz/authz/protection/uma-policy/{resource_id} \ http://localhost:8180{kc_realms_path}/photoz/authz/protection/uma-policy/{resource_id} \
-H 'Authorization: Bearer '$access_token \ -H 'Authorization: Bearer '$access_token \
-H 'Cache-Control: no-cache' \ -H 'Cache-Control: no-cache' \
-H 'Content-Type: application/json' \ -H 'Content-Type: application/json' \
@ -69,7 +73,7 @@ curl -X POST \
"scopes": ["read"], "scopes": ["read"],
"clients": ["my-client"] "clients": ["my-client"]
}' }'
``` ----
Or even using a custom policy using JavaScript: Or even using a custom policy using JavaScript:
@ -77,9 +81,10 @@ Or even using a custom policy using JavaScript:
:tech_feature_setting: -Dkeycloak.profile.feature.upload_scripts=enabled :tech_feature_setting: -Dkeycloak.profile.feature.upload_scripts=enabled
include::./templates/deprecated.adoc[] include::./templates/deprecated.adoc[]
```bash [source,bash,subs="attributes+"]
----
curl -X POST \ curl -X POST \
http://localhost:8180/auth/realms/photoz/authz/protection/uma-policy/{resource_id} \ http://localhost:8180{kc_realms_path}/photoz/authz/protection/uma-policy/{resource_id} \
-H 'Authorization: Bearer '$access_token \ -H 'Authorization: Bearer '$access_token \
-H 'Cache-Control: no-cache' \ -H 'Cache-Control: no-cache' \
-H 'Content-Type: application/json' \ -H 'Content-Type: application/json' \
@ -89,15 +94,16 @@ curl -X POST \
"scopes": ["read"], "scopes": ["read"],
"condition": "if (isPeopleManager()) {$evaluation.grant()}" "condition": "if (isPeopleManager()) {$evaluation.grant()}"
}' }'
``` ----
It is also possible to set any combination of these access control mechanisms. It is also possible to set any combination of these access control mechanisms.
To update an existing permission, send an HTTP PUT request as follows: To update an existing permission, send an HTTP PUT request as follows:
```bash [source,bash,subs="attributes+"]
----
curl -X PUT \ curl -X PUT \
http://localhost:8180/auth/realms/photoz/authz/protection/uma-policy/{permission_id} \ http://localhost:8180{kc_realms_path}/photoz/authz/protection/uma-policy/{permission_id} \
-H 'Authorization: Bearer '$access_token \ -H 'Authorization: Bearer '$access_token \
-H 'Content-Type: application/json' \ -H 'Content-Type: application/json' \
-d '{ -d '{
@ -115,41 +121,46 @@ curl -X PUT \
"user" "user"
] ]
}' }'
``` ----
== Removing a Permission == Removing a Permission
To remove a permission associated with a resource, send an HTTP DELETE request as follows: To remove a permission associated with a resource, send an HTTP DELETE request as follows:
```bash [source,bash,subs="attributes+"]
----
curl -X DELETE \ curl -X DELETE \
http://localhost:8180/auth/realms/photoz/authz/protection/uma-policy/{permission_id} \ http://localhost:8180{kc_realms_path}/photoz/authz/protection/uma-policy/{permission_id} \
-H 'Authorization: Bearer '$access_token -H 'Authorization: Bearer '$access_token
``` ----
== Querying Permission == Querying Permission
To query the permissions associated with a resource, send an HTTP GET request as follows: To query the permissions associated with a resource, send an HTTP GET request as follows:
```bash [source,subs="attributes+"]
http://${host}:${port}/auth/realms/${realm}/authz/protection/uma-policy?resource={resource_id} ----
``` http://${host}:${port}{kc_realms_path}/${realm}/authz/protection/uma-policy?resource={resource_id}
----
To query the permissions given its name, send an HTTP GET request as follows: To query the permissions given its name, send an HTTP GET request as follows:
```bash [source,bash,subs="attributes+"]
http://${host}:${port}/auth/realms/${realm}/authz/protection/uma-policy?name=Any people manager ----
``` http://${host}:${port}{kc_realms_path}/${realm}/authz/protection/uma-policy?name=Any people manager
----
To query the permissions associated with a specific scope, send an HTTP GET request as follows: To query the permissions associated with a specific scope, send an HTTP GET request as follows:
```bash [source,subs="attributes+"]
http://${host}:${port}/auth/realms/${realm}/authz/protection/uma-policy?scope=read ----
``` http://${host}:${port}{kc_realms_path}/${realm}/authz/protection/uma-policy?scope=read
----
To query all permissions, send an HTTP GET request as follows: To query all permissions, send an HTTP GET request as follows:
```bash [source,subs="attributes+"]
http://${host}:${port}/auth/realms/${realm}/authz/protection/uma-policy ----
``` http://${host}:${port}{kc_realms_path}/${realm}/authz/protection/uma-policy
----
When querying the server for permissions use parameters `first` and `max` results to limit the result. When querying the server for permissions use parameters `first` and `max` results to limit the result.

View file

@ -3,9 +3,10 @@
Resource servers can manage their resources remotely using a UMA-compliant endpoint. Resource servers can manage their resources remotely using a UMA-compliant endpoint.
``` [source,subs="attributes+"]
http://${host}:${port}/auth/realms/${realm_name}/authz/protection/resource_set ----
``` http://${host}:${port}{kc_realms_path}/${realm_name}/authz/protection/resource_set
----
This endpoint provides operations outlined as follows (entire path omitted for clarity): This endpoint provides operations outlined as follows (entire path omitted for clarity):
@ -21,9 +22,10 @@ For more information about the contract for each of these operations, see https:
To create a resource you must send an HTTP POST request as follows: To create a resource you must send an HTTP POST request as follows:
```bash [source,bash,subs="attributes+"]
----
curl -v -X POST \ curl -v -X POST \
http://${host}:${port}/auth/realms/${realm_name}/authz/protection/resource_set \ http://${host}:${port}{kc_realms_path}/${realm_name}/authz/protection/resource_set \
-H 'Authorization: Bearer '$pat \ -H 'Authorization: Bearer '$pat \
-H 'Content-Type: application/json' \ -H 'Content-Type: application/json' \
-d '{ -d '{
@ -37,21 +39,22 @@ curl -v -X POST \
"http://www.example.com/scopes/all" "http://www.example.com/scopes/all"
] ]
}' }'
``` ----
By default, the owner of a resource is the resource server. If you want to define a different owner, such as an By default, the owner of a resource is the resource server. If you want to define a different owner, such as an
specific user, you can send a request as follows: specific user, you can send a request as follows:
```bash [source,bash,subs="attributes+"]
----
curl -v -X POST \ curl -v -X POST \
http://${host}:${port}/auth/realms/${realm_name}/authz/protection/resource_set \ http://${host}:${port}{kc_realms_path}/${realm_name}/authz/protection/resource_set \
-H 'Authorization: Bearer '$pat \ -H 'Authorization: Bearer '$pat \
-H 'Content-Type: application/json' \ -H 'Content-Type: application/json' \
-d '{ -d '{
"name":"Alice Resource", "name":"Alice Resource",
"owner": "alice" "owner": "alice"
}' }'
``` ----
Where the property `owner` can be set with the username or the identifier of the user. Where the property `owner` can be set with the username or the identifier of the user.
@ -61,9 +64,10 @@ By default, resources created via Protection API can not be managed by resource
To create resources and allow resource owners to manage these resources, you must set `ownerManagedAccess` property as follows: To create resources and allow resource owners to manage these resources, you must set `ownerManagedAccess` property as follows:
```bash [source,bash,subs="attributes+"]
----
curl -v -X POST \ curl -v -X POST \
http://${host}:${port}/auth/realms/${realm_name}/authz/protection/resource_set \ http://${host}:${port}{kc_realms_path}/${realm_name}/authz/protection/resource_set \
-H 'Authorization: Bearer '$pat \ -H 'Authorization: Bearer '$pat \
-H 'Content-Type: application/json' \ -H 'Content-Type: application/json' \
-d '{ -d '{
@ -71,15 +75,16 @@ curl -v -X POST \
"owner": "alice", "owner": "alice",
"ownerManagedAccess": true "ownerManagedAccess": true
}' }'
``` ----
== Updating Resources == Updating Resources
To update an existing resource, send an HTTP PUT request as follows: To update an existing resource, send an HTTP PUT request as follows:
```bash [source,bash,subs="attributes+"]
----
curl -v -X PUT \ curl -v -X PUT \
http://${host}:${port}/auth/realms/${realm_name}/authz/protection/resource_set/{resource_id} \ http://${host}:${port}{kc_realms_path}/${realm_name}/authz/protection/resource_set/{resource_id} \
-H 'Authorization: Bearer '$pat \ -H 'Authorization: Bearer '$pat \
-H 'Content-Type: application/json' \ -H 'Content-Type: application/json' \
-d '{ -d '{
@ -89,60 +94,68 @@ curl -v -X PUT \
"read" "read"
] ]
}' }'
``` ----
== Deleting Resources == Deleting Resources
To delete an existing resource, send an HTTP DELETE request as follows: To delete an existing resource, send an HTTP DELETE request as follows:
```bash [source,bash,subs="attributes+"]
----
curl -v -X DELETE \ curl -v -X DELETE \
http://${host}:${port}/auth/realms/${realm_name}/authz/protection/resource_set/{resource_id} \ http://${host}:${port}{kc_realms_path}/${realm_name}/authz/protection/resource_set/{resource_id} \
-H 'Authorization: Bearer '$pat -H 'Authorization: Bearer '$pat
``` ----
== Querying Resources == Querying Resources
To query the resources by `id`, send an HTTP GET request as follows: To query the resources by `id`, send an HTTP GET request as follows:
```bash [source,bash,subs="attributes+"]
http://${host}:${port}/auth/realms/${realm_name}/authz/protection/resource_set/{resource_id} ----
``` http://${host}:${port}{kc_realms_path}/${realm_name}/authz/protection/resource_set/{resource_id}
----
To query resources given a `name`, send an HTTP GET request as follows: To query resources given a `name`, send an HTTP GET request as follows:
```bash [source,bash,subs="attributes+"]
http://${host}:${port}/auth/realms/${realm_name}/authz/protection/resource_set?name=Alice Resource ----
``` http://${host}:${port}{kc_realms_path}/${realm_name}/authz/protection/resource_set?name=Alice Resource
----
By default, the `name` filter will match any resource with the given pattern. To restrict the query to only return resources with an exact match, use: By default, the `name` filter will match any resource with the given pattern. To restrict the query to only return resources with an exact match, use:
```bash [source,bash,subs="attributes+"]
http://${host}:${port}/auth/realms/${realm_name}/authz/protection/resource_set?name=Alice Resource&exactName=true ----
``` http://${host}:${port}{kc_realms_path}/${realm_name}/authz/protection/resource_set?name=Alice Resource&exactName=true
----
To query resources given an `uri`, send an HTTP GET request as follows: To query resources given an `uri`, send an HTTP GET request as follows:
```bash [source,bash,subs="attributes+"]
http://${host}:${port}/auth/realms/${realm_name}/authz/protection/resource_set?uri=/api/alice ----
``` http://${host}:${port}{kc_realms_path}/${realm_name}/authz/protection/resource_set?uri=/api/alice
----
To query resources given an `owner`, send an HTTP GET request as follows: To query resources given an `owner`, send an HTTP GET request as follows:
```bash [source,bash,subs="attributes+"]
http://${host}:${port}/auth/realms/${realm_name}/authz/protection/resource_set?owner=alice ----
``` http://${host}:${port}{kc_realms_path}/${realm_name}/authz/protection/resource_set?owner=alice
----
To query resources given an `type`, send an HTTP GET request as follows: To query resources given an `type`, send an HTTP GET request as follows:
```bash [source,bash,subs="attributes+"]
http://${host}:${port}/auth/realms/${realm_name}/authz/protection/resource_set?type=albums ----
``` http://${host}:${port}{kc_realms_path}/${realm_name}/authz/protection/resource_set?type=albums
----
To query resources given an `scope`, send an HTTP GET request as follows: To query resources given an `scope`, send an HTTP GET request as follows:
```bash [source,bash,subs="attributes+"]
http://${host}:${port}/auth/realms/${realm_name}/authz/protection/resource_set?scope=read ----
``` http://${host}:${port}{kc_realms_path}/${realm_name}/authz/protection/resource_set?scope=read
----
When querying the server for permissions use parameters `first` and `max` results to limit the result. When querying the server for permissions use parameters `first` and `max` results to limit the result.

View file

@ -9,12 +9,13 @@ image:{project_images}/service/rs-uma-protection-role.png[alt="Service Account g
Resource servers can obtain a PAT from {project_name} like any other OAuth2 access token. For example, using curl: Resource servers can obtain a PAT from {project_name} like any other OAuth2 access token. For example, using curl:
```bash [source,bash,subs="attributes+"]
----
curl -X POST \ curl -X POST \
-H "Content-Type: application/x-www-form-urlencoded" \ -H "Content-Type: application/x-www-form-urlencoded" \
-d 'grant_type=client_credentials&client_id=${client_id}&client_secret=${client_secret}' \ -d 'grant_type=client_credentials&client_id=${client_id}&client_secret=${client_secret}' \
"http://localhost:8080/auth/realms/${realm_name}/protocol/openid-connect/token" "http://localhost:8080{kc_realms_path}/${realm_name}/protocol/openid-connect/token"
``` ----
The example above is using the *client_credentials* grant type to obtain a PAT from the server. As a result, the server returns a response similar to the following: The example above is using the *client_credentials* grant type to obtain a PAT from the server. As a result, the server returns a response similar to the following:

View file

@ -12,19 +12,21 @@ There are two main use cases where token introspection can help you:
The token introspection is essentially a https://datatracker.ietf.org/doc/html/rfc7662[OAuth2 token introspection]-compliant endpoint from which you can obtain information about an RPT. The token introspection is essentially a https://datatracker.ietf.org/doc/html/rfc7662[OAuth2 token introspection]-compliant endpoint from which you can obtain information about an RPT.
``` [source,subs="attributes+"]
http://${host}:${port}/auth/realms/${realm_name}/protocol/openid-connect/token/introspect ----
``` http://${host}:${port}{kc_realms_path}/${realm_name}/protocol/openid-connect/token/introspect
----
To introspect an RPT using this endpoint, you can send a request to the server as follows: To introspect an RPT using this endpoint, you can send a request to the server as follows:
```bash [source,bash,subs="attributes+"]
----
curl -X POST \ curl -X POST \
-H "Authorization: Basic aGVsbG8td29ybGQtYXV0aHotc2VydmljZTpzZWNyZXQ=" \ -H "Authorization: Basic aGVsbG8td29ybGQtYXV0aHotc2VydmljZTpzZWNyZXQ=" \
-H "Content-Type: application/x-www-form-urlencoded" \ -H "Content-Type: application/x-www-form-urlencoded" \
-d 'token_type_hint=requesting_party_token&token=${RPT}' \ -d 'token_type_hint=requesting_party_token&token=${RPT}' \
"http://localhost:8080/auth/realms/hello-world-authz/protocol/openid-connect/token/introspect" "http://localhost:8080{kc_realms_path}/hello-world-authz/protocol/openid-connect/token/introspect"
``` ----
[NOTE] [NOTE]
The request above is using HTTP BASIC and passing the client's credentials (client ID and secret) to authenticate the client attempting to introspect the token, but you can use any other client authentication method supported by {project_name}. The request above is using HTTP BASIC and passing the client's credentials (client ID and secret) to authenticate the client attempting to introspect the token, but you can use any other client authentication method supported by {project_name}.

View file

@ -6,7 +6,7 @@ An admin can do this through the admin console (or admin REST endpoints), but cl
registration service. registration service.
The Client Registration Service provides built-in support for {project_name} Client Representations, OpenID Connect Client Meta Data and SAML Entity Descriptors. The Client Registration Service provides built-in support for {project_name} Client Representations, OpenID Connect Client Meta Data and SAML Entity Descriptors.
The Client Registration Service endpoint is `/auth/realms/<realm>/clients-registrations/<provider>`. The Client Registration Service endpoint is `{kc_realms_path}/<realm>/clients-registrations/<provider>`.
The built-in supported `providers` are: The built-in supported `providers` are:
@ -73,22 +73,22 @@ The `default` client registration provider can be used to create, retrieve, upda
It uses {project_name} Client Representation format which provides support for configuring clients exactly as they can be configured through the admin It uses {project_name} Client Representation format which provides support for configuring clients exactly as they can be configured through the admin
console, including for example configuring protocol mappers. console, including for example configuring protocol mappers.
To create a client create a Client Representation (JSON) then perform an HTTP POST request to `/auth/realms/<realm>/clients-registrations/default`. To create a client create a Client Representation (JSON) then perform an HTTP POST request to `{kc_realms_path}/<realm>/clients-registrations/default`.
It will return a Client Representation that also includes the registration access token. It will return a Client Representation that also includes the registration access token.
You should save the registration access token somewhere if you want to retrieve the config, update or delete the client later. You should save the registration access token somewhere if you want to retrieve the config, update or delete the client later.
To retrieve the Client Representation perform an HTTP GET request to `/auth/realms/<realm>/clients-registrations/default/<client id>`. To retrieve the Client Representation perform an HTTP GET request to `{kc_realms_path}/<realm>/clients-registrations/default/<client id>`.
It will also return a new registration access token. It will also return a new registration access token.
To update the Client Representation perform an HTTP PUT request with the updated Client Representation to: To update the Client Representation perform an HTTP PUT request with the updated Client Representation to:
`/auth/realms/<realm>/clients-registrations/default/<client id>`. `{kc_realms_path}/<realm>/clients-registrations/default/<client id>`.
It will also return a new registration access token. It will also return a new registration access token.
To delete the Client Representation perform an HTTP DELETE request to: To delete the Client Representation perform an HTTP DELETE request to:
`/auth/realms/<realm>/clients-registrations/default/<client id>` `{kc_realms_path}/<realm>/clients-registrations/default/<client id>`
=== {project_name} adapter configuration === {project_name} adapter configuration
@ -101,7 +101,7 @@ To do this include the following header in the request:
Authorization: basic BASE64(client-id + ':' + client-secret) Authorization: basic BASE64(client-id + ':' + client-secret)
---- ----
To retrieve the Adapter Configuration then perform an HTTP GET request to `/auth/realms/<realm>/clients-registrations/install/<client id>`. To retrieve the Adapter Configuration then perform an HTTP GET request to `{kc_realms_path}/<realm>/clients-registrations/install/<client id>`.
No authentication is required for public clients. No authentication is required for public clients.
This means that for the JavaScript adapter you can load the client configuration directly from {project_name} using the above URL. This means that for the JavaScript adapter you can load the client configuration directly from {project_name} using the above URL.
@ -110,9 +110,9 @@ This means that for the JavaScript adapter you can load the client configuration
{project_name} implements https://openid.net/specs/openid-connect-registration-1_0.html[OpenID Connect Dynamic Client Registration], which extends https://datatracker.ietf.org/doc/html/rfc7591[OAuth 2.0 Dynamic Client Registration Protocol] and https://datatracker.ietf.org/doc/html/rfc7592[OAuth 2.0 Dynamic Client Registration Management Protocol]. {project_name} implements https://openid.net/specs/openid-connect-registration-1_0.html[OpenID Connect Dynamic Client Registration], which extends https://datatracker.ietf.org/doc/html/rfc7591[OAuth 2.0 Dynamic Client Registration Protocol] and https://datatracker.ietf.org/doc/html/rfc7592[OAuth 2.0 Dynamic Client Registration Management Protocol].
The endpoint to use these specifications to register clients in {project_name} is `/auth/realms/<realm>/clients-registrations/openid-connect[/<client id>]`. The endpoint to use these specifications to register clients in {project_name} is `{kc_realms_path}/<realm>/clients-registrations/openid-connect[/<client id>]`.
This endpoint can also be found in the OpenID Connect Discovery endpoint for the realm, `/auth/realms/<realm>/.well-known/openid-configuration`. This endpoint can also be found in the OpenID Connect Discovery endpoint for the realm, `{kc_realms_path}/<realm>/.well-known/openid-configuration`.
=== SAML Entity Descriptors === SAML Entity Descriptors
@ -121,20 +121,20 @@ It doesn't support retrieving, updating or deleting clients.
For those operations the {project_name} representation endpoints should be used. For those operations the {project_name} representation endpoints should be used.
When creating a client a {project_name} Client Representation is returned with details about the created client, including a registration access token. When creating a client a {project_name} Client Representation is returned with details about the created client, including a registration access token.
To create a client perform an HTTP POST request with the SAML Entity Descriptor to `/auth/realms/<realm>/clients-registrations/saml2-entity-descriptor`. To create a client perform an HTTP POST request with the SAML Entity Descriptor to `{kc_realms_path}/<realm>/clients-registrations/saml2-entity-descriptor`.
=== Example using CURL === Example using CURL
The following example creates a client with the clientId `myclient` using CURL. You need to replace `eyJhbGciOiJSUz...` with a proper initial access token or The following example creates a client with the clientId `myclient` using CURL. You need to replace `eyJhbGciOiJSUz...` with a proper initial access token or
bearer token. bearer token.
[source,bash] [source,bash,subs="attributes+"]
---- ----
curl -X POST \ curl -X POST \
-d '{ "clientId": "myclient" }' \ -d '{ "clientId": "myclient" }' \
-H "Content-Type:application/json" \ -H "Content-Type:application/json" \
-H "Authorization: bearer eyJhbGciOiJSUz..." \ -H "Authorization: bearer eyJhbGciOiJSUz..." \
http://localhost:8080/auth/realms/master/clients-registrations/default http://localhost:8080{kc_realms_path}/master/clients-registrations/default
---- ----
=== Example using Java Client Registration API === Example using Java Client Registration API
@ -145,7 +145,7 @@ To use include the dependency `org.keycloak:keycloak-client-registration-api:>VE
For full instructions on using the Client Registration refer to the JavaDocs. For full instructions on using the Client Registration refer to the JavaDocs.
Below is an example of creating a client. You need to replace `eyJhbGciOiJSUz...` with a proper initial access token or bearer token. Below is an example of creating a client. You need to replace `eyJhbGciOiJSUz...` with a proper initial access token or bearer token.
[source,java] [source,java,subs="attributes+"]
---- ----
String token = "eyJhbGciOiJSUz..."; String token = "eyJhbGciOiJSUz...";
@ -153,7 +153,7 @@ ClientRepresentation client = new ClientRepresentation();
client.setClientId(CLIENT_ID); client.setClientId(CLIENT_ID);
ClientRegistration reg = ClientRegistration.create() ClientRegistration reg = ClientRegistration.create()
.url("http://localhost:8080/auth", "myrealm") .url("http://localhost:8080{kc_base_path}", "myrealm")
.build(); .build();
reg.auth(Auth.token(token)); reg.auth(Auth.token(token));

View file

@ -15,7 +15,7 @@ To allow a particular user to use `Client Registration CLI` the {project_name} a
.Procedure .Procedure
. Log in to the Admin Console (for example, http://localhost:8080/auth/admin) as [command]`admin`. . Log in to the Admin Console (for example, http://localhost:8080{kc_admins_path}) as [command]`admin`.
. Select a realm to administer. . Select a realm to administer.
. If you want to use an existing user, select that user to edit; otherwise, create a new user. . If you want to use an existing user, select that user to edit; otherwise, create a new user.
. Select *Role Mappings > Client Roles > realm-management*. If you are in the master realm, select *NAME-realm*, where `NAME` is the name of the target realm. You can grant access to any other realm to users in the master realm. . Select *Role Mappings > Client Roles > realm-management*. If you are in the master realm, select *NAME-realm*, where `NAME` is the name of the target realm. You can grant access to any other realm to users in the master realm.
@ -92,17 +92,17 @@ For example, on:
* Linux: * Linux:
+ +
[options="npwrap"] [options="npwrap",subs="attributes+"]
---- ----
$ kcreg.sh config credentials --server http://localhost:8080/auth --realm demo --user user --client reg-cli $ kcreg.sh config credentials --server http://localhost:8080{kc_base_path} --realm demo --user user --client reg-cli
$ kcreg.sh create -s clientId=my_client -s 'redirectUris=["http://localhost:8980/myapp/*"]' $ kcreg.sh create -s clientId=my_client -s 'redirectUris=["http://localhost:8980/myapp/*"]'
$ kcreg.sh get my_client $ kcreg.sh get my_client
---- ----
* Windows: * Windows:
+ +
[options="npwrap"] [options="npwrap",subs="attributes+"]
---- ----
c:\> kcreg config credentials --server http://localhost:8080/auth --realm demo --user user --client reg-cli c:\> kcreg config credentials --server http://localhost:8080{kc_base_path} --realm demo --user user --client reg-cli
c:\> kcreg create -s clientId=my_client -s "redirectUris=[\"http://localhost:8980/myapp/*\"]" c:\> kcreg create -s clientId=my_client -s "redirectUris=[\"http://localhost:8980/myapp/*\"]"
c:\> kcreg get my_client c:\> kcreg get my_client
---- ----

View file

@ -13,11 +13,14 @@ For more information on how to set up and configure a Docker registry, see the l
For users with more advanced Docker registry configurations, it is generally recommended to provide your own registry configuration file. The {project_name} Docker provider supports this mechanism via the _Registry Config File_ Format Option. Choosing this option will generate output similar to the following: For users with more advanced Docker registry configurations, it is generally recommended to provide your own registry configuration file. The {project_name} Docker provider supports this mechanism via the _Registry Config File_ Format Option. Choosing this option will generate output similar to the following:
auth: [source,subs="attributes+"]
token: ----
realm: http://localhost:8080/auth/realms/master/protocol/docker-v2/auth auth:
service: docker-test token:
issuer: http://localhost:8080/auth/realms/master realm: http://localhost:8080{kc_realms_path}/master/protocol/docker-v2/auth
service: docker-test
issuer: http://localhost:8080{kc_realms_path}/master
----
This output can then be copied into any existing registry config file. See the link:https://docs.docker.com/registry/configuration/[registry config file specification] for more information on how the file should be set up, or start with link:https://github.com/distribution/distribution/blob/main/cmd/registry/config-example.yml[a basic example]. This output can then be copied into any existing registry config file. See the link:https://docs.docker.com/registry/configuration/[registry config file specification] for more information on how the file should be set up, or start with link:https://github.com/distribution/distribution/blob/main/cmd/registry/config-example.yml[a basic example].
@ -28,9 +31,12 @@ WARNING: Don't forget to configure the `rootcertbundle` field with the location
Often times it is appropriate to use a simple environment variable override for develop or POC Docker registries. While this approach is usually not recommended for production use, it can be helpful when one requires quick-and-dirty way to stand up a registry. Simply use the _Variable Override_ Format Option from the client installation tab, and an output should appear like the one below: Often times it is appropriate to use a simple environment variable override for develop or POC Docker registries. While this approach is usually not recommended for production use, it can be helpful when one requires quick-and-dirty way to stand up a registry. Simply use the _Variable Override_ Format Option from the client installation tab, and an output should appear like the one below:
REGISTRY_AUTH_TOKEN_REALM: http://localhost:8080/auth/realms/master/protocol/docker-v2/auth [source,subs="attributes+"]
REGISTRY_AUTH_TOKEN_SERVICE: docker-test ----
REGISTRY_AUTH_TOKEN_ISSUER: http://localhost:8080/auth/realms/master REGISTRY_AUTH_TOKEN_REALM: http://localhost:8080{kc_realms_path}/master/protocol/docker-v2/auth
REGISTRY_AUTH_TOKEN_SERVICE: docker-test
REGISTRY_AUTH_TOKEN_ISSUER: http://localhost:8080{kc_realms_path}/master
----
WARNING: Don't forget to configure the `REGISTRY_AUTH_TOKEN_ROOTCERTBUNDLE` override with the location of the {project_name} realm's public key. The auth configuration will not work without this argument. WARNING: Don't forget to configure the `REGISTRY_AUTH_TOKEN_ROOTCERTBUNDLE` override with the location of the {project_name} realm's public key. The auth configuration will not work without this argument.

View file

@ -49,7 +49,7 @@ convenient to use relative URI options in your client configuration.
With relative URIs the URI is resolved as relative to the URL used to access {project_name}. With relative URIs the URI is resolved as relative to the URL used to access {project_name}.
For example if the URL to your application is `$$https://acme.org/myapp$$` and the URL to {project_name} is `$$https://acme.org/auth$$`, then you can use For example if the URL to your application is `$$https://acme.org/myapp$$` and the URL to {project_name} is `\https://acme.org{kc_base_path}`, then you can use
the redirect-uri `/myapp` instead of `$$https://acme.org/myapp$$`. the redirect-uri `/myapp` instead of `$$https://acme.org/myapp$$`.
===== Admin URL configuration ===== Admin URL configuration

View file

@ -6,7 +6,7 @@ You can secure Apache Camel endpoints implemented with the https://camel.apache.
For example: For example:
[source,xml] [source,xml,subs="attributes+"]
---- ----
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
@ -21,7 +21,7 @@ For example:
<property name="realm" value="demo"/> <property name="realm" value="demo"/>
<property name="resource" value="admin-camel-endpoint"/> <property name="resource" value="admin-camel-endpoint"/>
<property name="bearerOnly" value="true"/> <property name="bearerOnly" value="true"/>
<property name="authServerUrl" value="http://localhost:8080/auth" /> <property name="authServerUrl" value="http://localhost:8080{kc_base_path}" />
<property name="sslRequired" value="EXTERNAL"/> <property name="sslRequired" value="EXTERNAL"/>
</bean> </bean>

View file

@ -8,7 +8,7 @@ To run your CXF endpoints secured by {project_name} on separate Jetty engines, p
. Add `META-INF/spring/beans.xml` to your application, and in it, declare `httpj:engine-factory` with Jetty SecurityHandler with injected `KeycloakJettyAuthenticator`. The configuration for a CFX JAX-WS application might resemble this one: . Add `META-INF/spring/beans.xml` to your application, and in it, declare `httpj:engine-factory` with Jetty SecurityHandler with injected `KeycloakJettyAuthenticator`. The configuration for a CFX JAX-WS application might resemble this one:
+ +
[source,xml] [source,xml,subs="attributes+"]
---- ----
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
@ -28,7 +28,7 @@ To run your CXF endpoints secured by {project_name} on separate Jetty engines, p
<property name="realm" value="demo"/> <property name="realm" value="demo"/>
<property name="resource" value="custom-cxf-endpoint"/> <property name="resource" value="custom-cxf-endpoint"/>
<property name="bearerOnly" value="true"/> <property name="bearerOnly" value="true"/>
<property name="authServerUrl" value="http://localhost:8080/auth" /> <property name="authServerUrl" value="http://localhost:8080{kc_base_path}" />
<property name="sslRequired" value="EXTERNAL"/> <property name="sslRequired" value="EXTERNAL"/>
</bean> </bean>

View file

@ -24,13 +24,13 @@ sshRealm=keycloak
. Add the `$FUSE_HOME/etc/keycloak-direct-access.json` file with content similar to the following (based on your environment and {project_name} client settings): . Add the `$FUSE_HOME/etc/keycloak-direct-access.json` file with content similar to the following (based on your environment and {project_name} client settings):
+ +
[source,json] [source,json,subs="attributes+"]
---- ----
{ {
"realm": "demo", "realm": "demo",
"resource": "ssh-jmx-admin-client", "resource": "ssh-jmx-admin-client",
"ssl-required" : "external", "ssl-required" : "external",
"auth-server-url" : "http://localhost:8080/auth", "auth-server-url" : "http://localhost:8080{kc_base_path}",
"credentials": { "credentials": {
"secret": "password" "secret": "password"
} }

View file

@ -20,12 +20,12 @@ hawtio.rolePrincipalClasses=org.keycloak.adapters.jaas.RolePrincipal,org.apache.
. Create the `keycloak-hawtio-client.json` file in the `$FUSE_HOME/etc` directory using content similar to that shown in the example below. Change the `realm`, `resource`, and `auth-server-url` properties according to your {project_name} environment. The `resource` property must point to the client created in the previous step. This file is used by the client (Hawtio JavaScript application) side. . Create the `keycloak-hawtio-client.json` file in the `$FUSE_HOME/etc` directory using content similar to that shown in the example below. Change the `realm`, `resource`, and `auth-server-url` properties according to your {project_name} environment. The `resource` property must point to the client created in the previous step. This file is used by the client (Hawtio JavaScript application) side.
[source,json] [source,json,subs="attributes+"]
---- ----
{ {
"realm" : "demo", "realm" : "demo",
"resource" : "hawtio-client", "resource" : "hawtio-client",
"auth-server-url" : "http://localhost:8080/auth", "auth-server-url" : "http://localhost:8080{kc_base_path}",
"ssl-required" : "external", "ssl-required" : "external",
"public-client" : true "public-client" : true
} }
@ -33,13 +33,13 @@ hawtio.rolePrincipalClasses=org.keycloak.adapters.jaas.RolePrincipal,org.apache.
. Create the `keycloak-hawtio.json` file in the `$FUSE_HOME/etc` dicrectory using content similar to that shown in the example below. Change the `realm` and `auth-server-url` properties according to your {project_name} environment. This file is used by the adapters on the server (JAAS Login module) side. . Create the `keycloak-hawtio.json` file in the `$FUSE_HOME/etc` dicrectory using content similar to that shown in the example below. Change the `realm` and `auth-server-url` properties according to your {project_name} environment. This file is used by the adapters on the server (JAAS Login module) side.
+ +
[source,json] [source,json,subs="attributes+"]
---- ----
{ {
"realm" : "demo", "realm" : "demo",
"resource" : "jaas", "resource" : "jaas",
"bearer-only" : true, "bearer-only" : true,
"auth-server-url" : "http://localhost:8080/auth", "auth-server-url" : "http://localhost:8080{kc_base_path}",
"ssl-required" : "external", "ssl-required" : "external",
"use-resource-role-mappings": false, "use-resource-role-mappings": false,
"principal-attribute": "preferred_username" "principal-attribute": "preferred_username"

View file

@ -9,7 +9,7 @@ You can use this method if you have a servlet class inside your OSGI bundled pro
. {project_name} provides `org.keycloak.adapters.osgi.undertow.PaxWebIntegrationService`, which allows injecting jetty-web.xml and configuring security constraints for your application. You need to declare such services in the `OSGI-INF/blueprint/blueprint.xml` file inside your application. Note that your servlet needs to depend on it. . {project_name} provides `org.keycloak.adapters.osgi.undertow.PaxWebIntegrationService`, which allows injecting jetty-web.xml and configuring security constraints for your application. You need to declare such services in the `OSGI-INF/blueprint/blueprint.xml` file inside your application. Note that your servlet needs to depend on it.
An example configuration: An example configuration:
+ +
[source,xml] [source,xml,subs="attributes+"]
---- ----
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"

View file

@ -53,12 +53,12 @@ For example:
+ +
For example: For example:
+ +
[source,json] [source,json,subs="attributes+"]
---- ----
{ {
"realm": "demo", "realm": "demo",
"resource": "customer-portal", "resource": "customer-portal",
"auth-server-url": "http://localhost:8080/auth", "auth-server-url": "http://localhost:8080{kc_base_path}",
"ssl-required" : "external", "ssl-required" : "external",
"credentials": { "credentials": {
"secret": "password" "secret": "password"

View file

@ -24,13 +24,13 @@ sshRealm=keycloak
. Add the `$FUSE_HOME/etc/keycloak-direct-access.json` file with content similar to the following (based on your environment and {project_name} client settings): . Add the `$FUSE_HOME/etc/keycloak-direct-access.json` file with content similar to the following (based on your environment and {project_name} client settings):
+ +
[source,json] [source,json,subs="attributes+"]
---- ----
{ {
"realm": "demo", "realm": "demo",
"resource": "ssh-jmx-admin-client", "resource": "ssh-jmx-admin-client",
"ssl-required" : "external", "ssl-required" : "external",
"auth-server-url" : "http://localhost:8080/auth", "auth-server-url" : "http://localhost:8080{kc_base_path}",
"credentials": { "credentials": {
"secret": "password" "secret": "password"
} }

View file

@ -10,12 +10,12 @@ To secure the Hawtio Administration Console with {project_name}, perform the fol
. Create the `keycloak-hawtio-client.json` file in the `$FUSE_HOME/etc` directory using content similar to that shown in the example below. Change the `realm`, `resource`, and `auth-server-url` properties according to your {project_name} environment. The `resource` property must point to the client created in the previous step. This file is used by the client (Hawtio JavaScript application) side. . Create the `keycloak-hawtio-client.json` file in the `$FUSE_HOME/etc` directory using content similar to that shown in the example below. Change the `realm`, `resource`, and `auth-server-url` properties according to your {project_name} environment. The `resource` property must point to the client created in the previous step. This file is used by the client (Hawtio JavaScript application) side.
+ +
[source,json] [source,json,subs="attributes+"]
---- ----
{ {
"realm" : "demo", "realm" : "demo",
"clientId" : "hawtio-client", "clientId" : "hawtio-client",
"url" : "http://localhost:8080/auth", "url" : "http://localhost:8080{kc_base_path}",
"ssl-required" : "external", "ssl-required" : "external",
"public-client" : true "public-client" : true
} }
@ -23,12 +23,12 @@ To secure the Hawtio Administration Console with {project_name}, perform the fol
. Create the `keycloak-direct-access.json` file in the `$FUSE_HOME/etc` directory using content similar to that shown in the example below. Change the `realm` and `url` properties according to your {project_name} environment. This file is used by JavaScript client. . Create the `keycloak-direct-access.json` file in the `$FUSE_HOME/etc` directory using content similar to that shown in the example below. Change the `realm` and `url` properties according to your {project_name} environment. This file is used by JavaScript client.
+ +
[source,json] [source,json,subs="attributes+"]
---- ----
{ {
"realm" : "demo", "realm" : "demo",
"resource" : "ssh-jmx-admin-client", "resource" : "ssh-jmx-admin-client",
"auth-server-url" : "http://localhost:8080/auth", "auth-server-url" : "http://localhost:8080{kc_base_path}",
"ssl-required" : "external", "ssl-required" : "external",
"credentials": { "credentials": {
"secret": "password" "secret": "password"
@ -38,13 +38,13 @@ To secure the Hawtio Administration Console with {project_name}, perform the fol
. Create the `keycloak-hawtio.json` file in the `$FUSE_HOME/etc` dicrectory using content similar to that shown in the example below. Change the `realm` and `auth-server-url` properties according to your {project_name} environment. This file is used by the adapters on the server (JAAS Login module) side. . Create the `keycloak-hawtio.json` file in the `$FUSE_HOME/etc` dicrectory using content similar to that shown in the example below. Change the `realm` and `auth-server-url` properties according to your {project_name} environment. This file is used by the adapters on the server (JAAS Login module) side.
+ +
[source,json] [source,json,subs="attributes+"]
---- ----
{ {
"realm" : "demo", "realm" : "demo",
"resource" : "jaas", "resource" : "jaas",
"bearer-only" : true, "bearer-only" : true,
"auth-server-url" : "http://localhost:8080/auth", "auth-server-url" : "http://localhost:8080{kc_base_path}",
"ssl-required" : "external", "ssl-required" : "external",
"use-resource-role-mappings": false, "use-resource-role-mappings": false,
"principal-attribute": "preferred_username" "principal-attribute": "preferred_username"

View file

@ -9,7 +9,7 @@ You can use this method if you have a servlet class inside your OSGI bundled pro
. {project_name} provides `org.keycloak.adapters.osgi.undertow.PaxWebIntegrationService`, which allows configuring authentication method and security constraints for your application. You need to declare such services in the `OSGI-INF/blueprint/blueprint.xml` file inside your application. Note that your servlet needs to depend on it. . {project_name} provides `org.keycloak.adapters.osgi.undertow.PaxWebIntegrationService`, which allows configuring authentication method and security constraints for your application. You need to declare such services in the `OSGI-INF/blueprint/blueprint.xml` file inside your application. Note that your servlet needs to depend on it.
An example configuration: An example configuration:
+ +
[source,xml] [source,xml,subs="attributes+"]
---- ----
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"

View file

@ -68,12 +68,12 @@ through the `KeycloakInstalled` constructor.
In the example below, the client configuration for `desktop-app` In the example below, the client configuration for `desktop-app`
uses the following `keycloak.json`: uses the following `keycloak.json`:
[source,json] [source,json,subs="attributes+"]
---- ----
{ {
"realm": "desktop-app-auth", "realm": "desktop-app-auth",
"auth-server-url": "http://localhost:8081/auth", "auth-server-url": "http://localhost:8081{kc_base_path}",
"ssl-required": "external", "ssl-required": "external",
"resource": "desktop-app", "resource": "desktop-app",
"public-client": true, "public-client": true,

View file

@ -5,13 +5,13 @@
Each Java adapter supported by {project_name} can be configured by a simple JSON file. Each Java adapter supported by {project_name} can be configured by a simple JSON file.
This is what one might look like: This is what one might look like:
[source,json] [source,json,subs="attributes+"]
---- ----
{ {
"realm" : "demo", "realm" : "demo",
"resource" : "customer-portal", "resource" : "customer-portal",
"realm-public-key" : "MIGfMA0GCSqGSIb3D...31LwIDAQAB", "realm-public-key" : "MIGfMA0GCSqGSIb3D...31LwIDAQAB",
"auth-server-url" : "https://localhost:8443/auth", "auth-server-url" : "https://localhost:8443{kc_base_path}",
"ssl-required" : "external", "ssl-required" : "external",
"use-resource-role-mappings" : false, "use-resource-role-mappings" : false,
"enable-cors" : true, "enable-cors" : true,
@ -69,7 +69,7 @@ realm-public-key::
will never download new keys from {project_name}, so when {project_name} rotate it's keys, adapter will break. will never download new keys from {project_name}, so when {project_name} rotate it's keys, adapter will break.
auth-server-url:: auth-server-url::
The base URL of the {project_name} server. All other {project_name} pages and REST service endpoints are derived from this. It is usually of the form `$$https://host:port/auth$$`. The base URL of the {project_name} server. All other {project_name} pages and REST service endpoints are derived from this. It is usually of the form `\https://host:port{kc_base_path}`.
This is _REQUIRED._ This is _REQUIRED._
ssl-required:: ssl-required::

View file

@ -238,7 +238,7 @@ While you don't have to specify KEYCLOAK as an `auth-method`, you still have to
You do not, however, have to create a `WEB-INF/keycloak.json` file. You do not, however, have to create a `WEB-INF/keycloak.json` file.
The metadata is instead defined within server configuration (`standalone.xml`) in the {project_name} subsystem definition. The metadata is instead defined within server configuration (`standalone.xml`) in the {project_name} subsystem definition.
[source,xml] [source,xml,subs="attributes+"]
---- ----
<extensions> <extensions>
<extension module="org.keycloak.keycloak-adapter-subsystem"/> <extension module="org.keycloak.keycloak-adapter-subsystem"/>
@ -248,7 +248,7 @@ The metadata is instead defined within server configuration (`standalone.xml`) i
<subsystem xmlns="urn:jboss:domain:keycloak:1.1"> <subsystem xmlns="urn:jboss:domain:keycloak:1.1">
<secure-deployment name="WAR MODULE NAME.war"> <secure-deployment name="WAR MODULE NAME.war">
<realm>demo</realm> <realm>demo</realm>
<auth-server-url>http://localhost:8081/auth</auth-server-url> <auth-server-url>http://localhost:8081{kc_base_path}</auth-server-url>
<ssl-required>external</ssl-required> <ssl-required>external</ssl-required>
<resource>customer-portal</resource> <resource>customer-portal</resource>
<credential name="secret">password</credential> <credential name="secret">password</credential>
@ -267,11 +267,11 @@ It provides an example XML file you can cut and paste.
If you have multiple deployments secured by the same realm you can share the realm configuration in a separate element. For example: If you have multiple deployments secured by the same realm you can share the realm configuration in a separate element. For example:
[source,xml] [source,xml,subs="attributes+"]
---- ----
<subsystem xmlns="urn:jboss:domain:keycloak:1.1"> <subsystem xmlns="urn:jboss:domain:keycloak:1.1">
<realm name="demo"> <realm name="demo">
<auth-server-url>http://localhost:8080/auth</auth-server-url> <auth-server-url>http://localhost:8080{kc_base_path}</auth-server-url>
<ssl-required>external</ssl-required> <ssl-required>external</ssl-required>
</realm> </realm>
<secure-deployment name="customer-portal.war"> <secure-deployment name="customer-portal.war">

View file

@ -65,7 +65,7 @@ You will have to define all adapter settings within the `jetty-web.xml` file as
Instead of using keycloak.json, you can define everything within the `jetty-web.xml`. Instead of using keycloak.json, you can define everything within the `jetty-web.xml`.
You'll just have to figure out how the json settings match to the `org.keycloak.representations.adapters.config.AdapterConfig` class. You'll just have to figure out how the json settings match to the `org.keycloak.representations.adapters.config.AdapterConfig` class.
+ +
[source] [source,subs="attributes+"]
---- ----
<?xml version="1.0"?> <?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd"> <!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
@ -77,7 +77,7 @@ You'll just have to figure out how the json settings match to the `org.keycloak.
<New class="org.keycloak.representations.adapters.config.AdapterConfig"> <New class="org.keycloak.representations.adapters.config.AdapterConfig">
<Set name="realm">tomcat</Set> <Set name="realm">tomcat</Set>
<Set name="resource">customer-portal</Set> <Set name="resource">customer-portal</Set>
<Set name="authServerUrl">http://localhost:8081/auth</Set> <Set name="authServerUrl">http://localhost:8081{kc_base_path}</Set>
<Set name="sslRequired">external</Set> <Set name="sslRequired">external</Set>
<Set name="credentials"> <Set name="credentials">
<Map> <Map>

View file

@ -3,7 +3,7 @@
[[_java_adapter_logout]] [[_java_adapter_logout]]
You can log out of a web application in multiple ways. You can log out of a web application in multiple ways.
For Jakarta EE servlet containers, you can call `HttpServletRequest.logout()`. For other browser applications, you can redirect the browser to For Jakarta EE servlet containers, you can call `HttpServletRequest.logout()`. For other browser applications, you can redirect the browser to
`$$http://auth-server/auth/realms/{realm-name}/protocol/openid-connect/logout?redirect_uri=encodedRedirectUri$$`, which logs you out if you have an SSO session with your browser. `\http://auth-server{kc_realms_path}/{realm-name}/protocol/openid-connect/logout?redirect_uri=encodedRedirectUri`, which logs you out if you have an SSO session with your browser.
When using the `HttpServletRequest.logout()` option the adapter executes a back-channel POST call against the {project_name} server passing the refresh token. When using the `HttpServletRequest.logout()` option the adapter executes a back-channel POST call against the {project_name} server passing the refresh token.
If the method is executed from an unprotected page (a page that does not check for a valid token) the refresh token can be unavailable and, in that case, If the method is executed from an unprotected page (a page that does not check for a valid token) the refresh token can be unavailable and, in that case,

View file

@ -62,10 +62,10 @@ Use the procedure to configure your Spring Boot app to use {project_name}.
. Instead of a `keycloak.json` file, you configure the realm for the Spring Boot adapter via the normal Spring Boot configuration. For example: . Instead of a `keycloak.json` file, you configure the realm for the Spring Boot adapter via the normal Spring Boot configuration. For example:
+ +
[source] [source,subs="attributes+"]
---- ----
keycloak.realm = demorealm keycloak.realm = demorealm
keycloak.auth-server-url = http://127.0.0.1:8080/auth keycloak.auth-server-url = http://127.0.0.1:8080{kc_base_path}
keycloak.ssl-required = external keycloak.ssl-required = external
keycloak.resource = demoapp keycloak.resource = demoapp
keycloak.credentials.secret = 11111111-1111-1111-1111-111111111111 keycloak.credentials.secret = 11111111-1111-1111-1111-111111111111

View file

@ -3,7 +3,7 @@
{project_name} comes with a client-side JavaScript library that can be used to secure HTML5/JavaScript applications. The JavaScript adapter has built-in support for Cordova applications. {project_name} comes with a client-side JavaScript library that can be used to secure HTML5/JavaScript applications. The JavaScript adapter has built-in support for Cordova applications.
The library can be retrieved directly from the {project_name} server at `/auth/js/keycloak.js` and is also distributed as a ZIP archive. The library can be retrieved directly from the {project_name} server at `{kc_js_path}/keycloak.js` and is also distributed as a ZIP archive.
A best practice is to load the JavaScript adapter directly from {project_name} Server as it will automatically be updated when you upgrade the server. If you copy the adapter to your web application instead, make sure you upgrade the adapter only after you have upgraded the server. A best practice is to load the JavaScript adapter directly from {project_name} Server as it will automatically be updated when you upgrade the server. If you copy the adapter to your web application instead, make sure you upgrade the adapter only after you have upgraded the server.
@ -55,10 +55,10 @@ var keycloak = new Keycloak('http://localhost:8080/myapp/keycloak.json');
Alternatively, you can pass in a JavaScript object with the required configuration instead: Alternatively, you can pass in a JavaScript object with the required configuration instead:
[source,javascript] [source,javascript,subs="attributes+"]
---- ----
var keycloak = new Keycloak({ var keycloak = new Keycloak({
url: 'http://keycloak-server/auth', url: 'http://keycloak-server${kc_base_path}',
realm: 'myrealm', realm: 'myrealm',
clientId: 'myapp' clientId: 'myapp'
}); });
@ -358,11 +358,11 @@ An affected browser is for example Safari starting with version 13.1.
===== Constructor ===== Constructor
[source,javascript] [source,javascript,subs="attributes+"]
---- ----
new Keycloak(); new Keycloak();
new Keycloak('http://localhost/keycloak.json'); new Keycloak('http://localhost/keycloak.json');
new Keycloak({ url: 'http://localhost/auth', realm: 'myrealm', clientId: 'myApp' }); new Keycloak({ url: 'http://localhost{kc_base_path}', realm: 'myrealm', clientId: 'myApp' });
---- ----
===== Properties ===== Properties

View file

@ -15,7 +15,7 @@ To configure _mod_auth_openidc_ you'll need
An example configuration would look like the following. An example configuration would look like the following.
[source] [source,subs="attributes+"]
---- ----
LoadModule auth_openidc_module modules/mod_auth_openidc.so LoadModule auth_openidc_module modules/mod_auth_openidc.so
@ -29,7 +29,7 @@ ServerName ${HOSTIP}
#this is required by mod_auth_openidc #this is required by mod_auth_openidc
OIDCCryptoPassphrase a-random-secret-used-by-apache-oidc-and-balancer OIDCCryptoPassphrase a-random-secret-used-by-apache-oidc-and-balancer
OIDCProviderMetadataURL ${KC_ADDR}/auth/realms/${KC_REALM}/.well-known/openid-configuration OIDCProviderMetadataURL ${KC_ADDR}{kc_realms_path}/${KC_REALM}/.well-known/openid-configuration
OIDCClientID ${CLIENT_ID} OIDCClientID ${CLIENT_ID}
OIDCClientSecret ${CLIENT_SECRET} OIDCClientSecret ${CLIENT_SECRET}

View file

@ -67,12 +67,12 @@ Instantiation with this method results in all of the reasonable defaults
being used. As alternative, it's also possible to provide a configuration being used. As alternative, it's also possible to provide a configuration
object, rather than the `keycloak.json` file: object, rather than the `keycloak.json` file:
[source,javascript] [source,javascript,subs="attributes+"]
---- ----
let kcConfig = { let kcConfig = {
clientId: 'myclient', clientId: 'myclient',
bearerOnly: true, bearerOnly: true,
serverUrl: 'http://localhost:8080/auth', serverUrl: 'http://localhost:8080{kc_base_path}',
realm: 'myrealm', realm: 'myrealm',
realmPublicKey: 'MIIBIjANB...' realmPublicKey: 'MIIBIjANB...'
}; };

View file

@ -12,7 +12,7 @@ The most important endpoint to understand is the `well-known` configuration endp
To obtain the full URL, add the base URL for {project_name} and replace `{realm-name}` with the name of your realm. For example: To obtain the full URL, add the base URL for {project_name} and replace `{realm-name}` with the name of your realm. For example:
$$http://localhost:8080/auth/realms/master/.well-known/openid-configuration$$ \http://localhost:8080{kc_realms_path}/master/.well-known/openid-configuration
Some RP libraries retrieve all required endpoints from this endpoint, but for others you might need to list the endpoints individually. Some RP libraries retrieve all required endpoints from this endpoint, but for others you might need to list the endpoints individually.
@ -96,7 +96,7 @@ For more details on how to invoke on this endpoint, see https://datatracker.ietf
===== Device Authorization endpoint ===== Device Authorization endpoint
.... ....
/realms/{realm-name}/protocol/openid-connect/auth/device /realms/{realm-name}/protocol/openid-connectauth/device
.... ....
The device authorization endpoint is used to obtain a device code and a user code. It can be invoked by confidential or public clients. The device authorization endpoint is used to obtain a device code and a user code. It can be invoked by confidential or public clients.
@ -179,7 +179,7 @@ For more details refer to the https://datatracker.ietf.org/doc/html/rfc6749#sect
The following example shows how to obtain an access token for a user in the realm `master` with username `user` and password `password`. The example is using The following example shows how to obtain an access token for a user in the realm `master` with username `user` and password `password`. The example is using
the confidential client `myclient`: the confidential client `myclient`:
[source,bash] [source,bash,subs="attributes+"]
---- ----
curl \ curl \
-d "client_id=myclient" \ -d "client_id=myclient" \
@ -187,7 +187,7 @@ curl \
-d "username=user" \ -d "username=user" \
-d "password=password" \ -d "password=password" \
-d "grant_type=password" \ -d "grant_type=password" \
"http://localhost:8080/auth/realms/master/protocol/openid-connect/token" "http://localhost:8080{kc_realms_path}/master/protocol/openid-connect/token"
---- ----
===== Client credentials ===== Client credentials

View file

@ -36,14 +36,14 @@ This is what one might look like:
<IDP entityID="idp" <IDP entityID="idp"
signaturesRequired="true"> signaturesRequired="true">
<SingleSignOnService requestBinding="POST" <SingleSignOnService requestBinding="POST"
bindingUrl="http://localhost:8081/auth/realms/demo/protocol/saml" bindingUrl="http://localhost:8081{kc_realms_path}/demo/protocol/saml"
/> />
<SingleLogoutService <SingleLogoutService
requestBinding="POST" requestBinding="POST"
responseBinding="POST" responseBinding="POST"
postBindingUrl="http://localhost:8081/auth/realms/demo/protocol/saml" postBindingUrl="http://localhost:8081{kc_realms_path}/demo/protocol/saml"
redirectBindingUrl="http://localhost:8081/auth/realms/demo/protocol/saml" redirectBindingUrl="http://localhost:8081{kc_realms_path}/demo/protocol/saml"
/> />
<Keys> <Keys>
<Key signing="true"> <Key signing="true">

View file

@ -7,7 +7,7 @@ While you don't have to specify KEYCLOAK-SAML as an `auth-method`, you still hav
You do not, however, have to create a `WEB-INF/keycloak-saml.xml` file. You do not, however, have to create a `WEB-INF/keycloak-saml.xml` file.
This metadata is instead defined within the XML in your server's `domain.xml` or `standalone.xml` subsystem configuration section. This metadata is instead defined within the XML in your server's `domain.xml` or `standalone.xml` subsystem configuration section.
[source,xml] [source,xml,subs="attributes+"]
---- ----
<extensions> <extensions>
@ -31,7 +31,7 @@ The rest of the configuration uses the same XML syntax as `keycloak-saml.xml` co
An example configuration: An example configuration:
[source,xml] [source,xml,subs="attributes+"]
---- ----
<subsystem xmlns="urn:jboss:domain:keycloak-saml:1.1"> <subsystem xmlns="urn:jboss:domain:keycloak-saml:1.1">
@ -57,7 +57,7 @@ An example configuration:
<SingleSignOnService signRequest="true" <SingleSignOnService signRequest="true"
validateResponseSignature="true" validateResponseSignature="true"
requestBinding="POST" requestBinding="POST"
bindingUrl="http://localhost:8080/auth/realms/saml-demo/protocol/saml"/> bindingUrl="http://localhost:8080{kc_realms_path}/saml-demo/protocol/saml"/>
<SingleLogoutService <SingleLogoutService
validateRequestSignature="true" validateRequestSignature="true"
@ -66,8 +66,8 @@ An example configuration:
signResponse="true" signResponse="true"
requestBinding="POST" requestBinding="POST"
responseBinding="POST" responseBinding="POST"
postBindingUrl="http://localhost:8080/auth/realms/saml-demo/protocol/saml" postBindingUrl="http://localhost:8080{kc_realms_path}/saml-demo/protocol/saml"
redirectBindingUrl="http://localhost:8080/auth/realms/saml-demo/protocol/saml"/> redirectBindingUrl="http://localhost:8080{kc_realms_path}/saml-demo/protocol/saml"/>
<Keys> <Keys>
<Key signing="true" > <Key signing="true" >
<KeyStore resource="/WEB-INF/keystore.jks" password="store123"> <KeyStore resource="/WEB-INF/keystore.jks" password="store123">

View file

@ -239,10 +239,10 @@ Use this procedure to retrieve that file from the IdP.
. Use this command, substituting with the correct value for $idp_host: . Use this command, substituting with the correct value for $idp_host:
+ +
[source] [source,subs="attributes+"]
---- ----
curl -k -o /etc/httpd/saml2/idp_metadata.xml \ curl -k -o /etc/httpd/saml2/idp_metadata.xml \
https://$idp_host/auth/realms/test_realm/protocol/saml/descriptor https://$idp_host{kc_realms_path}/test_realm/protocol/saml/descriptor
---- ----
+ +
Mellon is now fully configured. Mellon is now fully configured.

View file

@ -29,8 +29,9 @@ Token exchange in {project_name} is a very loose implementation of the link:http
We have extended it a little, ignored some of it, and loosely interpreted other parts of the specification. It is We have extended it a little, ignored some of it, and loosely interpreted other parts of the specification. It is
a simple grant type invocation on a realm's OpenID Connect token endpoint. a simple grant type invocation on a realm's OpenID Connect token endpoint.
[source,subs="attributes+"]
---- ----
/auth/realms/{realm}/protocol/openid-connect/token {kc_realms_path}/{realm}/protocol/openid-connect/token
---- ----
It accepts form parameters (`application/x-www-form-urlencoded`) as input and the output depends on the type of token you requested an exchange for. It accepts form parameters (`application/x-www-form-urlencoded`) as input and the output depends on the type of token you requested an exchange for.
@ -181,7 +182,7 @@ try to make an exchange.
When your client is exchanging an existing token for a token targeting another client, you use the `audience` parameter. When your client is exchanging an existing token for a token targeting another client, you use the `audience` parameter.
This parameter must be the client identifier for the target client that you configured in the Admin Console. This parameter must be the client identifier for the target client that you configured in the Admin Console.
[source,bash] [source,bash,subs="attributes+"]
---- ----
curl -X POST \ curl -X POST \
-d "client_id=starting-client" \ -d "client_id=starting-client" \
@ -190,7 +191,7 @@ curl -X POST \
-d "subject_token=...." \ -d "subject_token=...." \
--data-urlencode "requested_token_type=urn:ietf:params:oauth:token-type:refresh_token" \ --data-urlencode "requested_token_type=urn:ietf:params:oauth:token-type:refresh_token" \
-d "audience=target-client" \ -d "audience=target-client" \
http://localhost:8080/auth/realms/myrealm/protocol/openid-connect/token http://localhost:8080{kc_realms_path}/myrealm/protocol/openid-connect/token
---- ----
@ -268,7 +269,7 @@ Your client now has permission to invoke. If you do not do this correctly, you
When your client is exchanging an existing internal token to an external one, you provide the `requested_issuer` parameter. The parameter must be the alias of a configured identity provider. When your client is exchanging an existing internal token to an external one, you provide the `requested_issuer` parameter. The parameter must be the alias of a configured identity provider.
[source,bash] [source,bash,subs="attributes+"]
---- ----
curl -X POST \ curl -X POST \
-d "client_id=starting-client" \ -d "client_id=starting-client" \
@ -277,7 +278,7 @@ curl -X POST \
-d "subject_token=...." \ -d "subject_token=...." \
--data-urlencode "requested_token_type=urn:ietf:params:oauth:token-type:access_token" \ --data-urlencode "requested_token_type=urn:ietf:params:oauth:token-type:access_token" \
-d "requested_issuer=google" \ -d "requested_issuer=google" \
http://localhost:8080/auth/realms/myrealm/protocol/openid-connect/token http://localhost:8080{kc_realms_path}/myrealm/protocol/openid-connect/token
---- ----
The `subject_token` parameter must be an access token for the target realm. The `requested_token_type` parameter The `subject_token` parameter must be an access token for the target realm. The `requested_token_type` parameter
@ -354,7 +355,7 @@ By default, the internal token minted will use the calling client to determine w
mappers defined for the calling client. Alternatively, you can specify a different target client using the `audience` mappers defined for the calling client. Alternatively, you can specify a different target client using the `audience`
parameter. parameter.
[source,bash] [source,bash,subs="attributes+"]
---- ----
curl -X POST \ curl -X POST \
-d "client_id=starting-client" \ -d "client_id=starting-client" \
@ -364,7 +365,7 @@ curl -X POST \
-d "subject_issuer=myOidcProvider" \ -d "subject_issuer=myOidcProvider" \
--data-urlencode "subject_token_type=urn:ietf:params:oauth:token-type:access_token" \ --data-urlencode "subject_token_type=urn:ietf:params:oauth:token-type:access_token" \
-d "audience=target-client" \ -d "audience=target-client" \
http://localhost:8080/auth/realms/myrealm/protocol/openid-connect/token http://localhost:8080{kc_realms_path}/myrealm/protocol/openid-connect/token
---- ----
@ -401,7 +402,7 @@ fine grain admin permissions.
Make the request as described in other chapters except additionally specify the `requested_subject` parameter. The Make the request as described in other chapters except additionally specify the `requested_subject` parameter. The
value of this parameter must be a username or user id. value of this parameter must be a username or user id.
[source,bash] [source,bash,subs="attributes+"]
---- ----
curl -X POST \ curl -X POST \
-d "client_id=starting-client" \ -d "client_id=starting-client" \
@ -411,7 +412,7 @@ curl -X POST \
--data-urlencode "requested_token_type=urn:ietf:params:oauth:token-type:access_token" \ --data-urlencode "requested_token_type=urn:ietf:params:oauth:token-type:access_token" \
-d "audience=target-client" \ -d "audience=target-client" \
-d "requested_subject=wburke" \ -d "requested_subject=wburke" \
http://localhost:8080/auth/realms/myrealm/protocol/openid-connect/token http://localhost:8080{kc_realms_path}/myrealm/protocol/openid-connect/token
---- ----
=== Direct Naked Impersonation === Direct Naked Impersonation
@ -481,14 +482,14 @@ NOTE: Public clients are not allowed to do direct naked impersonations.
To make the request, simply specify the `requested_subject` parameter. This must be the username or user id of To make the request, simply specify the `requested_subject` parameter. This must be the username or user id of
a valid user. You can also specify an `audience` parameter if you wish. a valid user. You can also specify an `audience` parameter if you wish.
[source,bash] [source,bash,subs="attributes+"]
---- ----
curl -X POST \ curl -X POST \
-d "client_id=starting-client" \ -d "client_id=starting-client" \
-d "client_secret=the client secret" \ -d "client_secret=the client secret" \
--data-urlencode "grant_type=urn:ietf:params:oauth:grant-type:token-exchange" \ --data-urlencode "grant_type=urn:ietf:params:oauth:grant-type:token-exchange" \
-d "requested_subject=wburke" \ -d "requested_subject=wburke" \
http://localhost:8080/auth/realms/myrealm/protocol/openid-connect/token http://localhost:8080{kc_realms_path}/myrealm/protocol/openid-connect/token
---- ----
=== Expand permission model with service accounts === Expand permission model with service accounts

View file

@ -6,7 +6,9 @@ include::topics/initialization.adoc[]
include::topics/admin-console.adoc[] include::topics/admin-console.adoc[]
include::topics/user-federation.adoc[] include::topics/user-federation.adoc[]
include::topics/user-federation/ldap.adoc[] include::topics/user-federation/ldap.adoc[]
ifeval::["{kc_dist}" == "wildfly"]
include::topics/user-federation/sssd.adoc[] include::topics/user-federation/sssd.adoc[]
endif::[]
include::topics/user-federation/custom.adoc[] include::topics/user-federation/custom.adoc[]
include::topics/assembly-managing-users.adoc[] include::topics/assembly-managing-users.adoc[]
include::topics/sessions.adoc[] include::topics/sessions.adoc[]
@ -64,10 +66,14 @@ include::topics/vault.adoc[]
include::topics/events.adoc[] include::topics/events.adoc[]
include::topics/events/login.adoc[] include::topics/events/login.adoc[]
include::topics/events/admin.adoc[] include::topics/events/admin.adoc[]
ifeval::["{kc_dist}" == "wildfly"]
include::topics/export-import.adoc[] include::topics/export-import.adoc[]
endif::[]
include::topics/threat.adoc[] include::topics/threat.adoc[]
include::topics/threat/host.adoc[] include::topics/threat/host.adoc[]
ifeval::["{kc_dist}" == "wildfly"]
include::topics/threat/admin.adoc[] include::topics/threat/admin.adoc[]
endif::[]
include::topics/threat/brute-force.adoc[] include::topics/threat/brute-force.adoc[]
include::topics/threat/read-only-attributes.adoc[] include::topics/threat/read-only-attributes.adoc[]
include::topics/threat/clickjacking.adoc[] include::topics/threat/clickjacking.adoc[]

View file

@ -17,7 +17,7 @@ Any user can access the Account Console.
. Make note of the realm name and IP address for the {project_name} server where your account exists. . Make note of the realm name and IP address for the {project_name} server where your account exists.
. In a web browser, enter a URL in this format: `<server-root>/auth/realms/{realm-name}/account`. . In a web browser, enter a URL in this format: `<server-root>{kc_realms_path}/{realm-name}/account`.
. Enter your login name and password. . Enter your login name and password.

View file

@ -48,9 +48,9 @@ For example:
* Linux: * Linux:
+ +
[options="nowrap"] [options="nowrap",subs="attributes+"]
---- ----
$ kcadm.sh config credentials --server http://localhost:8080/auth --realm demo --user admin --client admin $ kcadm.sh config credentials --server http://localhost:8080{kc_base_path} --realm demo --user admin --client admin
$ kcadm.sh create realms -s realm=demorealm -s enabled=true -o $ kcadm.sh create realms -s realm=demorealm -s enabled=true -o
$ CID=$(kcadm.sh create clients -r demorealm -s clientId=my_client -s 'redirectUris=["http://localhost:8980/myapp/*"]' -i) $ CID=$(kcadm.sh create clients -r demorealm -s clientId=my_client -s 'redirectUris=["http://localhost:8980/myapp/*"]' -i)
$ kcadm.sh get clients/$CID/installation/providers/keycloak-oidc-keycloak-json $ kcadm.sh get clients/$CID/installation/providers/keycloak-oidc-keycloak-json
@ -58,9 +58,9 @@ $ kcadm.sh get clients/$CID/installation/providers/keycloak-oidc-keycloak-json
+ +
* Windows: * Windows:
+ +
[options="nowrap"] [options="nowrap",subs="attributes+"]
---- ----
c:\> kcadm config credentials --server http://localhost:8080/auth --realm demo --user admin --client admin c:\> kcadm config credentials --server http://localhost:8080{kc_base_path} --realm demo --user admin --client admin
c:\> kcadm create realms -s realm=demorealm -s enabled=true -o c:\> kcadm create realms -s realm=demorealm -s enabled=true -o
c:\> kcadm create clients -r demorealm -s clientId=my_client -s "redirectUris=[\"http://localhost:8980/myapp/*\"]" -i > clientid.txt c:\> kcadm create clients -r demorealm -s clientId=my_client -s "redirectUris=[\"http://localhost:8980/myapp/*\"]" -i > clientid.txt
c:\> set /p CID=<clientid.txt c:\> set /p CID=<clientid.txt
@ -102,9 +102,9 @@ Ensure the account used for the session has the proper permissions to invoke Adm
Two primary mechanisms are available for authentication. One mechanism uses `kcadm config credentials` to start an authenticated session. Two primary mechanisms are available for authentication. One mechanism uses `kcadm config credentials` to start an authenticated session.
[options="nowrap"] [options="nowrap",subs="attributes+"]
---- ----
$ kcadm.sh config credentials --server http://localhost:8080/auth --realm master --user admin --password admin $ kcadm.sh config credentials --server http://localhost:8080{kc_base_path} --realm master --user admin --password admin
---- ----
This mechanism maintains an authenticated session between the `kcadm` command invocations by saving the obtained access token and its associated refresh token. It can maintain other secrets in a private configuration file. See the <<_working_with_alternative_configurations, next chapter>> for more information. This mechanism maintains an authenticated session between the `kcadm` command invocations by saving the obtained access token and its associated refresh token. It can maintain other secrets in a private configuration file. See the <<_working_with_alternative_configurations, next chapter>> for more information.
@ -112,9 +112,9 @@ This mechanism maintains an authenticated session between the `kcadm` command in
The second mechanism authenticates each command invocation for the duration of the invocation. This mechanism increases the load on the server and the time spent on round trips obtaining tokens. The benefit of this approach is that it is unnecessary to save tokens between invocations, so nothing is saved to disk. {project_name} uses this mode when the `--no-config` argument is specified. The second mechanism authenticates each command invocation for the duration of the invocation. This mechanism increases the load on the server and the time spent on round trips obtaining tokens. The benefit of this approach is that it is unnecessary to save tokens between invocations, so nothing is saved to disk. {project_name} uses this mode when the `--no-config` argument is specified.
For example, when performing an operation, specify all the information required for authentication. For example, when performing an operation, specify all the information required for authentication.
[options="nowrap"] [options="nowrap",subs="attributes+"]
---- ----
$ kcadm.sh get realms --no-config --server http://localhost:8080/auth --realm master --user admin --password admin $ kcadm.sh get realms --no-config --server http://localhost:8080{kc_base_path} --realm master --user admin --password admin
---- ----
Run the `kcadm.sh help` command for more information on using the Admin CLI. Run the `kcadm.sh help` command for more information on using the Admin CLI.
@ -161,9 +161,9 @@ ENDPOINT is a target resource URI and can be absolute (starting with `http:` or
SERVER_URI/admin/realms/REALM/ENDPOINT SERVER_URI/admin/realms/REALM/ENDPOINT
---- ----
For example, if you authenticate against the server http://localhost:8080/auth and realm is `master`, using `users` as ENDPOINT creates the http://localhost:8080/auth/admin/realms/master/users resource URL. For example, if you authenticate against the server http://localhost:8080{kc_base_path} and realm is `master`, using `users` as ENDPOINT creates the http://localhost:8080{kc_admins_path}/realms/master/users resource URL.
If you set ENDPOINT to `clients`, the effective resource URI is http://localhost:8080/auth/admin/realms/master/clients. If you set ENDPOINT to `clients`, the effective resource URI is http://localhost:8080{kc_admins_path}/realms/master/clients.
{project_name} has a `realms` endpoint that is the container for realms. It resolves to: {project_name} has a `realms` endpoint that is the container for realms. It resolves to:
[options="nowrap"] [options="nowrap"]
@ -181,13 +181,13 @@ SERVER_URI/admin/realms/TARGET_REALM/ENDPOINT
---- ----
For example: For example:
[options="nowrap"] [options="nowrap",subs="attributes+"]
---- ----
$ kcadm.sh config credentials --server http://localhost:8080/auth --realm master --user admin --password admin $ kcadm.sh config credentials --server http://localhost:8080{kc_base_path} --realm master --user admin --password admin
$ kcadm.sh create users -s username=testuser -s enabled=true -r demorealm $ kcadm.sh create users -s username=testuser -s enabled=true -r demorealm
---- ----
In this example, you start a session authenticated as the `admin` user in the `master` realm. You then perform a POST call against the resource URL `http://localhost:8080/auth/admin/realms/demorealm/users`. In this example, you start a session authenticated as the `admin` user in the `master` realm. You then perform a POST call against the resource URL `http://localhost:8080{kc_admins_path}/realms/demorealm/users`.
The `create` and `update` commands send a JSON body to the server. You can use `-f FILENAME` to read a pre-made document from a file. When you can use the `-f -` option, {project_name} reads the message body from the standard input. You can specify individual attributes and their values, as seen in the `create users` example. {project_name} composes the attributes into a JSON body and sends them to the server. The `create` and `update` commands send a JSON body to the server. You can use `-f FILENAME` to read a pre-made document from a file. When you can use the `-f -` option, {project_name} reads the message body from the standard input. You can specify individual attributes and their values, as seen in the `create users` example. {project_name} composes the attributes into a JSON body and sends them to the server.
@ -946,9 +946,9 @@ Use the client ID to construct an endpoint URI that targets a specific client, s
The response is in `.zip` format. The response is in `.zip` format.
For example: For example:
[options="nowrap"] [options="nowrap",subs="attributes+"]
---- ----
$ kcadm.sh get http://localhost:8080/auth/admin/realms/demorealm/clients/8f271c35-44e3-446f-8953-b0893810ebe7/installation/providers/docker-v2-compose-yaml -r demorealm > keycloak-docker-compose-yaml.zip $ kcadm.sh get http://localhost:8080{kc_admins_path}/realms/demorealm/clients/8f271c35-44e3-446f-8953-b0893810ebe7/installation/providers/docker-v2-compose-yaml -r demorealm > keycloak-docker-compose-yaml.zip
---- ----
[discrete] [discrete]
@ -1468,9 +1468,9 @@ $ kcadm.sh delete identity-provider/instances/facebook -r demorealm
+ +
For example: For example:
+ +
[options="nowrap"] [options="nowrap",subs=+attributes]
---- ----
$ kcadm.sh create identity-provider/instances -r demorealm -s alias=keycloak-oidc -s providerId=keycloak-oidc -s enabled=true -s 'config.useJwksUrl="true"' -s config.authorizationUrl=http://localhost:8180/auth/realms/demorealm/protocol/openid-connect/auth -s config.tokenUrl=http://localhost:8180/auth/realms/demorealm/protocol/openid-connect/token -s config.clientId=demo-oidc-provider -s config.clientSecret=secret $ kcadm.sh create identity-provider/instances -r demorealm -s alias=keycloak-oidc -s providerId=keycloak-oidc -s enabled=true -s 'config.useJwksUrl="true"' -s config.authorizationUrl=http://localhost:8180{kc_realms_path}/demorealm/protocol/openid-connect/auth -s config.tokenUrl=http://localhost:8180{kc_realms_path}/demorealm/protocol/openid-connect/token -s config.clientId=demo-oidc-provider -s config.clientSecret=secret
---- ----
[discrete] [discrete]
@ -1485,9 +1485,9 @@ Configure the generic OpenID Connect provider the same way you configure the Key
. Provide the `config` attributes: `singleSignOnServiceUrl`, `nameIDPolicyFormat`, and `signatureAlgorithm`. . Provide the `config` attributes: `singleSignOnServiceUrl`, `nameIDPolicyFormat`, and `signatureAlgorithm`.
For example: For example:
[options="nowrap"] [options="nowrap",subs=+attributes]
---- ----
$ kcadm.sh create identity-provider/instances -r demorealm -s alias=saml -s providerId=saml -s enabled=true -s 'config.useJwksUrl="true"' -s config.singleSignOnServiceUrl=http://localhost:8180/auth/realms/saml-broker-realm/protocol/saml -s config.nameIDPolicyFormat=urn:oasis:names:tc:SAML:2.0:nameid-format:persistent -s config.signatureAlgorithm=RSA_SHA256 $ kcadm.sh create identity-provider/instances -r demorealm -s alias=saml -s providerId=saml -s enabled=true -s 'config.useJwksUrl="true"' -s config.singleSignOnServiceUrl=http://localhost:8180{kc_realms_path}/saml-broker-realm/protocol/saml -s config.nameIDPolicyFormat=urn:oasis:names:tc:SAML:2.0:nameid-format:persistent -s config.signatureAlgorithm=RSA_SHA256
---- ----
[discrete] [discrete]

View file

@ -4,6 +4,7 @@
:tech_feature_name: Fine Grain Admin Permissions :tech_feature_name: Fine Grain Admin Permissions
:tech_feature_setting: -Dkeycloak.profile.feature.admin_fine_grained_authz=enabled :tech_feature_setting: -Dkeycloak.profile.feature.admin_fine_grained_authz=enabled
:tech_feature_id: admin-fine-grained-authz
include::../templates/techpreview.adoc[] include::../templates/techpreview.adoc[]
Sometimes roles like `manage-realm` or `manage-users` are too coarse grain and you want to create Sometimes roles like `manage-realm` or `manage-users` are too coarse grain and you want to create
@ -101,7 +102,7 @@ IMPORTANT If you do not set the `query-clients` role, restricted admins like `sa
===== Testing it out ===== Testing it out
Next, we log out of the master realm and re-login to the <<_per_realm_admin_permissions, dedicated admin console>> for the `test` realm Next, we log out of the master realm and re-login to the <<_per_realm_admin_permissions, dedicated admin console>> for the `test` realm
using the `sales-admin` as a username. This is located under `/auth/admin/test/console`. using the `sales-admin` as a username. This is located under `{kc_admins_path}/test/console`.
.Sales admin login .Sales admin login
image:{project_images}/fine-grain-sales-admin-login.png[] image:{project_images}/fine-grain-sales-admin-login.png[]
@ -165,7 +166,7 @@ image:{project_images}/fine-grain-add-view-users.png[]
===== Testing it out ===== Testing it out
Next, we log out of the master realm and re-login to the <<_per_realm_admin_permissions, dedicated admin console>> for the `test` realm Next, we log out of the master realm and re-login to the <<_per_realm_admin_permissions, dedicated admin console>> for the `test` realm
using the `sales-admin` as a username. This is located under `/auth/admin/test/console`. using the `sales-admin` as a username. This is located under `{kc_admins_path}/test/console`.
You will see that now the `sales-admin` can view users in the system. If you select one of the You will see that now the `sales-admin` can view users in the system. If you select one of the
users you'll see that each user detail page is read only, except for the `Role Mappings` tab. users you'll see that each user detail page is read only, except for the `Role Mappings` tab.

View file

@ -2,7 +2,7 @@
=== Dedicated realm admin consoles === Dedicated realm admin consoles
Each realm has a dedicated Admin Console that can be accessed by going to the url `/auth/admin/{realm-name}/console`. Each realm has a dedicated Admin Console that can be accessed by going to the url `{kc_admins_path}/{realm-name}/console`.
Users within that realm can be granted realm management permissions by assigning specific user role mappings. Users within that realm can be granted realm management permissions by assigning specific user role mappings.
Each realm has a built-in client called `realm-management`. You can view this client by going to the Each realm has a built-in client called `realm-management`. You can view this client by going to the

View file

@ -324,9 +324,9 @@ image:images/authentication-step-up-flow.png[]
.Request a certain authentication level .Request a certain authentication level
To use the step-up mechanism, you have to specify a requested level of authentication (LoA) in your authentication request. The claims parameter is used for this purpose: To use the step-up mechanism, you have to specify a requested level of authentication (LoA) in your authentication request. The claims parameter is used for this purpose:
[source] [source,subs=+attributes]
---- ----
https://{DOMAIN}/auth/realms/{REALMNAME}/protocol/openid-connect/auth?client_id={CLIENT-ID}&redirect_uri={REDIRECT-URI}&scope=openid&response_type=code&response_mode=query&nonce=exg16fxdjcu&claims=%7B%22id_token%22%3A%7B%22acr%22%3A%7B%22essential%22%3Atrue%2C%22values%22%3A%5B%22gold%22%5D%7D%7D%7D https://{DOMAIN}{kc_realms_path}/{REALMNAME}/protocol/openid-connect/auth?client_id={CLIENT-ID}&redirect_uri={REDIRECT-URI}&scope=openid&response_type=code&response_mode=query&nonce=exg16fxdjcu&claims=%7B%22id_token%22%3A%7B%22acr%22%3A%7B%22essential%22%3Atrue%2C%22values%22%3A%5B%22gold%22%5D%7D%7D%7D
---- ----
The claims parameter is specified in a JSON representation: The claims parameter is specified in a JSON representation:

View file

@ -206,5 +206,5 @@ When using the Kerberos user storage provider, there cannot be conflicting users
If you have issues, enable additional logging to debug the problem: If you have issues, enable additional logging to debug the problem:
* Enable `Debug` flag in the Admin Console for Kerberos or LDAP federation providers * Enable `Debug` flag in the Admin Console for Kerberos or LDAP federation providers
* Enable TRACE logging for category `org.keycloak` in the logging section of `standalone/configuration/standalone.xml` to receive more information in `standalone/log/server.log` * Enable TRACE logging for category `org.keycloak` to receive more information in server logs
* Add system properties `-Dsun.security.krb5.debug=true` and `-Dsun.security.spnego.debug=true` * Add system properties `-Dsun.security.krb5.debug=true` and `-Dsun.security.spnego.debug=true`

View file

@ -7,6 +7,7 @@
ifeval::[{project_product}==true] ifeval::[{project_product}==true]
:tech_feature_name: WebAuthn :tech_feature_name: WebAuthn
:tech_feature_setting: -Dkeycloak.profile.feature.web_authn=enabled :tech_feature_setting: -Dkeycloak.profile.feature.web_authn=enabled
:tech_feature_id: web-authn
include::../templates/techpreview.adoc[] include::../templates/techpreview.adoc[]
endif::[] endif::[]

View file

@ -72,6 +72,7 @@ The certificate identity mapping can map the extracted user identity to an exist
* Certificate KeyUsage validation. * Certificate KeyUsage validation.
* Certificate ExtendedKeyUsage validation. * Certificate ExtendedKeyUsage validation.
ifeval::["{kc_dist}" == "wildfly"]
==== Enable X.509 client certificate user authentication ==== Enable X.509 client certificate user authentication
The following sections describe how to configure {appserver_name}/Undertow and the {project_name} Server to enable X.509 client certificate authentication. The following sections describe how to configure {appserver_name}/Undertow and the {project_name} Server to enable X.509 client certificate authentication.
@ -157,6 +158,7 @@ This value must match the name of the realm from the previous section.
`https-listener/verify-client`:: `https-listener/verify-client`::
If set to *REQUESTED*, the server optionally asks for a client certificate. If set to *REQUESTED*, the server optionally asks for a client certificate.
If set to *REQUIRED*, the server refuses inbound connections if no client certificate has been provided. If set to *REQUIRED*, the server refuses inbound connections if no client certificate has been provided.
endif::[]
[[_browser_flow]] [[_browser_flow]]
==== Adding X.509 client certificate authentication to browser flows ==== Adding X.509 client certificate authentication to browser flows
@ -378,6 +380,7 @@ All certificates in trusted-ca-list-for-client-auth.pem must be added to link:{i
{project_name} does not have built-in support for other reverse proxy implementations. However, you can make other reverse proxies behave in a similar way to `apache` or `haproxy`. If none of these work, create your implementation of the `org.keycloak.services.x509.X509ClientCertificateLookupFactory` and `org.keycloak.services.x509.X509ClientCertificateLookup` providers. See the link:{developerguide_link}[{developerguide_name}] for details on how to add your provider. {project_name} does not have built-in support for other reverse proxy implementations. However, you can make other reverse proxies behave in a similar way to `apache` or `haproxy`. If none of these work, create your implementation of the `org.keycloak.services.x509.X509ClientCertificateLookupFactory` and `org.keycloak.services.x509.X509ClientCertificateLookup` providers. See the link:{developerguide_link}[{developerguide_name}] for details on how to add your provider.
ifeval::["{kc_dist}" == "wildfly"]
==== Troubleshooting ==== Troubleshooting
Dumping HTTP headers:: Dumping HTTP headers::
@ -405,13 +408,13 @@ Do not use RequestDumpingHandler or TRACE logging in production.
Direct Grant authentication with X.509:: Direct Grant authentication with X.509::
You can use the following template to request a token by using the Resource Owner Password Credentials Grant: You can use the following template to request a token by using the Resource Owner Password Credentials Grant:
``` [source,subs=+attributes]
$ curl https://[host][:port]/auth/realms/master/protocol/openid-connect/token \ $ curl https://[host][:port]{kc_realms_path}/master/protocol/openid-connect/token \
--insecure \ --insecure \
--data "grant_type=password&scope=openid profile&username=&password=&client_id=CLIENT_ID&client_secret=CLIENT_SECRET" \ --data "grant_type=password&scope=openid profile&username=&password=&client_id=CLIENT_ID&client_secret=CLIENT_SECRET" \
-E /path/to/client_cert.crt \ -E /path/to/client_cert.crt \
--key /path/to/client_cert.key --key /path/to/client_cert.key
``` [source]
`[host][:port]`:: `[host][:port]`::
The host and the port number of the remote {project_name} server. The host and the port number of the remote {project_name} server.
@ -427,3 +430,4 @@ A public key certificate to verify the identity of the client in mutual SSL auth
`client_cert.key`:: `client_cert.key`::
A private key in the public key pair. This key must be in PEM format. A private key in the public key pair. This key must be in PEM format.
endif::[]

View file

@ -8,8 +8,8 @@ If a client accesses this endpoint using a `HTTP GET` request, {project_name} re
As an example, given the realm `master` and the client-id `account`: As an example, given the realm `master` and the client-id `account`:
[source] [source,subs=+attributes]
---- ----
http://host:port/auth/realms/master/clients/account/redirect http://host:port{kc_realms_path}/master/clients/account/redirect
---- ----
This URL temporarily redirects to: http://host:port/auth/realms/master/account This URL temporarily redirects to: http://host:port{kc_realms_path}/master/account

View file

@ -6,10 +6,12 @@ When you click _Advanced Settings_, additional fields are displayed.
[[_mtls-client-certificate-bound-tokens]] [[_mtls-client-certificate-bound-tokens]]
*OAuth 2.0 Mutual TLS Certificate Bound Access Tokens Enabled* *OAuth 2.0 Mutual TLS Certificate Bound Access Tokens Enabled*
ifeval::["{kc_dist}" == "wildfly"]
[NOTE] [NOTE]
==== ====
To enable mutual TLS in {project_name}, see <<_enable-mtls-wildfly, Enable mutual SSL in WildFly>>. To enable mutual TLS in {project_name}, see <<_enable-mtls-wildfly, Enable mutual SSL in WildFly>>.
==== ====
endif::[]
Mutual TLS binds an access token and a refresh token together with a client certificate, which is exchanged during a TLS handshake. This binding prevents an attacker from using stolen tokens. Mutual TLS binds an access token and a refresh token together with a client certificate, which is exchanged during a TLS handshake. This binding prevents an attacker from using stolen tokens.

View file

@ -69,7 +69,9 @@ The client secret will be used to sign the JWT by the client.
{project_name} will validate if the client uses proper X509 certificate during the TLS Handshake. {project_name} will validate if the client uses proper X509 certificate during the TLS Handshake.
ifeval::["{kc_dist}" == "wildfly"]
NOTE: This option requires mutual TLS in {project_name}. See <<_enable-mtls-wildfly, Enable mutual SSL in WildFly>>. NOTE: This option requires mutual TLS in {project_name}. See <<_enable-mtls-wildfly, Enable mutual SSL in WildFly>>.
endif::[]
.X509 certificate .X509 certificate
image:{project_images}/x509-client-auth.png[] image:{project_images}/x509-client-auth.png[]

View file

@ -25,7 +25,7 @@ Roles from access tokens are the intersection of:
* Role scope mappings of a client combined with the role scope mappings inherited from linked client scopes. * Role scope mappings of a client combined with the role scope mappings inherited from linked client scopes.
* Service account roles. * Service account roles.
The REST URL to invoke is `/auth/realms/{realm-name}/protocol/openid-connect/token`. This URL must be invoked as a POST request and requires that you post the client credentials with the request. The REST URL to invoke is `{kc_realms_path}/{realm-name}/protocol/openid-connect/token`. This URL must be invoked as a POST request and requires that you post the client credentials with the request.
By default, client credentials are represented by the clientId and clientSecret of the client in the *Authorization: Basic* header but you can also authenticate the client with a signed JWT assertion or any other custom mechanism for client authentication. By default, client credentials are represented by the clientId and clientSecret of the client in the *Authorization: Basic* header but you can also authenticate the client with a signed JWT assertion or any other custom mechanism for client authentication.
@ -33,10 +33,10 @@ You also need to set the *grant_type* parameter to "client_credentials" as per t
For example, the POST invocation to retrieve a service account can look like this: For example, the POST invocation to retrieve a service account can look like this:
[source] [source,subs=+attributes]
---- ----
POST /auth/realms/demo/protocol/openid-connect/token POST {kc_realms_path}/demo/protocol/openid-connect/token
Authorization: Basic cHJvZHVjdC1zYS1jbGllbnQ6cGFzc3dvcmQ= Authorization: Basic cHJvZHVjdC1zYS1jbGllbnQ6cGFzc3dvcmQ=
Content-Type: application/x-www-form-urlencoded Content-Type: application/x-www-form-urlencoded

View file

@ -16,7 +16,7 @@ have `Full Scope Allowed` on. As in a normal login, roles from access token are
* Role scope mappings of particular client combined with the role scope mappings inherited from linked client scopes * Role scope mappings of particular client combined with the role scope mappings inherited from linked client scopes
* Service account roles * Service account roles
The REST URL to invoke on is `/auth/realms/{realm-name}/protocol/openid-connect/token`. The REST URL to invoke on is `{kc_realms_path}/{realm-name}/protocol/openid-connect/token`.
Invoking on this URL is a POST request and requires you to post the client credentials. Invoking on this URL is a POST request and requires you to post the client credentials.
By default, client credentials are represented by clientId and clientSecret of the client in `Authorization: Basic` header, but you can also authenticate the client with a signed JWT assertion or any other custom mechanism for client authentication. By default, client credentials are represented by clientId and clientSecret of the client in `Authorization: Basic` header, but you can also authenticate the client with a signed JWT assertion or any other custom mechanism for client authentication.
You also need to use the parameter `grant_type=client_credentials` as per the OAuth2 specification. You also need to use the parameter `grant_type=client_credentials` as per the OAuth2 specification.
@ -26,7 +26,7 @@ For example the POST invocation to retrieve a service account can look like this
[source] [source]
---- ----
POST /auth/realms/demo/protocol/openid-connect/token POST {kc_realms_path}/demo/protocol/openid-connect/token
Authorization: Basic cHJvZHVjdC1zYS1jbGllbnQ6cGFzc3dvcmQ= Authorization: Basic cHJvZHVjdC1zYS1jbGllbnQ6cGFzc3dvcmQ=
Content-Type: application/x-www-form-urlencoded Content-Type: application/x-www-form-urlencoded

View file

@ -4,7 +4,7 @@
IDP Initiated Login is a feature that allows you to set up an endpoint on the {project_name} server that will log you into a specific application/client. IDP Initiated Login is a feature that allows you to set up an endpoint on the {project_name} server that will log you into a specific application/client.
In the *Settings* tab for your client, you need to specify the *IDP Initiated SSO URL Name*. In the *Settings* tab for your client, you need to specify the *IDP Initiated SSO URL Name*.
This is a simple string with no whitespace in it. This is a simple string with no whitespace in it.
After this you can reference your client at the following URL: `root/auth/realms/{realm}/protocol/saml/clients/{url-name}` After this you can reference your client at the following URL: `root{kc_realms_path}/{realm}/protocol/saml/clients/{url-name}`
The IDP initiated login implementation prefers _POST_ over _REDIRECT_ binding (check <<_saml, saml bindings>> for more information). The IDP initiated login implementation prefers _POST_ over _REDIRECT_ binding (check <<_saml, saml bindings>> for more information).
Therefore the final binding and SP URL are selected in the following way: Therefore the final binding and SP URL are selected in the following way:
@ -17,7 +17,7 @@ of the client settings) _POST_ binding is used through that URL.
If your client requires a special relay state, you can also configure this on the *Settings* tab in the *IDP Initiated SSO Relay State* field. If your client requires a special relay state, you can also configure this on the *Settings* tab in the *IDP Initiated SSO Relay State* field.
Alternatively, browsers can specify the relay state in a *RelayState* query parameter, i.e. Alternatively, browsers can specify the relay state in a *RelayState* query parameter, i.e.
`root/auth/realms/{realm}/protocol/saml/clients/{url-name}?RelayState=thestate`. `root{kc_realms_path}/{realm}/protocol/saml/clients/{url-name}?RelayState=thestate`.
When using <<_identity_broker,identity brokering>>, it is possible to set up an IDP Initiated Login for a client from an When using <<_identity_broker,identity brokering>>, it is possible to set up an IDP Initiated Login for a client from an
external IDP. The actual client is set up for IDP Initiated Login at broker IDP as described above. The external IDP has external IDP. The actual client is set up for IDP Initiated Login at broker IDP as described above. The external IDP has
@ -28,7 +28,7 @@ at the external IDP:
* *IDP Initiated SSO URL Name* is set to a name that will be published as IDP Initiated Login initial point, * *IDP Initiated SSO URL Name* is set to a name that will be published as IDP Initiated Login initial point,
* *Assertion Consumer Service POST Binding URL* in the *Fine Grain SAML Endpoint Configuration* section has * *Assertion Consumer Service POST Binding URL* in the *Fine Grain SAML Endpoint Configuration* section has
to be set to the following URL: to be set to the following URL:
`broker-root/auth/realms/{broker-realm}/broker/{idp-name}/endpoint/clients/{client-id}`, where: `broker-root{kc_realms_path}/{broker-realm}/broker/{idp-name}/endpoint/clients/{client-id}`, where:
** _broker-root_ is base broker URL ** _broker-root_ is base broker URL
** _broker-realm_ is name of the realm at broker where external IDP is declared ** _broker-realm_ is name of the realm at broker where external IDP is declared

View file

@ -18,6 +18,6 @@ Some SAML client adapters, such as _mod-auth-mellon_, need the XML Entity Descri
[source, subs="attributes"] [source, subs="attributes"]
---- ----
root/auth/realms/{realm}/protocol/saml/descriptor root{kc_realms_path}/{realm}/protocol/saml/descriptor
---- ----
where _realm_ is the realm of your client. where _realm_ is the realm of your client.

View file

@ -126,6 +126,21 @@ The Logging Event Listener logs events to the `org.keycloak.events` log category
To include debug log events in server logs: To include debug log events in server logs:
ifeval::["{kc_dist}" == "quarkus"]
. Change the log level for the `org.keycloak.events` category
. Change the log level used by the Logging Event listener.
To change the log level used by the Logging Event listener, add the following:
[source,bash]
----
bin/kc.[sh|bat] start --spi-events-listener-jboss-logging-success-level=info --spi-events-listener-jboss-logging-error-level=error
----
The valid values for log levels are `debug`, `info`, `warn`, `error`, and `fatal`.
endif::[]
ifeval::["{kc_dist}" == "wildfly"]
. Edit the `standalone.xml` file. . Edit the `standalone.xml` file.
. Change the log level used by the Logging Event listener. . Change the log level used by the Logging Event listener.
@ -161,6 +176,7 @@ To change the log level used by the Logging Event listener, add the following:
---- ----
The valid values for log levels are `debug`, `info`, `warn`, `error`, and `fatal`. The valid values for log levels are `debug`, `info`, `warn`, `error`, and `fatal`.
endif::[]
===== The Email Event Listener ===== The Email Event Listener
@ -180,6 +196,23 @@ To enable the Email Listener:
. Click the *Event Listeners* field. . Click the *Event Listeners* field.
. Select `email`. . Select `email`.
ifeval::["{kc_dist}" == "quarkus"]
You can exclude events by using the `--spi-events-listener-email-exclude-events` argument. For example:
[source,bash]
----
kc.[sh|bat] --spi-events-listener-email-exclude-events=UPDATE_TOTP,REMOVE_TOTP
----
You can set a maximum length of the Event detail in the database by using the `--spi-events-listener-email-exclude-events` argument. This setting is useful if a field (for example, redirect_uri) is long. For example:
[source,bash]
----
kc.[sh|bat] --spi-events-listener-email-max-detail-length=1000
----
endif::[]
ifeval::["{kc_dist}" == "wildfly"]
You can exclude events by editing the `standalone.xml`, `standalone-ha.xml`, or `domain.xml` configuration files included in your distribution. For example: You can exclude events by editing the `standalone.xml`, `standalone-ha.xml`, or `domain.xml` configuration files included in your distribution. For example:
[source,xml] [source,xml]
@ -207,3 +240,4 @@ You can set a maximum length of the Event detail in the database by editing the
---- ----
See the link:{installguide_link}[{installguide_name}] for more details on the location of the `standalone.xml`, `standalone-ha.xml`, or `domain.xml` files. See the link:{installguide_link}[{installguide_name}] for more details on the location of the `standalone.xml`, `standalone-ha.xml`, or `domain.xml` files.
endif::[]

View file

@ -67,7 +67,7 @@ If the user is unauthenticated in the IDP, the client still receives a `login_re
|This switch is applicable if `Validate Signatures` is *ON*. If *Use JWKS URL* is *ON*, {project_name} downloads the IDP's public keys from the JWKS URL. New keys download when the identity provider generates a new keypair. If *OFF*, {project_name} uses the public key (or certificate) from its database, so when the IDP keypair changes, import the new key to the {project_name} database as well. |This switch is applicable if `Validate Signatures` is *ON*. If *Use JWKS URL* is *ON*, {project_name} downloads the IDP's public keys from the JWKS URL. New keys download when the identity provider generates a new keypair. If *OFF*, {project_name} uses the public key (or certificate) from its database, so when the IDP keypair changes, import the new key to the {project_name} database as well.
|JWKS URL |JWKS URL
|The URL pointing to the location of the IDP JWK keys. For more information, see the https://self-issued.info/docs/draft-ietf-jose-json-web-key.html[JWK specification]. If you use an external {project_name} as an IDP, you can use a URL such as http://broker-keycloak:8180/auth/realms/test/protocol/openid-connect/certs if your brokered {project_name} is running on http://broker-keycloak:8180 and its realm is `test`. |The URL pointing to the location of the IDP JWK keys. For more information, see the https://self-issued.info/docs/draft-ietf-jose-json-web-key.html[JWK specification]. If you use an external {project_name} as an IDP, you can use a URL such as http://broker-keycloak:8180{kc_realms_path}/test/protocol/openid-connect/certs if your brokered {project_name} is running on http://broker-keycloak:8180 and its realm is `test`.
|Validating Public Key |Validating Public Key
|The public key in PEM format that {project_name} uses to verify external IDP signatures. This key applies if `Use JWKS URL` is *OFF*. |The public key in PEM format that {project_name} uses to verify external IDP signatures. This key applies if `Use JWKS URL` is *OFF*.
@ -77,4 +77,4 @@ If the user is unauthenticated in the IDP, the client still receives a `login_re
|=== |===
You can import all this configuration data by providing a URL or file that points to OpenID Provider Metadata. If you connect to a {project_name} external IDP, you can import the IDP settings from `<root>/auth/realms/{realm-name}/.well-known/openid-configuration`. This link is a JSON document describing metadata about the IDP. You can import all this configuration data by providing a URL or file that points to OpenID Provider Metadata. If you connect to a {project_name} external IDP, you can import the IDP settings from `<root>{kc_realms_path}/{realm-name}/.well-known/openid-configuration`. This link is a JSON document describing metadata about the IDP.

View file

@ -16,7 +16,7 @@ image:{project_images}/saml-add-identity-provider.png[Add Identity Provider]
|Configuration|Description |Configuration|Description
|Service Provider Entity ID |Service Provider Entity ID
|The SAML Entity ID that the remote Identity Provider uses to identify requests from this Service Provider. By default, this setting is set to the realms base URL `<root>/auth/realms/{realm-name}`. |The SAML Entity ID that the remote Identity Provider uses to identify requests from this Service Provider. By default, this setting is set to the realms base URL `<root>{kc_realms_path}/{realm-name}`.
|Single Sign-On Service URL |Single Sign-On Service URL
|The SAML endpoint that starts the authentication process. If your SAML IDP publishes an IDP entity descriptor, the value of this field is specified there. |The SAML endpoint that starts the authentication process. If your SAML IDP publishes an IDP entity descriptor, the value of this field is specified there.
@ -79,7 +79,7 @@ image:{project_images}/saml-add-identity-provider.png[Add Identity Provider]
|A descriptive name for the set of attributes that are advertised in the autogenerated SP metadata document. |A descriptive name for the set of attributes that are advertised in the autogenerated SP metadata document.
|=== |===
You can import all configuration data by providing a URL or a file pointing to the SAML IDP entity descriptor of the external IDP. If you are connecting to a {project_name} external IDP, you can import the IDP settings from the URL `<root>/auth/realms/{realm-name}/protocol/saml/descriptor`. This link is an XML document describing metadata about the IDP. You can also import all this configuration data by providing a URL or XML file pointing to the external SAML IDP's entity descriptor to connect to. You can import all configuration data by providing a URL or a file pointing to the SAML IDP entity descriptor of the external IDP. If you are connecting to a {project_name} external IDP, you can import the IDP settings from the URL `<root>{kc_realms_path}/{realm-name}/protocol/saml/descriptor`. This link is an XML document describing metadata about the IDP. You can also import all this configuration data by providing a URL or XML file pointing to the external SAML IDP's entity descriptor to connect to.
[[_identity_broker_saml_requested_authncontext]] [[_identity_broker_saml_requested_authncontext]]
==== Requesting specific AuthnContexts ==== Requesting specific AuthnContexts
@ -108,9 +108,9 @@ When you access the provider's SAML SP metadata, look for the `Endpoints` item i
This metadata is also available publicly by going to the following URL: This metadata is also available publicly by going to the following URL:
[source] [source,subs=+attributes]
---- ----
http[s]://{host:port}/auth/realms/{realm-name}/broker/{broker-alias}/endpoint/descriptor http[s]://{host:port}{kc_realms_path}/{realm-name}/broker/{broker-alias}/endpoint/descriptor
---- ----
Ensure you save any configuration changes before accessing the descriptor. Ensure you save any configuration changes before accessing the descriptor.
@ -120,9 +120,9 @@ Ensure you save any configuration changes before accessing the descriptor.
By default, a social button pointing to a SAML Identity Provider redirects the user to the following login URL: By default, a social button pointing to a SAML Identity Provider redirects the user to the following login URL:
[source] [source,subs=+attributes]
---- ----
http[s]://{host:port}/auth/realms/${realm-name}/broker/{broker-alias}/login http[s]://{host:port}{kc_realms_path}/${realm-name}/broker/{broker-alias}/login
---- ----
Adding a query parameter named `login_hint` to this URL adds the parameter's value to SAML request as a Subject attribute. If this query parameter is empty, {project_name} does not add a subject to the request. Adding a query parameter named `login_hint` to this URL adds the parameter's value to SAML request as a Subject attribute. If this query parameter is empty, {project_name} does not add a subject to the request.

View file

@ -7,7 +7,7 @@ Application code can retrieve these tokens and responses to import extra user in
[source,subs="attributes+"] [source,subs="attributes+"]
---- ----
GET /auth/realms/{realm}/broker/{provider_alias}/token HTTP/1.1 GET {kc_realms_path}/{realm}/broker/{provider_alias}/token HTTP/1.1
Host: localhost:8080 Host: localhost:8080
Authorization: Bearer <KEYCLOAK ACCESS TOKEN> Authorization: Bearer <KEYCLOAK ACCESS TOKEN>
---- ----

View file

@ -14,7 +14,7 @@ If your server is accessible from `localhost`, perform these steps.
.Procedure .Procedure
. In a web browser, go to the http://localhost:8080/auth URL. . In a web browser, go to the http://localhost:8080{kc_base_path} URL.
. Supply a username and password that you can recall. . Supply a username and password that you can recall.
+ +
@ -23,6 +23,20 @@ image:{project_images}/initial-welcome-page.png[Welcome Page]
=== Creating the account remotely === Creating the account remotely
ifeval::["{kc_dist}" == "quarkus"]
If you cannot access the server from a `localhost` address, or just want to start {project_name} from the command line, use the `KEYCLOAK_ADMIN` and `KEYCLOAK_ADMIN_PASSWORD` environment variables to create an initial admin account.
For example:
[source,bash]
----
export KEYCLOAK_ADMIN=<username>
export KEYCLOAK_ADMIN_PASSWORD=<password>
bin/kc.[sh|bat] start
----
endif::[]
ifeval::["{kc_dist}" == "wildfly"]
If you cannot access the server from a `localhost` address, or just want to start {project_name} from the command line, use the `.../bin/add-user-keycloak` script. If you cannot access the server from a `localhost` address, or just want to start {project_name} from the command line, use the `.../bin/add-user-keycloak` script.
.Add-user-keycloak script .Add-user-keycloak script
@ -55,8 +69,7 @@ $ .../bin/add-user-keycloak.sh --sc domain/servers/server-one/configuration -r m
---- ----
> ...\bin\add-user-keycloak.bat --sc domain/servers/server-one/configuration -r master -u <username> -p <password> > ...\bin\add-user-keycloak.bat --sc domain/servers/server-one/configuration -r master -u <username> -p <password>
---- ----
endif::[]

View file

@ -25,10 +25,4 @@ image:{project_images}/add-realm-menu.png[Add realm menu]
.Create realm .Create realm
image:{project_images}/create-realm.png[Create realm] image:{project_images}/create-realm.png[Create realm]
The current realm is now set to the realm you just created. You can switch between managing different realms by pointing to the top left corner to click *Select Realm*. The current realm is now set to the realm you just created. You can switch between managing different realms by pointing to the top left corner to click *Select Realm*.
ifdef::standalone[]
[role="_additional-resources"]
.Additional resources
* Alternatively you can import a JSON document that defines your new realm. For more detail, see the xref:assembly-exporting-importing_{context}[Export and Import] chapter.
endif::[]

View file

@ -10,7 +10,7 @@ You configure realms and perform most administrative tasks in the {project_name}
. Go the the URL for the Admin Console. . Go the the URL for the Admin Console.
+ +
For example, for localhost, use this URL: http://localhost:8080/auth/admin/ For example, for localhost, use this URL: http://localhost:8080{kc_admins_path}/
+ +
.Login page .Login page
image:{project_images}/login-page.png[Login page] image:{project_images}/login-page.png[Login page]

View file

@ -12,6 +12,14 @@ It can be achieved by setting `preloadOfflineSessionsFromDatabase` property in t
The following example shows how to configure offline sessions preloading. The following example shows how to configure offline sessions preloading.
ifeval::["{kc_dist}" == "quarkus"]
[source,bash]
----
bin/kc.[sh|bat] start --spi-user-sessions-infinispan-preload-offline-sessions-from-database=false
----
endif::[]
ifeval::["{kc_dist}" == "wildfly"]
[source,xml] [source,xml]
---- ----
<subsystem xmlns="urn:jboss:domain:keycloak-server:1.1"> <subsystem xmlns="urn:jboss:domain:keycloak-server:1.1">
@ -35,3 +43,4 @@ Equivalent configuration using CLI commands:
/subsystem=keycloak-server/spi=userSessions:add(default-provider=infinispan) /subsystem=keycloak-server/spi=userSessions:add(default-provider=infinispan)
/subsystem=keycloak-server/spi=userSessions/provider=infinispan:add(properties={preloadOfflineSessionsFromDatabase => "true"},enabled=true) /subsystem=keycloak-server/spi=userSessions/provider=infinispan:add(properties={preloadOfflineSessionsFromDatabase => "true"},enabled=true)
---- ----
endif::[]

View file

@ -131,13 +131,13 @@ The CIBA grant uses the following two providers.
{project_name} has both default providers. However, the administrator needs to set up Authentication Channel Provider like this: {project_name} has both default providers. However, the administrator needs to set up Authentication Channel Provider like this:
[source,xml] [source,xml,subs="attributes+"]
---- ----
<spi name="ciba-auth-channel"> <spi name="ciba-auth-channel">
<default-provider>ciba-http-auth-channel</default-provider> <default-provider>ciba-http-auth-channel</default-provider>
<provider name="ciba-http-auth-channel" enabled="true"> <provider name="ciba-http-auth-channel" enabled="true">
<properties> <properties>
<property name="httpAuthenticationChannelUri" value="https://backend.internal.example.com/auth"/> <property name="httpAuthenticationChannelUri" value="https://backend.internal.example.com{kc_base_path}"/>
</properties> </properties>
</provider> </provider>
</spi> </spi>
@ -235,8 +235,9 @@ Authentication Result Notification/ACK consists of the following messaging.
Authentication Result Notification:: The authentication entity sends the result of the authentication request to {project_name}. Authentication Result Notification:: The authentication entity sends the result of the authentication request to {project_name}.
[source,subs=+attributes]
---- ----
POST /auth/realms/[realm]/protocol/openid-connect/ext/ciba/auth/callback POST {kc_realms_path}/[realm]/protocol/openid-connect/ext/ciba/auth/callback
---- ----
* Headers * Headers

View file

@ -36,6 +36,6 @@ Enhanced Client or Proxy (ECP) is a SAML v.2.0 profile which allows the exchange
{project_name} has one endpoint for all SAML requests. {project_name} has one endpoint for all SAML requests.
`http(s)://authserver.host/auth/realms/{realm-name}/protocol/saml` `http(s)://authserver.host{kc_realms_path}/{realm-name}/protocol/saml`
All bindings use this endpoint. All bindings use this endpoint.

View file

@ -2,11 +2,11 @@
==== {project_name} server OIDC URI endpoints ==== {project_name} server OIDC URI endpoints
[role="_abstract"] [role="_abstract"]
The following is a list of OIDC endpoints that {project_name} publishes. These endpoints can be used when a non-{project_name} client adapter uses OIDC to communicate with the authentication server. They are all relative URLs. The root of the URL consists of the HTTP(S) protocol, hostname, and the path, which is usually prefixed with _/auth_: For example The following is a list of OIDC endpoints that {project_name} publishes. These endpoints can be used when a non-{project_name} client adapter uses OIDC to communicate with the authentication server. They are all relative URLs. The root of the URL consists of the HTTP(S) protocol, hostname, and optionally the path: For example
[source, subs="attributes"] [source, subs="attributes"]
---- ----
https://localhost:8080/auth https://localhost:8080{kc_base_path}
---- ----
/realms/{realm-name}/protocol/openid-connect/auth:: /realms/{realm-name}/protocol/openid-connect/auth::

View file

@ -27,4 +27,4 @@ NOTE: {project_name} does not create a browser SSO session after successful auth
{project_name} has one endpoint for all Docker auth v2 requests. {project_name} has one endpoint for all Docker auth v2 requests.
`http(s)://authserver.host/auth/realms/{realm-name}/protocol/docker-v2` `http(s)://authserver.host{kc_realms_path}/{realm-name}/protocol/docker-v2`

View file

@ -25,5 +25,5 @@ is still valid. So creating the session is unnecessary overhead for this protoco
{project_name} really only has one endpoint for all Docker auth v2 requests. {project_name} really only has one endpoint for all Docker auth v2 requests.
`http(s)://authserver.host/auth/realms/{realm-name}/protocol/docker-v2` `http(s)://authserver.host{kc_realms_path}/{realm-name}/protocol/docker-v2`

View file

@ -155,13 +155,13 @@ The CIBA grant uses the following two providers.
{project_name} has both default providers. However, the administrator needs to set up Authentication Channel Provider like this: {project_name} has both default providers. However, the administrator needs to set up Authentication Channel Provider like this:
[source,xml] [source,xml,subs="attributes+"]
---- ----
<spi name="ciba-auth-channel"> <spi name="ciba-auth-channel">
<default-provider>ciba-http-auth-channel</default-provider> <default-provider>ciba-http-auth-channel</default-provider>
<provider name="ciba-http-auth-channel" enabled="true"> <provider name="ciba-http-auth-channel" enabled="true">
<properties> <properties>
<property name="httpAuthenticationChannelUri" value="https://backend.internal.example.com/auth"/> <property name="httpAuthenticationChannelUri" value="https://backend.internal.example.com{kc_base_path}"/>
</properties> </properties>
</provider> </provider>
</spi> </spi>
@ -261,8 +261,9 @@ Authentication Result Notification/ACK consists of the following messaging.
Authentication Result Notification:: The authentication entity sends the result of the authentication request to {project_name}. Authentication Result Notification:: The authentication entity sends the result of the authentication request to {project_name}.
[source,subs=+attributes]
---- ----
POST /auth/realms/[realm]/protocol/openid-connect/ext/ciba/auth/callback POST {kc_realms_path}/[realm]/protocol/openid-connect/ext/ciba/auth/callback
---- ----
* Headers * Headers
@ -376,7 +377,7 @@ requests are sent to a registered backchannel logout URLs at {project_name} and
Here's a list of OIDC endpoints that the {project_name} publishes. These URLs are useful if you are using a non-{project_name} client adapter to Here's a list of OIDC endpoints that the {project_name} publishes. These URLs are useful if you are using a non-{project_name} client adapter to
talk OIDC with the auth server. These are all relative URLs and the root of the URL being the HTTP(S) protocol, hostname, and usually path prefixed with talk OIDC with the auth server. These are all relative URLs and the root of the URL being the HTTP(S) protocol, hostname, and usually path prefixed with
_/auth_, for example $$https://localhost:8080/auth$$. _/auth_, for example \https://localhost:8080{kc_base_path}.
You can also find these endpoints under "OpenID Endpoint Configuration" in your realm settings. You can also find these endpoints under "OpenID Endpoint Configuration" in your realm settings.

View file

@ -3,7 +3,7 @@
{project_name} exposes the administrative REST API and the web console on the same port as non-administrative usage by default. Do not expose administrative endpoints externally if external access is not necessary. If you need to expose administrative endpoints externally, you can expose them directly in {project_name} or use a proxy. {project_name} exposes the administrative REST API and the web console on the same port as non-administrative usage by default. Do not expose administrative endpoints externally if external access is not necessary. If you need to expose administrative endpoints externally, you can expose them directly in {project_name} or use a proxy.
To expose endpoints by using a proxy, consult the documentation for the proxy. You need to control access to requests to the `/auth/admin` endpoint. To expose endpoints by using a proxy, consult the documentation for the proxy. You need to control access to requests to the `{kc_admins_path}` endpoint.
Two options are available in {project_name} to expose endpoints directly, IP restriction and separate ports. Two options are available in {project_name} to expose endpoints directly, IP restriction and separate ports.
@ -11,7 +11,7 @@ When the Admin Console becomes inaccessible on the frontend URL of {project_name
==== IP restriction ==== IP restriction
You can restrict access to `/auth/admin` to only specific IP addresses. For example, restrict access to `/auth/admin` to IP addresses in the range `10.0.0.1` to `10.0.0.255`. You can restrict access to `{kc_admins_path}` to only specific IP addresses. For example, restrict access to `{kc_admins_path}` to IP addresses in the range `10.0.0.1` to `10.0.0.255`.
[source,xml,subs="attributes+"] [source,xml,subs="attributes+"]
---- ----
@ -25,7 +25,7 @@ You can restrict access to `/auth/admin` to only specific IP addresses. For exam
</host> </host>
</server> </server>
<filters> <filters>
<expression-filter name="ipAccess" expression="path-prefix('/auth/admin') -> ip-access-control(acl={'10.0.0.0/24 allow'})"/> <expression-filter name="ipAccess" expression="path-prefix('{kc_admins_path}') -> ip-access-control(acl={'10.0.0.0/24 allow'})"/>
</filters> </filters>
... ...
</subsystem> </subsystem>
@ -33,9 +33,9 @@ You can restrict access to `/auth/admin` to only specific IP addresses. For exam
You can also restrict access to specific IP addresses by using these CLI commands.: You can also restrict access to specific IP addresses by using these CLI commands.:
[source,bash] [source,bash,subs="attributes+"]
---- ----
/subsystem=undertow/configuration=filter/expression-filter=ipAccess:add(,expression="path-prefix[/auth/admin] -> ip-access-control(acl={'10.0.0.0/24 allow'})") /subsystem=undertow/configuration=filter/expression-filter=ipAccess:add(,expression="path-prefix[{kc_admins_path}] -> ip-access-control(acl={'10.0.0.0/24 allow'})")
/subsystem=undertow/server=default-server/host=default-host/filter-ref=ipAccess:add() /subsystem=undertow/server=default-server/host=default-host/filter-ref=ipAccess:add()
---- ----
@ -46,7 +46,7 @@ For IP restriction using a proxy, configure the proxy to ensure {project_name} r
==== Port restriction ==== Port restriction
You can expose `/auth/admin` to a different unexposed port. For example, expose `/auth/admin` on port `8444` and prevent access to the default port `8443`. You can expose `{kc_admins_path}` to a different unexposed port. For example, expose `{kc_admins_path}` on port `8444` and prevent access to the default port `8443`.
[source,xml,subs="attributes+"] [source,xml,subs="attributes+"]
---- ----
@ -62,7 +62,7 @@ You can expose `/auth/admin` to a different unexposed port. For example, expose
</host> </host>
</server> </server>
<filters> <filters>
<expression-filter name="portAccess" expression="path-prefix('/auth/admin') and not equals(%p, 8444) -> response-code(403)"/> <expression-filter name="portAccess" expression="path-prefix('{kc_admins_path}') and not equals(%p, 8444) -> response-code(403)"/>
</filters> </filters>
... ...
</subsystem> </subsystem>
@ -77,14 +77,14 @@ You can expose `/auth/admin` to a different unexposed port. For example, expose
</socket-binding-group> </socket-binding-group>
---- ----
You can expose `/auth/admin` on port `8444` and prevent access to the default port `8443` by using CLI commands: You can expose `{kc_admins_path}` on port `8444` and prevent access to the default port `8443` by using CLI commands:
[source,bash] [source,bash,subs="attributes+"]
---- ----
/socket-binding-group=standard-sockets/socket-binding=https-admin/:add(port=8444) /socket-binding-group=standard-sockets/socket-binding=https-admin/:add(port=8444)
/subsystem=undertow/server=default-server/https-listener=https-admin:add(socket-binding=https-admin, security-realm=ApplicationRealm, enable-http2=true) /subsystem=undertow/server=default-server/https-listener=https-admin:add(socket-binding=https-admin, security-realm=ApplicationRealm, enable-http2=true)
/subsystem=undertow/configuration=filter/expression-filter=portAccess:add(,expression="path-prefix('/auth/admin') and not equals(%p, 8444) -> response-code(403)") /subsystem=undertow/configuration=filter/expression-filter=portAccess:add(,expression="path-prefix('{kc_admins_path}') and not equals(%p, 8444) -> response-code(403)")
/subsystem=undertow/server=default-server/host=default-host/filter-ref=portAccess:add() /subsystem=undertow/server=default-server/host=default-host/filter-ref=portAccess:add()
---- ----

View file

@ -26,7 +26,14 @@ The maximum number of `AuthenticationSessionEntity` per `RootAuthenticationSessi
The following example shows how to limit the number of active `AuthenticationSessionEntity` per a `RootAuthenticationSessionEntity` to 100. The following example shows how to limit the number of active `AuthenticationSessionEntity` per a `RootAuthenticationSessionEntity` to 100.
ifeval::["{kc_dist}" == "quarkus"]
[source,bash]
----
bin/kc.[sh|bat] start --spi-authentication-sessions-infinispan-auth-sessions-limit=100
----
endif::[]
ifeval::["{kc_dist}" == "wildfly"]
[source,xml] [source,xml]
---- ----
<subsystem xmlns="urn:jboss:domain:keycloak-server:1.1"> <subsystem xmlns="urn:jboss:domain:keycloak-server:1.1">
@ -50,3 +57,4 @@ Equivalent configuration using CLI commands:
/subsystem=keycloak-server/spi=authenticationSessions:add(default-provider=infinispan) /subsystem=keycloak-server/spi=authenticationSessions:add(default-provider=infinispan)
/subsystem=keycloak-server/spi=authenticationSessions/provider=infinispan:add(properties={authSessionsLimit => "100"},enabled=true) /subsystem=keycloak-server/spi=authenticationSessions/provider=infinispan:add(properties={authSessionsLimit => "100"},enabled=true)
---- ----
endif::[]

View file

@ -28,6 +28,17 @@ This is the list of the read-only attributes, which are used internally by the {
* For administrators: `KERBEROS_PRINCIPAL`, `LDAP_ID`, `LDAP_ENTRY_DN`, `CREATED_TIMESTAMP`, `createTimestamp`, `modifyTimestamp` * For administrators: `KERBEROS_PRINCIPAL`, `LDAP_ID`, `LDAP_ENTRY_DN`, `CREATED_TIMESTAMP`, `createTimestamp`, `modifyTimestamp`
System administrators have a way to add additional attributes to this list. The configuration is currently available at the server level. System administrators have a way to add additional attributes to this list. The configuration is currently available at the server level.
ifeval::["{kc_dist}" == "quarkus"]
You can add this configuration by using the `spi-user-profile-legacy-user-profile-read-only-attributes` and ``spi-user-profile-legacy-user-profile-admin-read-only-attributes` options. For example:
[source,bash,options="nowrap"]
----
kc.[sh|bat] start --spi-user-profile-legacy-user-profile-read-only-attributes=foo,bar*
----
endif::[]
ifeval::["{kc_dist}" == "wildfly"]
You can add this configuration to your `standalone(-*).xml` files to the configuration of the {project_name} server subsystem: You can add this configuration to your `standalone(-*).xml` files to the configuration of the {project_name} server subsystem:
[options="nowrap"] [options="nowrap"]
@ -52,6 +63,7 @@ The same can be configured with the usage of the JBoss CLI with the commands:
/subsystem=keycloak-server/spi=userProfile/provider=legacy-user-profile/:map-put(name=properties,key=read-only-attributes,value=[foo,bar*]) /subsystem=keycloak-server/spi=userProfile/provider=legacy-user-profile/:map-put(name=properties,key=read-only-attributes,value=[foo,bar*])
/subsystem=keycloak-server/spi=userProfile/provider=legacy-user-profile/:map-put(name=properties,key=admin-read-only-attributes,value=[foo]) /subsystem=keycloak-server/spi=userProfile/provider=legacy-user-profile/:map-put(name=properties,key=admin-read-only-attributes,value=[foo])
---- ----
endif::[]
For this example, users and administrators would not be able to update attribute `foo`. Users would not be able to edit any attributes starting with the `bar`. For this example, users and administrators would not be able to update attribute `foo`. Users would not be able to edit any attributes starting with the `bar`.
So for example `bar` or `barrier`. Configuration is case insensitive, so attributes like `FOO` or `BarRier` will be denied as well for this example. The wildcard character `\*` is supported So for example `bar` or `barrier`. Configuration is case insensitive, so attributes like `FOO` or `BarRier` will be denied as well for this example. The wildcard character `\*` is supported

View file

@ -149,11 +149,8 @@ directory entry using `ldapsearch` and base64 decode the `userPassword` attribut
[[_ldap_troubleshooting]] [[_ldap_troubleshooting]]
==== Troubleshooting ==== Troubleshooting
- It is useful to increase the logging level to TRACE for the category `org.keycloak.storage.ldap`. You increase this level in the logging It is useful to increase the logging level to TRACE for the category `org.keycloak.storage.ldap`. With this setting, many logging messages are sent
to the server log in the `TRACE` level, including the logging for all queries to the LDAP server and the parameters, which were
It is useful to increase the logging level to TRACE for the category `org.keycloak.storage.ldap`. You increase this level in the logging
subsystem in the `standalone(-ha).xml` file. With this setting, many logging messages are sent
to the `server.log` file in the `TRACE` level, including the logging for all queries to the LDAP server and the parameters, which were
used to send the queries. When you are creating any LDAP question on user forum or JIRA, consider attaching the server log with used to send the queries. When you are creating any LDAP question on user forum or JIRA, consider attaching the server log with
enabled TRACE logging. If it is too big, the good alternative is to include just the snippet from server log with the messages, which were enabled TRACE logging. If it is too big, the good alternative is to include just the snippet from server log with the messages, which were
added to the log during the operation, which causes the issues to you. added to the log during the operation, which causes the issues to you.

View file

@ -36,6 +36,7 @@ In the future, the legacy behavior will no longer be supported in {project_name}
:tech_feature_name: Declarative User Profile :tech_feature_name: Declarative User Profile
:tech_feature_setting: -Dkeycloak.profile.feature.declarative_user_profile=enabled :tech_feature_setting: -Dkeycloak.profile.feature.declarative_user_profile=enabled
:tech_feature_id: declarative-user-profile
include::../templates/techpreview.adoc[] include::../templates/techpreview.adoc[]
In addition to enabling the `declarative_user_profile` feature, you should enable User Profile for a realm. To do that, click on the `Realm Settings` link on In addition to enabling the `declarative_user_profile` feature, you should enable User Profile for a realm. To do that, click on the `Realm Settings` link on

View file

@ -24,13 +24,16 @@ In the <<_ldap,LDAP settings>> of LDAP-based user federation.
OIDC identity provider secret:: OIDC identity provider secret::
In the _Client Secret_ inside identity provider <<_identity_broker_oidc,OpenID Connect Config>> In the _Client Secret_ inside identity provider <<_identity_broker_oidc,OpenID Connect Config>>
ifeval::["{kc_dist}" == "wildfly"]
To use a vault, register a vault provider in {project_name}. You can use the providers described <<_providers, here>> or implement your provider. See the link:{developerguide_link}[{developerguide_name}] for more information. To use a vault, register a vault provider in {project_name}. You can use the providers described <<_providers, here>> or implement your provider. See the link:{developerguide_link}[{developerguide_name}] for more information.
[NOTE] [NOTE]
==== ====
{project_name} permits a maximum of one active vault provider per {project_name} instance at a time. Configure the vault provider in each instance within the cluster consistently. {project_name} permits a maximum of one active vault provider per {project_name} instance at a time. Configure the vault provider in each instance within the cluster consistently.
==== ====
endif::[]
ifeval::["{kc_dist}" == "wildfly"]
[[_providers]] [[_providers]]
=== Kubernetes / OpenShift files plain-text vault provider === Kubernetes / OpenShift files plain-text vault provider
@ -116,11 +119,19 @@ For more information about creating and managing elytron credential stores and m
==== ====
{project_name} implements the `elytron-cs-keystore` vault provider as a WildFly extension and is available if the {project_name} server runs on WildFly/JBoss EAP only. {project_name} implements the `elytron-cs-keystore` vault provider as a WildFly extension and is available if the {project_name} server runs on WildFly/JBoss EAP only.
==== ====
endif::[]
=== Key resolvers === Key resolvers
All built-in providers support the configuration of key resolvers. A key resolver implements the algorithm or strategy for combining the realm name with the key, obtained from the `${vault.key}` expression, into the final entry name used to retrieve the secret from the vault. {project_name} uses the `keyResolvers` property to configure the resolvers that the provider uses. The value is a comma-separated list of resolver names. An example of the configuration for the `files-plaintext` provider follows: All built-in providers support the configuration of key resolvers. A key resolver implements the algorithm or strategy for combining the realm name with the key, obtained from the `${vault.key}` expression, into the final entry name used to retrieve the secret from the vault. {project_name} uses the `keyResolvers` property to configure the resolvers that the provider uses. The value is a comma-separated list of resolver names. An example of the configuration for the `files-plaintext` provider follows:
ifeval::["{kc_dist}" == "quarkus"]
[source,bash]
----
kc.[sh.bat] start --spi-vault-file-key-resolvers=REALM_UNDERSCORE_KEY,KEY_ONLY
----
endif::[]
ifeval::["{kc_dist}" == "wildfly"]
[source, xml] [source, xml]
---- ----
<spi name="vault"> <spi name="vault">
@ -133,6 +144,7 @@ All built-in providers support the configuration of key resolvers. A key resolve
</provider> </provider>
</spi> </spi>
---- ----
endif::[]
The resolvers run in the same order you declare them in the configuration. For each resolver, {project_name} uses the last entry name the resolver produces, which combines the realm with the vault key to search for the vault's secret. If {project_name} finds a secret, it returns the secret. If not, {project_name} uses the next resolver. This search continues until {project_name} finds a non-empty secret or runs out of resolvers. If {project_name} finds no secret, {project_name} returns an empty secret. The resolvers run in the same order you declare them in the configuration. For each resolver, {project_name} uses the last entry name the resolver produces, which combines the realm with the vault key to search for the vault's secret. If {project_name} finds a secret, it returns the secret. If not, {project_name} uses the next resolver. This search continues until {project_name} finds a non-empty secret or runs out of resolvers. If {project_name} finds no secret, {project_name} returns an empty secret.
@ -161,6 +173,7 @@ endif::[]
If you have not configured a resolver for the built-in providers, {project_name} selects the `REALM_UNDERSCORE_KEY`. If you have not configured a resolver for the built-in providers, {project_name} selects the `REALM_UNDERSCORE_KEY`.
ifeval::["{kc_dist}" == "wildfly"]
ifeval::[{project_community}==true] ifeval::[{project_community}==true]
The `FACTORY_PROVIDED` resolver provides a hook that you can use to implement a custom resolver by extending the provider factory of choice and overriding the `getFactoryResolver` method, so it returns the custom resolver. For example, if you want to use the `elytron-cs-keystore` provider but the built-in resolvers do not match the format used in your keystore, you can extend the `ElytronCSKeystoreProvider` and implement the `getFactoryResolver` method: The `FACTORY_PROVIDED` resolver provides a hook that you can use to implement a custom resolver by extending the provider factory of choice and overriding the `getFactoryResolver` method, so it returns the custom resolver. For example, if you want to use the `elytron-cs-keystore` provider but the built-in resolvers do not match the format used in your keystore, you can extend the `ElytronCSKeystoreProvider` and implement the `getFactoryResolver` method:
@ -208,7 +221,9 @@ To install and use the previous custom provider, the configuration would look si
This configuration makes {project_name} set up the custom Elytron provider and use the key resolver that the custom factory creates. This configuration makes {project_name} set up the custom Elytron provider and use the key resolver that the custom factory creates.
endif::[] endif::[]
endif::[]
ifeval::["{kc_dist}" == "wildfly"]
=== Sample Configuration === Sample Configuration
The following is an example of configuring a vault and credential store. The procedure involves two parts: The following is an example of configuring a vault and credential store. The procedure involves two parts:
@ -371,3 +386,4 @@ The vault and credential store are now masked:
.Additional resources .Additional resources
For more information about the Elytron tool, see link:https://access.redhat.com/documentation/en-us/red_hat_jboss_enterprise_application_platform/7.3/html/how_to_configure_server_security/securely_storing_credentials#cred_store_elytron_client[Using Credential Stores with Elytron Client]. For more information about the Elytron tool, see link:https://access.redhat.com/documentation/en-us/red_hat_jboss_enterprise_application_platform/7.3/html/how_to_configure_server_security/securely_storing_credentials#cred_store_elytron_client[Using Credential Stores with Elytron Client].
endif::[]

View file

@ -34,7 +34,7 @@ In addition, an action token can contain any number of custom fields serializabl
=== Action token processing === Action token processing
When an action token is passed to a {project_name} endpoint When an action token is passed to a {project_name} endpoint
`_KEYCLOAK_ROOT_/auth/realms/master/login-actions/action-token` via `key` parameter, it is validated and a proper action `_KEYCLOAK_ROOT_{kc_realms_path}/master/login-actions/action-token` via `key` parameter, it is validated and a proper action
token handler is executed. *The processing always takes place in a context of an authentication session*, either a fresh token handler is executed. *The processing always takes place in a context of an authentication session*, either a fresh
one or the action token service joins an existing authentication session (details are described below). The action token one or the action token service joins an existing authentication session (details are described below). The action token
handler can perform actions prescribed by the token (often it alters the authentication session) and results into an HTTP handler can perform actions prescribed by the token (often it alters the authentication session) and results into an HTTP

View file

@ -20,14 +20,14 @@ A token can be obtained by enabling authenticating to your application with {pro
. Obtain an access token for user in the realm `master` with username `admin` and password `password`: . Obtain an access token for user in the realm `master` with username `admin` and password `password`:
+ +
[source,bash] [source,bash,subs="attributes+"]
---- ----
curl \ curl \
-d "client_id=admin-cli" \ -d "client_id=admin-cli" \
-d "username=admin" \ -d "username=admin" \
-d "password=password" \ -d "password=password" \
-d "grant_type=password" \ -d "grant_type=password" \
"http://localhost:8080/auth/realms/master/protocol/openid-connect/token" "http://localhost:8080{kc_realms_path}/master/protocol/openid-connect/token"
---- ----
+ +
NOTE: By default this token expires in 1 minute NOTE: By default this token expires in 1 minute
@ -40,11 +40,11 @@ The result will be a JSON document.
+ +
The following example shows how to get the details of the master realm: The following example shows how to get the details of the master realm:
+ +
[source,bash] [source,bash,subs="attributes+"]
---- ----
curl \ curl \
-H "Authorization: bearer eyJhbGciOiJSUz..." \ -H "Authorization: bearer eyJhbGciOiJSUz..." \
"http://localhost:8080/auth/admin/realms/master" "http://localhost:8080{kc_admins_path}/realms/master"
---- ----
==== Authenticate with a service account ==== Authenticate with a service account
@ -60,13 +60,13 @@ Finally, check that `client_id` has the role 'admin' assigned in the "Service Ac
After that, you will be able to obtain an access token for the Admin REST API using `client_id` and `client_secret`: After that, you will be able to obtain an access token for the Admin REST API using `client_id` and `client_secret`:
[source,bash] [source,bash,subs="attributes+"]
---- ----
curl \ curl \
-d "client_id=<YOUR_CLIENT_ID>" \ -d "client_id=<YOUR_CLIENT_ID>" \
-d "client_secret=<YOUR_CLIENT_SECRET>" \ -d "client_secret=<YOUR_CLIENT_SECRET>" \
-d "grant_type=client_credentials" \ -d "grant_type=client_credentials" \
"http://localhost:8080/auth/realms/master/protocol/openid-connect/token" "http://localhost:8080{kc_realms_path}/master/protocol/openid-connect/token"
---- ----
ifeval::[{project_community}==true] ifeval::[{project_community}==true]
@ -77,7 +77,7 @@ There's a Java client library for the Admin REST API that makes it easy to use f
The following example shows how to use the Java client library to get the details of the master realm: The following example shows how to use the Java client library to get the details of the master realm:
[source,java] [source,java,subs="attributes+"]
---- ----
import org.keycloak.admin.client.Keycloak; import org.keycloak.admin.client.Keycloak;
@ -85,7 +85,7 @@ import org.keycloak.representations.idm.RealmRepresentation;
... ...
Keycloak keycloak = Keycloak.getInstance( Keycloak keycloak = Keycloak.getInstance(
"http://localhost:8080/auth", "http://localhost:8080{kc_base_path}",
"master", "master",
"admin", "admin",
"password", "password",

View file

@ -849,7 +849,13 @@ org.keycloak.examples.authenticator.SecretQuestionRequiredActionFactory
This services/ file is used by {project_name} to scan the providers it has to load into the system. This services/ file is used by {project_name} to scan the providers it has to load into the system.
To deploy this jar, just copy it to the `standalone/deployments` directory. ifeval::["{kc_dist}" == "quarkus"]
To deploy this jar, copy it to the `providers/` directory, then run `bin/kc.[sh|bat] build`.
endif::[]
ifeval::["{kc_dist}" == "wildfly"]
To deploy this jar, just copy it to the `standalone/deployments/` directory.
endif::[]
==== Implement the RequiredActionProvider ==== Implement the RequiredActionProvider
@ -1121,7 +1127,13 @@ org.keycloak.authentication.forms.RegistrationRecaptcha
This services/ file is used by {project_name} to scan the providers it has to load into the system. This services/ file is used by {project_name} to scan the providers it has to load into the system.
To deploy this jar, just copy it to the `standalone/deployments` directory. ifeval::["{kc_dist}" == "quarkus"]
To deploy this jar, copy it to the `providers/` directory, then run `bin/kc.[sh|bat] build`.
endif::[]
ifeval::["{kc_dist}" == "wildfly"]
To deploy this jar, just copy it to the `standalone/deployments/` directory.
endif::[]
==== Adding FormAction to the registration flow ==== Adding FormAction to the registration flow

View file

@ -20,9 +20,9 @@ There are some preconditions that must be met by the client application before i
To initiate the login, the application must fabricate a URL and redirect the user's browser to this URL. The URL looks like this: To initiate the login, the application must fabricate a URL and redirect the user's browser to this URL. The URL looks like this:
[source] [source,subs="attributes+"]
---- ----
/{auth-server-root}/auth/realms/{realm}/broker/{provider}/link?client_id={id}&redirect_uri={uri}&nonce={nonce}&hash={hash} /{auth-server-root}{kc_realms_path}/{realm}/broker/{provider}/link?client_id={id}&redirect_uri={uri}&nonce={nonce}&hash={hash}
---- ----
Here's a description of each path and query param: Here's a description of each path and query param:
@ -50,7 +50,7 @@ hash::
Here's an example of Java Servlet code that generates the URL to establish the account link. Here's an example of Java Servlet code that generates the URL to establish the account link.
[source,java] [source,java,subs="attributes+"]
---- ----
KeycloakSecurityContext session = (KeycloakSecurityContext) httpServletRequest.getAttribute(KeycloakSecurityContext.class.getName()); KeycloakSecurityContext session = (KeycloakSecurityContext) httpServletRequest.getAttribute(KeycloakSecurityContext.class.getName());
AccessToken token = session.getToken(); AccessToken token = session.getToken();
@ -68,7 +68,7 @@ Here's an example of Java Servlet code that generates the URL to establish the a
request.getSession().setAttribute("hash", hash); request.getSession().setAttribute("hash", hash);
String redirectUri = ...; String redirectUri = ...;
String accountLinkUrl = KeycloakUriBuilder.fromUri(authServerRootUrl) String accountLinkUrl = KeycloakUriBuilder.fromUri(authServerRootUrl)
.path("/auth/realms/{realm}/broker/{provider}/link") .path("{kc_realms_path}/{realm}/broker/{provider}/link")
.queryParam("nonce", nonce) .queryParam("nonce", nonce)
.queryParam("hash", hash) .queryParam("hash", hash)
.queryParam("client_id", clientId) .queryParam("client_id", clientId)

View file

@ -8,9 +8,9 @@ Application code can retrieve these tokens and responses to pull in extra user i
For example, an application might want to use the Google token to invoke on other Google services and REST APIs. For example, an application might want to use the Google token to invoke on other Google services and REST APIs.
To retrieve a token for a particular identity provider you need to send a request as follows: To retrieve a token for a particular identity provider you need to send a request as follows:
[source] [source,subs="attributes+"]
---- ----
GET /auth/realms/{realm}/broker/{provider_alias}/token HTTP/1.1 GET {kc_realms_path}/{realm}/broker/{provider_alias}/token HTTP/1.1
Host: localhost:8080 Host: localhost:8080
Authorization: Bearer <KEYCLOAK ACCESS TOKEN> Authorization: Bearer <KEYCLOAK ACCESS TOKEN>
---- ----

View file

@ -82,6 +82,18 @@ Example service configuration file (`META-INF/services/org.keycloak.theme.ThemeS
org.acme.provider.MyThemeSelectorProviderFactory org.acme.provider.MyThemeSelectorProviderFactory
---- ----
ifeval::["{kc_dist}" == "quarkus"]
You can configure your provider through server configuring.
For example by adding starting the server with the following arguments:
[source,bash]
----
bin/kc.[sh|bat] --spi-theme-selector-my-theme-selector-enabled=true --spi-theme-selector-my-theme-selector-theme=my-theme
----
endif::[]
ifeval::["{kc_dist}" == "wildfly"]
You can configure your provider through `standalone.xml`, `standalone-ha.xml`, or `domain.xml`. You can configure your provider through `standalone.xml`, `standalone-ha.xml`, or `domain.xml`.
For example by adding the following to `standalone.xml`: For example by adding the following to `standalone.xml`:
@ -96,6 +108,7 @@ For example by adding the following to `standalone.xml`:
</provider> </provider>
</spi> </spi>
---- ----
endif::[]
Then you can retrieve the config in the `ProviderFactory` init method: Then you can retrieve the config in the `ProviderFactory` init method:
@ -165,7 +178,18 @@ usage of the `KeycloakSession`, which is available to your provider as described
* *Single-implementation provider types* - There can be only a single active implementation of the particular provider type in {project_name} runtime. * *Single-implementation provider types* - There can be only a single active implementation of the particular provider type in {project_name} runtime.
For example `HostnameProvider` specifies the hostname to be used by {project_name} and that is shared for the whole {project_name} server. For example `HostnameProvider` specifies the hostname to be used by {project_name} and that is shared for the whole {project_name} server.
Hence there can be only single implementation of this provider active for the {project_name} server. If there are multiple provider implementations available to the server runtime, Hence there can be only single implementation of this provider active for the {project_name} server. If there are multiple provider implementations available to the server runtime,
one of them needs to be specified in the keycloak subsystem configuration in the `standalone.xml` as the default one. For example such as: one of them needs to be specified as the default one.
ifeval::["{kc_dist}" == "quarkus"]
For example such as:
[source,bash]
----
bin/kc.[sh|bat] build --spi-hostname-provider=default
----
endif::[]
ifeval::["{kc_dist}" == "wildfly"]
For example such as:
[source,xml] [source,xml]
---- ----
<spi name="hostname"> <spi name="hostname">
@ -173,6 +197,8 @@ one of them needs to be specified in the keycloak subsystem configuration in the
... ...
</spi> </spi>
---- ----
endif::[]
The value `default` used as the value of `default-provider` must match the ID returned by the `ProviderFactory.getId()` of the particular provider factory implementation. The value `default` used as the value of `default-provider` must match the ID returned by the `ProviderFactory.getId()` of the particular provider factory implementation.
In the code, you can obtain the provider such as `keycloakSession.getProvider(HostnameProvider.class)` In the code, you can obtain the provider such as `keycloakSession.getProvider(HostnameProvider.class)`
@ -184,7 +210,27 @@ as there can be multiple instances of this provider type as described above. The
particular provider factory implementation. Some provider types can be retrieved with the usage of `ComponentModel` as the second argument and some (for example `Authenticator`) even particular provider factory implementation. Some provider types can be retrieved with the usage of `ComponentModel` as the second argument and some (for example `Authenticator`) even
need to be retrieved with the usage of `KeycloakSessionFactory`. It is not recommended to implement your own providers this way as it may be deprecated in the future. need to be retrieved with the usage of `KeycloakSessionFactory`. It is not recommended to implement your own providers this way as it may be deprecated in the future.
ifeval::["{kc_dist}" == "quarkus"]
=== Registering provider implementations
Providers are registered with the server by simply copying them to the `providers` directory.
If your provider needs additional dependencies not already provided by Keycloak copy these to the `providers` directory.
After registering new providers or dependencies Keycloak needs to be re-built with the `kc.[sh|bat] build` command.
==== Disabling a provider
You can disable a provider by setting the enabled attribute for the provider to false.
For example to disable the Infinispan user cache provider use:
[source,bash]
----
bin/kc.[sh|bat] build --spi-user-cache-infinispan-enabled=false
----
endif::[]
ifeval::["{kc_dist}" == "wildfly"]
=== Registering provider implementations === Registering provider implementations
There are two ways to register provider implementations. In most cases the simplest way is to use the {project_name} deployer There are two ways to register provider implementations. In most cases the simplest way is to use the {project_name} deployer
@ -335,6 +381,7 @@ public class EjbExampleUserStorageProviderFactory
} }
} }
---- ----
endif::[]
[[_script_providers]] [[_script_providers]]
=== JavaScript providers === JavaScript providers
@ -466,7 +513,13 @@ The name of the script file. This property is *mandatory* and should map to a fi
==== Deploy the script JAR ==== Deploy the script JAR
ifeval::["{kc_dist}" == "quarkus"]
Once you have a JAR file with a descriptor and the scripts you want to deploy, you just need to copy the JAR to the {project_name} `providers/` directory, then run `bin/kc.[sh|bat] build`.
endif::[]
ifeval::["{kc_dist}" == "wildfly"]
Once you have a JAR file with a descriptor and the scripts you want to deploy, you just need to copy the JAR to the {project_name} `standalone/deployments/` directory. Once you have a JAR file with a descriptor and the scripts you want to deploy, you just need to copy the JAR to the {project_name} `standalone/deployments/` directory.
endif::[]
==== Using the {project_name} Admin Console to upload scripts ==== Using the {project_name} Admin Console to upload scripts

View file

@ -8,7 +8,7 @@ An example use-case would be a <<_auth_spi,custom authenticator>> that requires
endif::[] endif::[]
The easiest way to load additional theme resources is to create a JAR with templates in `theme-resources/templates` The easiest way to load additional theme resources is to create a JAR with templates in `theme-resources/templates`
resources in `theme-resources/resources` and messages bundles in `theme-resources/messages` and drop it into the `standalone/deployments/` directory of {project_name}. resources in `theme-resources/resources` and messages bundles in `theme-resources/messages`.
If you want a more flexible way to load templates and resources that can be achieved through the ThemeResourceSPI. If you want a more flexible way to load templates and resources that can be achieved through the ThemeResourceSPI.
By implementing `ThemeResourceProviderFactory` and `ThemeResourceProvider` you can decide exactly how to load templates By implementing `ThemeResourceProviderFactory` and `ThemeResourceProvider` you can decide exactly how to load templates

View file

@ -31,6 +31,18 @@ NOTE: To set the theme for the `master` Admin Console you need to set the Admin
+ +
. To see the changes to the Admin Console refresh the page. . To see the changes to the Admin Console refresh the page.
ifeval::["{kc_dist}" == "quarkus"]
. Change the welcome theme by using the `spi-theme-welcome-theme` option.
. For example:
+
[source,bash]
----
bin/kc.[sh|bat] start --spi-theme-welcome-theme=custom-theme
----
endif::[]
ifeval::["{kc_dist}" == "wildfly"]
. Change the welcome theme by editing `standalone.xml`, `standalone-ha.xml`, or `domain.xml`. . Change the welcome theme by editing `standalone.xml`, `standalone-ha.xml`, or `domain.xml`.
. Add `welcomeTheme` to the theme element, for example: . Add `welcomeTheme` to the theme element, for example:
@ -44,6 +56,7 @@ NOTE: To set the theme for the `master` Admin Console you need to set the Admin
</theme> </theme>
---- ----
. Restart the server for the changes to the welcome theme to take effect. . Restart the server for the changes to the welcome theme to take effect.
endif::[]
=== Default themes === Default themes
@ -73,6 +86,16 @@ restarting {project_name}.
.Procedure .Procedure
ifeval::["{kc_dist}" == "quarkus"]
. Run Keycloak with the following options:
[source,bash]
----
bin/kc.[sh|bat] start --spi-theme-static-max-age=-1 --spi-theme-cache-themes=false --spi-theme-cache-templates=false
----
endif::[]
ifeval::["{kc_dist}" == "wildfly"]
. Edit `standalone.xml`. . Edit `standalone.xml`.
. For `theme` set `staticMaxAge` to `-1` and both . For `theme` set `staticMaxAge` to `-1` and both
@ -87,6 +110,7 @@ restarting {project_name}.
... ...
</theme> </theme>
---- ----
endif::[]
. Create a directory in the `themes` directory. . Create a directory in the `themes` directory.
+ +
@ -416,5 +440,12 @@ The contents of `META-INF/keycloak-themes.json` in this case would be:
+ +
A single archive can contain multiple themes and each theme can support one or more types. A single archive can contain multiple themes and each theme can support one or more types.
. To deploy the archive to {project_name}, add it to the `standalone/deployments/` directory of ifeval::["{kc_dist}" == "quarkus"]
To deploy the archive to {project_name}, add it to the `providers/` directory of
{project_name} and restart the server if it is already running.
endif::[]
ifeval::["{kc_dist}" == "wildfly"]
To deploy the archive to {project_name}, add it to the `standalone/deployments/` directory of
{project_name} and it will be automatically loaded. {project_name} and it will be automatically loaded.
endif::[]

View file

@ -83,7 +83,7 @@ So, knowing this there are different approaches you can take.
. You can remove the earlier provider in your earlier {project_name} deployment. This will remove the local linked copies . You can remove the earlier provider in your earlier {project_name} deployment. This will remove the local linked copies
of all users you imported. Then, when you upgrade {project_name}, just deploy and configure your new provider for your realm. of all users you imported. Then, when you upgrade {project_name}, just deploy and configure your new provider for your realm.
. The second option is to write your new provider making sure it has the same provider ID: `UserStorageProviderFactory.getId()`. . The second option is to write your new provider making sure it has the same provider ID: `UserStorageProviderFactory.getId()`.
Make sure this provider is in the `standalone/deployments/` directory of the new {project_name} installation. Boot the server, and have Make sure this provider is deployed to the server. Boot the server, and have
the built-in migration script convert from the earlier data model to the later data model. In this case all your earlier linked imported the built-in migration script convert from the earlier data model to the later data model. In this case all your earlier linked imported
users will work and be the same. users will work and be the same.

View file

@ -1,8 +1,6 @@
=== Packaging and deployment === Packaging and deployment
User Storage providers are packaged in a JAR and deployed or undeployed to the {project_name} runtime in the same way you would deploy something in the {appserver_name} application server. You can either copy the JAR directly to the `standalone/deployments/` directory of the server, or use the JBoss CLI to execute the deployment.
In order for {project_name} to recognize the provider, you need to add a file to the JAR: `META-INF/services/org.keycloak.storage.UserStorageProviderFactory`. This file must contain a line-separated list of fully qualified classnames of the `UserStorageProviderFactory` implementations: In order for {project_name} to recognize the provider, you need to add a file to the JAR: `META-INF/services/org.keycloak.storage.UserStorageProviderFactory`. This file must contain a line-separated list of fully qualified classnames of the `UserStorageProviderFactory` implementations:
---- ----
@ -10,5 +8,10 @@ org.keycloak.examples.federation.properties.ClasspathPropertiesStorageFactory
org.keycloak.examples.federation.properties.FilePropertiesStorageFactory org.keycloak.examples.federation.properties.FilePropertiesStorageFactory
---- ----
{project_name} supports hot deployment of these provider JARs. You'll also see later in this chapter that you can package it within and as Jakarta EE components. ifeval::["{kc_dist}" == "quarkus"]
To deploy this jar, copy it to the `providers/` directory, then run `bin/kc.[sh|bat] build`.
endif::[]
ifeval::["{kc_dist}" == "wildfly"]
To deploy this jar, just copy it to the `standalone/deployments/` directory.
endif::[]

View file

@ -58,14 +58,14 @@ public interface ComponentResource {
To create a user storage provider, you must specify the provider id, a provider type of the string `org.keycloak.storage.UserStorageProvider`, To create a user storage provider, you must specify the provider id, a provider type of the string `org.keycloak.storage.UserStorageProvider`,
as well as the configuration. as well as the configuration.
[source,java] [source,java,subs="attributes+"]
---- ----
import org.keycloak.admin.client.Keycloak; import org.keycloak.admin.client.Keycloak;
import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.RealmRepresentation;
... ...
Keycloak keycloak = Keycloak.getInstance( Keycloak keycloak = Keycloak.getInstance(
"http://localhost:8080/auth", "http://localhost:8080{kc_base_path}",
"master", "master",
"admin", "admin",
"password", "password",

View file

@ -207,8 +207,18 @@ The `UserStorageProviderFactory` interface has an optional `init()` method you c
In our `init()` method implementation, we find the property file containing our user declarations from the classpath. We then load the `properties` field with the username and password combinations stored there. In our `init()` method implementation, we find the property file containing our user declarations from the classpath. We then load the `properties` field with the username and password combinations stored there.
The `Config.Scope` parameter is factory configuration that can be set up within `standalone.xml`, `standalone-ha.xml`, or `domain.xml`. The `Config.Scope` parameter is factory configuration that configured through server configuration.
ifeval::["{kc_dist}" == "quarkus"]
For example, by running the server with the following argument:
[source,bash]
----
kc.[sh|bat] start --spi-storage-readonly-property-file-path=/other-users.properties
----
endif::[]
ifeval::["{kc_dist}" == "wildfly"]
For example, by adding the following to `standalone.xml`: For example, by adding the following to `standalone.xml`:
[source,xml] [source,xml]
@ -221,6 +231,7 @@ For example, by adding the following to `standalone.xml`:
</provider> </provider>
</spi> </spi>
---- ----
endif::[]
We can specify the classpath of the user property file instead of hardcoding it. Then you can retrieve the configuration in the `PropertyFileUserStorageProviderFactory.init()`: We can specify the classpath of the user property file instead of hardcoding it. Then you can retrieve the configuration in the `PropertyFileUserStorageProviderFactory.init()`:
@ -256,7 +267,13 @@ The class files for our provider implementation should be placed in a jar. You
org.keycloak.examples.federation.properties.FilePropertiesStorageFactory org.keycloak.examples.federation.properties.FilePropertiesStorageFactory
---- ----
Once you create the jar you can deploy it using regular {appserver_name} means: copy the jar into the `standalone/deployments/` directory or using the JBoss CLI. ifeval::["{kc_dist}" == "quarkus"]
To deploy this jar, copy it to the `providers/` directory, then run `bin/kc.[sh|bat] build`.
endif::[]
ifeval::["{kc_dist}" == "wildfly"]
To deploy this jar, just copy it to the `standalone/deployments/` directory.
endif::[]
==== Enabling the provider in the Admin Console ==== Enabling the provider in the Admin Console

View file

@ -31,6 +31,12 @@ endif::[]
:create_cmd: kubectl apply :create_cmd: kubectl apply
:create_cmd_brief: kubectl :create_cmd_brief: kubectl
:kc_dist: quarkus
:kc_realms_path: /realms
:kc_admins_path: /admin
:kc_js_path: /js
:kc_base_path:
:quickstartRepo_link: https://github.com/keycloak/keycloak-quickstarts :quickstartRepo_link: https://github.com/keycloak/keycloak-quickstarts
:quickstartRepo_name: Keycloak Quickstarts Repository :quickstartRepo_name: Keycloak Quickstarts Repository
:quickstartRepo_dir: keycloak-quickstarts :quickstartRepo_dir: keycloak-quickstarts

View file

@ -29,6 +29,12 @@
:create_cmd: oc create :create_cmd: oc create
:create_cmd_brief: oc :create_cmd_brief: oc
:kc_dist: wildfly
:kc_realms_path: /auth/realms
:kc_admins_path: /auth/admin
:kc_js_path: /auth/js
:kc_base_path: /auth
:project_dirref: RHSSO_HOME :project_dirref: RHSSO_HOME
:quickstartRepo_name: {project_name} Quickstarts Repository :quickstartRepo_name: {project_name} Quickstarts Repository

View file

@ -3,11 +3,20 @@ ifeval::[{tech_feature_disabled}!=false]
==== ====
{tech_feature_name} is *Technology Preview* and is not fully supported. This feature is disabled by default. {tech_feature_name} is *Technology Preview* and is not fully supported. This feature is disabled by default.
ifeval::["{kc_dist}" == "quarkus"]
To enable start the server with `--features=preview`
ifdef::tech_feature_setting[]
or `--features={tech_feature_id}`
endif::[]
endif::[]
ifeval::["{kc_dist}" == "wildfly"]
To enable start the server with `-Dkeycloak.profile=preview` To enable start the server with `-Dkeycloak.profile=preview`
ifdef::tech_feature_setting[] ifdef::tech_feature_setting[]
or `{tech_feature_setting}` or `{tech_feature_setting}`
endif::[] endif::[]
. For more details see link:{installguide_profile_link}[{installguide_profile_name}]. . For more details see link:{installguide_profile_link}[{installguide_profile_name}].
endif::[]
==== ====
endif::[] endif::[]
ifeval::[{tech_feature_disabled}==false] ifeval::[{tech_feature_disabled}==false]

View file

@ -0,0 +1,15 @@
[[_install_new_version]]
== Upgrading the {project_name} server
It is important that you upgrade {project_name} server before upgrading the adapters.
.Prerequisites
* Handle any open transactions and delete the data/tx-object-store/ transaction directory.
.Procedure
. Download the new server archive
. Move the downloaded archive to the desired location.
. Extract the archive. This step installs a clean instance of the latest {project_name} release.
. Copy `conf/`, `providers/` and `themes/` from the previous installation to the new installation.
. Re-build the server with `bin/kc.[sh|bat] build` unless you are using auto-build

View file

@ -4,9 +4,21 @@
include::../prep_migration.adoc[leveloffset=1] include::../prep_migration.adoc[leveloffset=1]
include::../install_new_version.adoc[leveloffset=1] ifeval::["{kc_dist}" == "quarkus"]
include::../install_new_version-quarkus.adoc[leveloffset=1]
endif::[]
ifeval::["{kc_dist}" == "wildfly"]
include::../install_new_version.adoc[leveloffset=1]
endif::[]
ifeval::["{kc_dist}" == "quarkus"]
include::../migrate_db-quarkus.adoc[leveloffset=1]
endif::[]
ifeval::["{kc_dist}" == "wildfly"]
include::../migrate_db.adoc[leveloffset=1] include::../migrate_db.adoc[leveloffset=1]
endif::[]
include::../migrate_themes.adoc[leveloffset=1] include::../migrate_themes.adoc[leveloffset=1]

View file

@ -0,0 +1,49 @@
[[_migrate_db]]
== Database migration
{project_name} can automatically migrate the database schema, or you can choose to do it manually. By default the
database is automatically migrated when you start the new installation for the first time.
=== Automatic relational database migration
To enable automatic upgrading of the database schema, set the migration-strategy property value to "update" for the
default connections-jpa provider:
[source,bash]
----
kc.[sh|bat] start --spi-connections-jpa-default-migration-strategy=update
----
When you start the server with this setting your database is automatically migrated if the database schema has changed
in the new version.
Creating an index on huge tables with millions of records can easily take a huge amount of time
and potentially cause major service disruption on upgrades.
For those cases, we added a threshold (the number of records) for automated index creation.
By default, this threshold is `300000` records.
When the number of records is higher than the threshold, the index is not created automatically,
and there will be a warning message in server logs including SQL commands which can be applied later manually.
To change the threshold, set the `index-creation-threshold` property, value for the default `connections-liquibase` provider:
[source,bash]
----
kc.[sh|bat] start --spi-connections-liquibase-default-index-creation-threshold=300000
----
=== Manual relational database migration
To enable manual upgrading of the database schema, set the migration-strategy property value to "manual" for the default
connections-jpa provider:
[source,bash]
----
kc.[sh|bat] start --spi-connections-jpa-default-migration-strategy=manual
----
When you start the server with this configuration it checks if the database needs to be migrated. The required changes
are written to an SQL file that you can review and manually run against the database. For further details on how to
apply this file to the database, see the documentation for the relational database you're using. After the changes have
been written to the file, the server exits.