Remove adapters from product documentation (#21177)
Closes #21176 Co-authored-by: andymunro <48995441+andymunro@users.noreply.github.com> Co-authored-by: Stian Thorgersen <stianst@gmail.com>
This commit is contained in:
parent
2bd7de6e8a
commit
702495fe22
43 changed files with 688 additions and 1100 deletions
|
@ -6,16 +6,6 @@ include::topics/auth-services-terminology.adoc[leveloffset=+2]
|
|||
|
||||
include::topics/getting-started-overview.adoc[leveloffset=+1]
|
||||
|
||||
include::topics/hello-world-overview.adoc[leveloffset=+2]
|
||||
|
||||
include::topics/hello-world-create-realm.adoc[leveloffset=+2]
|
||||
|
||||
include::topics/hello-world-create-resource-server.adoc[leveloffset=+2]
|
||||
|
||||
include::topics/hello-world-deploy.adoc[leveloffset=+2]
|
||||
|
||||
include::topics/authorization-quickstarts.adoc[leveloffset=+2]
|
||||
|
||||
include::topics/resource-server-overview.adoc[leveloffset=+1]
|
||||
|
||||
include::topics/resource-server-create-client.adoc[leveloffset=+2]
|
||||
|
@ -110,7 +100,7 @@ include::topics/service-client-api.adoc[leveloffset=+2]
|
|||
|
||||
include::topics/enforcer-overview.adoc[leveloffset=+1]
|
||||
|
||||
include::topics/enforcer-keycloak-enforcement-filter.adoc[leveloffset=+2]
|
||||
include::topics/enforcer-configuration.adoc[leveloffset=+2]
|
||||
|
||||
include::topics/enforcer-claim-information-point.adoc[leveloffset=+2]
|
||||
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
[[_authorization_quickstarts]]
|
||||
= Authorization quickstarts
|
||||
|
||||
In addition to the *app-authz-jee-vanilla* quickstart that was used as a sample application in the previous section, the
|
||||
link:{quickstartRepo_link}[{quickstartRepo_name}] contains other applications that make use of the authorization services
|
||||
described in this documentation.
|
||||
|
||||
The authorization quickstarts have been designed so that authorization services are displayed in different scenarios and
|
||||
using different technologies and integrations. It is not meant as a comprehensive set of all the possible use cases involving
|
||||
authorization but they should provide a starting point for users interested in understanding how the authorization services
|
||||
can be used in their own applications.
|
||||
|
||||
Each quickstart has a `README` file with instructions on how to build, deploy, and test the sample application. The following
|
||||
table provides a brief description of the available authorization quickstarts:
|
||||
|
||||
.Authorization quickstarts
|
||||
|===
|
||||
|Name |Description
|
||||
|
||||
| {quickstartRepo_link}/tree/latest/app-authz-jee-servlet[app-authz-jee-servlet]
|
||||
| Demonstrates how to enable fine-grained authorization to a Jakarta EE application in order to protect specific resources and build a dynamic menu based on the permissions obtained from a {Project_Name} Server.
|
||||
|
||||
| {quickstartRepo_link}/tree/latest/app-authz-jee-vanilla[app-authz-jee-vanilla]
|
||||
| Demonstrates how to enable fine-grained authorization to a Jakarta EE application and use the default authorization settings to protect all resources in the application.
|
||||
|
||||
| {quickstartRepo_link}/tree/latest/app-authz-rest-springboot[app-authz-rest-springboot]
|
||||
| Demonstrates how to protect a SpringBoot REST service using {Project_Name} Authorization Services.
|
||||
|
||||
| {quickstartRepo_link}/tree/latest/app-authz-springboot[app-authz-springboot]
|
||||
| Demonstrates how to write a SpringBoot Web application where both authentication and authorization aspects are managed by {Project_Name}.
|
||||
|
||||
| {quickstartRepo_link}/tree/latest/app-authz-uma-photoz[app-authz-uma-photoz]
|
||||
| A simple application based on HTML5+AngularJS+JAX-RS that demonstrates how to enable User-Managed Access to your application and let users manage permissions for their resources.
|
||||
|
||||
|===
|
|
@ -5,23 +5,19 @@ When policy enforcement is enabled, the permissions obtained from the server are
|
|||
This class provides several methods you can use to obtain permissions and ascertain whether a permission was granted for a particular resource or scope.
|
||||
|
||||
Obtaining the Authorization Context in a Servlet Container
|
||||
```java
|
||||
HttpServletRequest request = ... // obtain javax.servlet.http.HttpServletRequest
|
||||
KeycloakSecurityContext keycloakSecurityContext =
|
||||
(KeycloakSecurityContext) request
|
||||
.getAttribute(KeycloakSecurityContext.class.getName());
|
||||
AuthorizationContext authzContext =
|
||||
keycloakSecurityContext.getAuthorizationContext();
|
||||
```
|
||||
|
||||
[source,java]
|
||||
----
|
||||
HttpServletRequest request = // obtain javax.servlet.http.HttpServletRequest
|
||||
AuthorizationContext authzContext = (AuthorizationContext) request.getAttribute(AuthorizationContext.class.getName());
|
||||
----
|
||||
|
||||
[NOTE]
|
||||
For more details about how you can obtain a `KeycloakSecurityContext` consult the adapter configuration. The example above should be sufficient
|
||||
to obtain the context when running an application using any of the servlet containers supported by {project_name}.
|
||||
|
||||
The authorization context helps give you more control over the decisions made and returned by the server. For example, you can use it
|
||||
to build a dynamic menu where items are hidden or shown depending on the permissions associated with a resource or scope.
|
||||
|
||||
```java
|
||||
[source,java]
|
||||
----
|
||||
if (authzContext.hasResourcePermission("Project Resource")) {
|
||||
// user can access the Project Resource
|
||||
}
|
||||
|
@ -33,13 +29,14 @@ if (authzContext.hasResourcePermission("Admin Resource")) {
|
|||
if (authzContext.hasScopePermission("urn:project.com:project:create")) {
|
||||
// user can create new projects
|
||||
}
|
||||
```
|
||||
----
|
||||
|
||||
The `AuthorizationContext` represents one of the main capabilities of {project_name} Authorization Services. From the examples above, you can see that the protected resource is not directly associated with the policies that govern them.
|
||||
|
||||
Consider some similar code using role-based access control (RBAC):
|
||||
|
||||
```java
|
||||
[source,java]
|
||||
----
|
||||
if (User.hasRole('user')) {
|
||||
// user can access the Project Resource
|
||||
}
|
||||
|
@ -51,9 +48,9 @@ if (User.hasRole('admin')) {
|
|||
if (User.hasRole('project-manager')) {
|
||||
// user can create new projects
|
||||
}
|
||||
```
|
||||
----
|
||||
|
||||
Although both examples address the same requirements, they do so in different ways. In RBAC, roles only _implicitly_ define access for their resources. With {project_name} you gain the capability to create more manageable code that focuses directly on your resources whether you are using RBAC, attribute-based access control (ABAC), or any other BAC variant. Either you have the permission for a given resource or scope, or you don't.
|
||||
Although both examples address the same requirements, they do so in different ways. In RBAC, roles only _implicitly_ define access for their resources. With {project_name}, you gain the capability to create more manageable code that focuses directly on your resources whether you are using RBAC, attribute-based access control (ABAC), or any other BAC variant. Either you have the permission for a given resource or scope, or you do not have that permission.
|
||||
|
||||
Now, suppose your security requirements have changed and in addition to project managers, PMOs can also create new projects.
|
||||
|
||||
|
@ -63,9 +60,10 @@ Security requirements change, but with {project_name} there is no need to change
|
|||
|
||||
The ```AuthorizationContext``` can also be used to obtain a reference to the <<_service_client_api, Authorization Client API>> configured to your application:
|
||||
|
||||
```java
|
||||
[source,java]
|
||||
----
|
||||
ClientAuthorizationContext clientContext = ClientAuthorizationContext.class.cast(authzContext);
|
||||
AuthzClient authzClient = clientContext.getClient();
|
||||
```
|
||||
----
|
||||
|
||||
In some cases, resource servers protected by the policy enforcer need to access the APIs provided by the authorization server. With an ```AuthzClient``` instance in hands, resource servers can interact with the server in order to create resources or check for specific permissions programmatically.
|
||||
|
|
|
@ -19,90 +19,102 @@ Contextual-based Authorization and how to use runtime information in order to su
|
|||
Here are several examples showing how you can extract claims from an HTTP request:
|
||||
|
||||
.keycloak.json
|
||||
```json
|
||||
"policy-enforcer": {
|
||||
"paths": [
|
||||
{
|
||||
"path": "/protected/resource",
|
||||
"claim-information-point": {
|
||||
"claims": {
|
||||
"claim-from-request-parameter": "{request.parameter['a']}",
|
||||
"claim-from-header": "{request.header['b']}",
|
||||
"claim-from-cookie": "{request.cookie['c']}",
|
||||
"claim-from-remoteAddr": "{request.remoteAddr}",
|
||||
"claim-from-method": "{request.method}",
|
||||
"claim-from-uri": "{request.uri}",
|
||||
"claim-from-relativePath": "{request.relativePath}",
|
||||
"claim-from-secure": "{request.secure}",
|
||||
"claim-from-json-body-object": "{request.body['/a/b/c']}",
|
||||
"claim-from-json-body-array": "{request.body['/d/1']}",
|
||||
"claim-from-body": "{request.body}",
|
||||
"claim-from-static-value": "static value",
|
||||
"claim-from-multiple-static-value": ["static", "value"],
|
||||
"param-replace-multiple-placeholder": "Test {keycloak.access_token['/custom_claim/0']} and {request.parameter['a']} "
|
||||
}
|
||||
[source,json]
|
||||
----
|
||||
{
|
||||
"paths": [
|
||||
{
|
||||
"path": "/protected/resource",
|
||||
"claim-information-point": {
|
||||
"claims": {
|
||||
"claim-from-request-parameter": "{request.parameter['a']}",
|
||||
"claim-from-header": "{request.header['b']}",
|
||||
"claim-from-cookie": "{request.cookie['c']}",
|
||||
"claim-from-remoteAddr": "{request.remoteAddr}",
|
||||
"claim-from-method": "{request.method}",
|
||||
"claim-from-uri": "{request.uri}",
|
||||
"claim-from-relativePath": "{request.relativePath}",
|
||||
"claim-from-secure": "{request.secure}",
|
||||
"claim-from-json-body-object": "{request.body['/a/b/c']}",
|
||||
"claim-from-json-body-array": "{request.body['/d/1']}",
|
||||
"claim-from-body": "{request.body}",
|
||||
"claim-from-static-value": "static value",
|
||||
"claim-from-multiple-static-value": ["static", "value"],
|
||||
"param-replace-multiple-placeholder": "Test {keycloak.access_token['/custom_claim/0']} and {request.parameter['a']}"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
}
|
||||
]
|
||||
}
|
||||
----
|
||||
|
||||
== Obtaining information from an external HTTP service
|
||||
|
||||
Here are several examples showing how you can extract claims from an external HTTP Service:
|
||||
|
||||
.keycloak.json
|
||||
```json
|
||||
"policy-enforcer": {
|
||||
"paths": [
|
||||
{
|
||||
"path": "/protected/resource",
|
||||
"claim-information-point": {
|
||||
"http": {
|
||||
"claims": {
|
||||
"claim-a": "/a",
|
||||
"claim-d": "/d",
|
||||
"claim-d0": "/d/0",
|
||||
"claim-d-all": ["/d/0", "/d/1"]
|
||||
},
|
||||
"url": "http://mycompany/claim-provider",
|
||||
"method": "POST",
|
||||
"headers": {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
"header-b": ["header-b-value1", "header-b-value2"],
|
||||
"Authorization": "Bearer {keycloak.access_token}"
|
||||
},
|
||||
"parameters": {
|
||||
"param-a": ["param-a-value1", "param-a-value2"],
|
||||
"param-subject": "{keycloak.access_token['/sub']}",
|
||||
"param-user-name": "{keycloak.access_token['/preferred_username']}",
|
||||
"param-other-claims": "{keycloak.access_token['/custom_claim']}"
|
||||
}
|
||||
[source,json]
|
||||
----
|
||||
{
|
||||
"paths": [
|
||||
{
|
||||
"path": "/protected/resource",
|
||||
"claim-information-point": {
|
||||
"http": {
|
||||
"claims": {
|
||||
"claim-a": "/a",
|
||||
"claim-d": "/d",
|
||||
"claim-d0": "/d/0",
|
||||
"claim-d-all": [
|
||||
"/d/0",
|
||||
"/d/1"
|
||||
]
|
||||
},
|
||||
"url": "http://mycompany/claim-provider",
|
||||
"method": "POST",
|
||||
"headers": {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
"header-b": [
|
||||
"header-b-value1",
|
||||
"header-b-value2"
|
||||
],
|
||||
"Authorization": "Bearer {keycloak.access_token}"
|
||||
},
|
||||
"parameters": {
|
||||
"param-a": [
|
||||
"param-a-value1",
|
||||
"param-a-value2"
|
||||
],
|
||||
"param-subject": "{keycloak.access_token['/sub']}",
|
||||
"param-user-name": "{keycloak.access_token['/preferred_username']}",
|
||||
"param-other-claims": "{keycloak.access_token['/custom_claim']}"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
}
|
||||
]
|
||||
}
|
||||
----
|
||||
|
||||
== Static claims
|
||||
|
||||
.keycloak.json
|
||||
```json
|
||||
"policy-enforcer": {
|
||||
"paths": [
|
||||
{
|
||||
"path": "/protected/resource",
|
||||
"claim-information-point": {
|
||||
"claims": {
|
||||
"claim-from-static-value": "static value",
|
||||
"claim-from-multiple-static-value": ["static", "value"],
|
||||
}
|
||||
[source,json]
|
||||
----
|
||||
{
|
||||
"paths": [
|
||||
{
|
||||
"path": "/protected/resource",
|
||||
"claim-information-point": {
|
||||
"claims": {
|
||||
"claim-from-static-value": "static value",
|
||||
"claim-from-multiple-static-value": ["static", "value"]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
}
|
||||
]
|
||||
}
|
||||
----
|
||||
|
||||
== Claim information provider SPI
|
||||
|
||||
|
@ -115,7 +127,8 @@ in your application`s classpath.
|
|||
|
||||
Example of `org.keycloak.adapters.authorization.ClaimInformationPointProviderFactory`:
|
||||
|
||||
```java
|
||||
[source,java]
|
||||
----
|
||||
public class MyClaimInformationPointProviderFactory implements ClaimInformationPointProviderFactory<MyClaimInformationPointProvider> {
|
||||
|
||||
@Override
|
||||
|
@ -133,7 +146,7 @@ public class MyClaimInformationPointProviderFactory implements ClaimInformationP
|
|||
return new MyClaimInformationPointProvider(config);
|
||||
}
|
||||
}
|
||||
```
|
||||
----
|
||||
|
||||
Every CIP provider must be associated with a name, as defined above in the `MyClaimInformationPointProviderFactory.getName` method. The name
|
||||
will be used to map the configuration from the `claim-information-point` section in the `policy-enforcer` configuration to the implementation.
|
||||
|
@ -144,7 +157,8 @@ instance of MyClaimInformationPointProvider. When called, any configuration defi
|
|||
|
||||
Example of `ClaimInformationPointProvider`:
|
||||
|
||||
```java
|
||||
[source,java]
|
||||
----
|
||||
public class MyClaimInformationPointProvider implements ClaimInformationPointProvider {
|
||||
|
||||
private final Map<String, Object> config;
|
||||
|
@ -162,4 +176,4 @@ public class MyClaimInformationPointProvider implements ClaimInformationPointPro
|
|||
return claims;
|
||||
}
|
||||
}
|
||||
```
|
||||
----
|
||||
|
|
|
@ -1,68 +1,105 @@
|
|||
[[_enforcer_filter]]
|
||||
[[_enforcer_configuration]]
|
||||
= Configuration
|
||||
|
||||
To enable policy enforcement for your application, add the following property to your *keycloak.json* file:
|
||||
The policy enforcer configuration uses a JSON format and most of the time you don't need to set anything if you want to
|
||||
automatically resolve the protected paths based on the resources available from your resource server.
|
||||
|
||||
.keycloak.json
|
||||
```json
|
||||
If you want to manually define the resources being protected, you can use a slightly more verbose format:
|
||||
|
||||
[source,json]
|
||||
----
|
||||
{
|
||||
"policy-enforcer": {}
|
||||
"enforcement-mode" : "ENFORCING",
|
||||
"paths": [
|
||||
{
|
||||
"path" : "/users/*",
|
||||
"methods" : [
|
||||
{
|
||||
"method": "GET",
|
||||
"scopes" : ["urn:app.com:scopes:view"]
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"scopes" : ["urn:app.com:scopes:create"]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
Or a little more verbose if you want to manually define the resources being protected:
|
||||
----
|
||||
|
||||
```json
|
||||
{
|
||||
"policy-enforcer": {
|
||||
"user-managed-access" : {},
|
||||
"enforcement-mode" : "ENFORCING",
|
||||
"paths": [
|
||||
{
|
||||
"path" : "/someUri/*",
|
||||
"methods" : [
|
||||
{
|
||||
"method": "GET",
|
||||
"scopes" : ["urn:app.com:scopes:view"]
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"scopes" : ["urn:app.com:scopes:create"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "Some Resource",
|
||||
"path" : "/usingPattern/{id}",
|
||||
"methods" : [
|
||||
{
|
||||
"method": "DELETE",
|
||||
"scopes" : ["urn:app.com:scopes:delete"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"path" : "/exactMatch"
|
||||
},
|
||||
{
|
||||
"name" : "Admin Resources",
|
||||
"path" : "/usingWildCards/*"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
The following is a description of each configuration option:
|
||||
|
||||
Here is a description of each configuration option:
|
||||
|
||||
* *policy-enforcer*
|
||||
* *enforcement-mode*
|
||||
+
|
||||
Specifies the configuration options that define how policies are actually enforced and optionally the paths you want to protect. If not specified, the policy enforcer queries the server
|
||||
for all resources associated with the resource server being protected. In this case, you need to ensure the resources are properly configured with a <<_resource_create_uri, URIS>> property that matches the paths you want to protect.
|
||||
Specifies how policies are enforced.
|
||||
+
|
||||
** *user-managed-access*
|
||||
** *ENFORCING*
|
||||
+
|
||||
Specifies that the adapter uses the UMA protocol. If specified, the adapter queries the server for permission tickets and returns them to clients according to the UMA specification. If not specified, the policy enforcer will be able to enforce permissions based on regular access tokens or RPTs. In this case,
|
||||
before denying access to the resource when the token lacks permission, the policy enforcer will try to obtain permissions directly from the server.
|
||||
(default mode) Requests are denied by default even when no policy is associated with a given resource.
|
||||
+
|
||||
** *PERMISSIVE*
|
||||
+
|
||||
Requests are allowed even when no policy is associated with a given resource.
|
||||
+
|
||||
** *DISABLED*
|
||||
+
|
||||
Completely disables the evaluation of policies and allows access to any resource. When `enforcement-mode` is `DISABLED`,
|
||||
applications are still able to obtain all permissions granted by {project_name} through the <<_enforcer_authorization_context, Authorization Context>>
|
||||
+
|
||||
* *on-deny-redirect-to*
|
||||
+
|
||||
Defines a URL where a client request is redirected when an "access denied" message is obtained from the server. By default, the adapter responds with a 403 HTTP status code.
|
||||
+
|
||||
* *path-cache*
|
||||
+
|
||||
Defines how the policy enforcer should track associations between paths in your application and resources defined in {project_name}. The cache is needed to avoid
|
||||
unnecessary requests to a {project_name} server by caching associations between paths and protected resources.
|
||||
+
|
||||
** *lifespan*
|
||||
+
|
||||
Defines the time in milliseconds when the entry should be expired. If not provided, default value is *30000*. A value equal to 0 can be set to completely disable the cache. A value equal to -1 can be set to disable the expiry of the cache.
|
||||
+
|
||||
** *max-entries*
|
||||
+
|
||||
Defines the limit of entries that should be kept in the cache. If not provided, default value is *1000*.
|
||||
+
|
||||
* *paths*
|
||||
+
|
||||
Specifies the paths to protect. This configuration is optional. If not defined, the policy enforcer discovers all paths by fetching the resources you defined to your application in {project_name}, where these resources are defined with `URIS` representing some paths in your application.
|
||||
+
|
||||
** *name*
|
||||
+
|
||||
The name of a resource on the server that is to be associated with a given path. When used in conjunction with a *path*, the policy enforcer ignores the resource's *URIS* property and uses the path you provided instead.
|
||||
** *path*
|
||||
+
|
||||
(required) A URI relative to the application's context path. If this option is specified, the policy enforcer queries the server for a resource with a *URI* with the same value.
|
||||
Currently a very basic logic for path matching is supported. Examples of valid paths are:
|
||||
+
|
||||
*** Wildcards: `/*`
|
||||
*** Suffix: `/*.html`
|
||||
*** Sub-paths: `/path/*`
|
||||
*** Path parameters: /resource/{id}
|
||||
*** Exact match: /resource
|
||||
*** Patterns: /{version}/resource, /api/{version}/resource, /api/{version}/resource/*
|
||||
+
|
||||
** *methods*
|
||||
+
|
||||
The HTTP methods (for example, GET, POST, PATCH) to protect and how they are associated with the scopes for a given resource in the server.
|
||||
+
|
||||
*** *method*
|
||||
+
|
||||
The name of the HTTP method.
|
||||
+
|
||||
*** *scopes*
|
||||
+
|
||||
An array of strings with the scopes associated with the method. When you associate scopes with a specific method, the client trying to access a protected resource (or path) must provide an RPT that grants permission to all scopes specified in the list. For example, if you define a method _POST_ with a scope _create_, the RPT must contain a permission granting access to the _create_ scope when performing a POST to the path.
|
||||
+
|
||||
*** *scopes-enforcement-mode*
|
||||
+
|
||||
A string referencing the enforcement mode for the scopes associated with a method. Values can be *ALL* or *ANY*. If *ALL*,
|
||||
all defined scopes must be granted in order to access the resource using that method. If *ANY*, at least one scope should be
|
||||
granted in order to gain access to the resource using that method. By default, enforcement mode is set to *ALL*.
|
||||
+
|
||||
** *enforcement-mode*
|
||||
+
|
||||
|
@ -72,95 +109,24 @@ Specifies how policies are enforced.
|
|||
+
|
||||
(default mode) Requests are denied by default even when there is no policy associated with a given resource.
|
||||
+
|
||||
*** *PERMISSIVE*
|
||||
+
|
||||
Requests are allowed even when there is no policy associated with a given resource.
|
||||
+
|
||||
*** *DISABLED*
|
||||
+
|
||||
Completely disables the evaluation of policies and allows access to any resource. When `enforcement-mode` is `DISABLED`
|
||||
applications are still able to obtain all permissions granted by {project_name} through the <<_enforcer_authorization_context, Authorization Context>>
|
||||
+
|
||||
** *on-deny-redirect-to*
|
||||
+
|
||||
Defines a URL where a client request is redirected when an "access denied" message is obtained from the server. By default, the adapter responds with a 403 HTTP status code.
|
||||
+
|
||||
** *path-cache*
|
||||
+
|
||||
Defines how the policy enforcer should track associations between paths in your application and resources defined in {project_name}. The cache is needed to avoid
|
||||
unnecessary requests to a {project_name} server by caching associations between paths and protected resources.
|
||||
+
|
||||
*** *lifespan*
|
||||
+
|
||||
Defines the time in milliseconds when the entry should be expired. If not provided, default value is *30000*. A value equal to 0 can be set to completely disable the cache. A value equal to -1 can be set to disable the expiry of the cache.
|
||||
+
|
||||
*** *max-entries*
|
||||
+
|
||||
Defines the limit of entries that should be kept in the cache. If not provided, default value is *1000*.
|
||||
+
|
||||
** *paths*
|
||||
+
|
||||
Specifies the paths to protect. This configuration is optional. If not defined, the policy enforcer will discover all paths by fetching the resources you defined to your application in {project_name}, where these resources are defined with `URIS` representing some paths in your application.
|
||||
+
|
||||
*** *name*
|
||||
+
|
||||
The name of a resource on the server that is to be associated with a given path. When used in conjunction with a *path*, the policy enforcer ignores the resource's *URIS* property and uses the path you provided instead.
|
||||
*** *path*
|
||||
+
|
||||
(required) A URI relative to the application's context path. If this option is specified, the policy enforcer queries the server for a resource with a *URI* with the same value.
|
||||
Currently a very basic logic for path matching is supported. Examples of valid paths are:
|
||||
+
|
||||
**** Wildcards: `/*`
|
||||
**** Suffix: `/*.html`
|
||||
**** Sub-paths: `/path/*`
|
||||
**** Path parameters: /resource/{id}
|
||||
**** Exact match: /resource
|
||||
**** Patterns: /{version}/resource, /api/{version}/resource, /api/{version}/resource/*
|
||||
+
|
||||
*** *methods*
|
||||
+
|
||||
The HTTP methods (for example, GET, POST, PATCH) to protect and how they are associated with the scopes for a given resource in the server.
|
||||
+
|
||||
**** *method*
|
||||
+
|
||||
The name of the HTTP method.
|
||||
+
|
||||
**** *scopes*
|
||||
+
|
||||
An array of strings with the scopes associated with the method. When you associate scopes with a specific method, the client trying to access a protected resource (or path) must provide an RPT that grants permission to all scopes specified in the list. For example, if you define a method _POST_ with a scope _create_, the RPT must contain a permission granting access to the _create_ scope when performing a POST to the path.
|
||||
+
|
||||
**** *scopes-enforcement-mode*
|
||||
+
|
||||
A string referencing the enforcement mode for the scopes associated with a method. Values can be *ALL* or *ANY*. If *ALL*,
|
||||
all defined scopes must be granted in order to access the resource using that method. If *ANY*, at least one scope should be
|
||||
granted in order to gain access to the resource using that method. By default, enforcement mode is set to *ALL*.
|
||||
+
|
||||
*** *enforcement-mode*
|
||||
+
|
||||
Specifies how policies are enforced.
|
||||
+
|
||||
**** *ENFORCING*
|
||||
+
|
||||
(default mode) Requests are denied by default even when there is no policy associated with a given resource.
|
||||
+
|
||||
**** *DISABLED*
|
||||
+
|
||||
*** *claim-information-point*
|
||||
** *claim-information-point*
|
||||
+
|
||||
Defines a set of one or more claims that must be resolved and pushed to the {project_name} server in order to make these claims available to policies. See <<_enforcer_claim_information_point, Claim Information Point>> for more details.
|
||||
+
|
||||
** *lazy-load-paths*
|
||||
* *lazy-load-paths*
|
||||
+
|
||||
Specifies how the adapter should fetch the server for resources associated with paths in your application. If *true*, the policy
|
||||
enforcer is going to fetch resources on-demand accordingly with the path being requested. This configuration is specially useful
|
||||
when you don't want to fetch all resources from the server during deployment (in case you have provided no `paths`) or in case
|
||||
when you do not want to fetch all resources from the server during deployment (in case you have provided no `paths`) or in case
|
||||
you have defined only a sub set of `paths` and want to fetch others on-demand.
|
||||
+
|
||||
** *http-method-as-scope*
|
||||
* *http-method-as-scope*
|
||||
+
|
||||
Specifies how scopes should be mapped to HTTP methods. If set to *true*, the policy enforcer will use the HTTP method from the current request to
|
||||
check whether or not access should be granted. When enabled, make sure your resources in {project_name} are associated with scopes representing each HTTP method you are protecting.
|
||||
+
|
||||
** *claim-information-point*
|
||||
* *claim-information-point*
|
||||
+
|
||||
Defines a set of one or more *global* claims that must be resolved and pushed to the {project_name} server in order to make these claims available to policies. See <<_enforcer_claim_information_point, Claim Information Point>> for more details.
|
|
@ -1,15 +1,15 @@
|
|||
[[_enforcer_filter_using_https]]
|
||||
= Configuring TLS/HTTPS
|
||||
|
||||
When the server is using HTTPS, ensure your adapter is configured as follows:
|
||||
When the server is using HTTPS, ensure your policy enforcer is configured as follows:
|
||||
|
||||
.keycloak.json
|
||||
```json
|
||||
[source,json]
|
||||
----
|
||||
{
|
||||
"truststore": "path_to_your_trust_store",
|
||||
"truststore-password": "trust_store_password"
|
||||
}
|
||||
```
|
||||
----
|
||||
|
||||
The configuration above enables TLS/HTTPS to the Authorization Client, making possible to access a
|
||||
{project_name} Server remotely using the HTTPS scheme.
|
||||
|
|
|
@ -10,12 +10,13 @@ You can obtain this library from a running a {project_name} Server instance by i
|
|||
----
|
||||
<script src="http://...{kc_js_path}/keycloak-authz.js"></script>
|
||||
----
|
||||
Once you do that, you can create a `KeycloakAuthorization` instance as follows:
|
||||
Next, you can create a `KeycloakAuthorization` instance as follows:
|
||||
|
||||
```javascript
|
||||
[source,javascript]
|
||||
----
|
||||
const keycloak = ... // obtain a Keycloak instance from keycloak.js library
|
||||
const authorization = new KeycloakAuthorization(keycloak);
|
||||
```
|
||||
----
|
||||
The *keycloak-authz.js* library provides two main features:
|
||||
|
||||
* Obtain permissions from the server using a permission ticket, if you are accessing a UMA protected resource server.
|
||||
|
@ -44,7 +45,8 @@ See <<_service_uma_authorization_process, UMA Authorization Process>> for more i
|
|||
What your client needs to do is extract the permission ticket from the ```WWW-Authenticate``` header returned by the resource server
|
||||
and use the library to send an authorization request as follows:
|
||||
|
||||
```javascript
|
||||
[source,javascript]
|
||||
----
|
||||
// prepare a authorization request with the permission ticket
|
||||
const authorizationRequest = {};
|
||||
authorizationRequest.ticket = ticket;
|
||||
|
@ -57,7 +59,7 @@ Identity.authorization.authorize(authorizationRequest).then(function (rpt) {
|
|||
}, function () {
|
||||
// onError
|
||||
});
|
||||
```
|
||||
----
|
||||
|
||||
The `authorize` function is completely asynchronous and supports a few callback functions to receive notifications from the server:
|
||||
|
||||
|
@ -73,16 +75,18 @@ The ```keycloak-authz.js``` library provides an `entitlement` function that you
|
|||
the resources and scopes your client wants to access.
|
||||
|
||||
.Example about how to obtain an RPT with permissions for all resources and scopes the user can access
|
||||
```javascript
|
||||
[source,javascript]
|
||||
----
|
||||
authorization.entitlement('my-resource-server-id').then(function (rpt) {
|
||||
// onGrant callback function.
|
||||
// If authorization was successful you'll receive an RPT
|
||||
// with the necessary permissions to access the resource server
|
||||
});
|
||||
```
|
||||
----
|
||||
|
||||
.Example about how to obtain an RPT with permissions for specific resources and scopes
|
||||
```javascript
|
||||
[source,javascript]
|
||||
----
|
||||
authorization.entitlement('my-resource-server', {
|
||||
"permissions": [
|
||||
{
|
||||
|
@ -92,7 +96,7 @@ authorization.entitlement('my-resource-server', {
|
|||
}).then(function (rpt) {
|
||||
// onGrant
|
||||
});
|
||||
```
|
||||
----
|
||||
|
||||
When using the `entitlement` function, you must provide the _client_id_ of the resource server you want to access.
|
||||
|
||||
|
@ -111,7 +115,8 @@ properties:
|
|||
+
|
||||
An array of objects representing the resource and scopes. For instance:
|
||||
+
|
||||
```javascript
|
||||
[source,javascript]
|
||||
----
|
||||
const authorizationRequest = {
|
||||
"permissions": [
|
||||
{
|
||||
|
@ -120,7 +125,7 @@ const authorizationRequest = {
|
|||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
----
|
||||
+
|
||||
* *metadata*
|
||||
+
|
||||
|
@ -144,6 +149,7 @@ This parameter will only take effect when used together with the `ticket` parame
|
|||
|
||||
If you have already obtained an RPT using any of the authorization functions provided by the library, you can always obtain the RPT as follows from the authorization object (assuming that it has been initialized by one of the techniques shown earlier):
|
||||
|
||||
```javascript
|
||||
[source,javascript]
|
||||
----
|
||||
const rpt = authorization.rpt;
|
||||
```
|
||||
----
|
||||
|
|
|
@ -11,18 +11,15 @@ A PEP is responsible for enforcing access decisions from the {project_name} serv
|
|||
associated with a protected resource. It acts as a filter or interceptor in your application in order to check whether or not a particular request
|
||||
to a protected resource can be fulfilled based on the permissions granted by these decisions.
|
||||
|
||||
Permissions are enforced depending on the protocol you are using. When using UMA, the policy enforcer always expects an RPT as a bearer token in order
|
||||
to decide whether or not a request can be served. That means clients should first obtain an RPT from {project_name} before sending requests to the resource server.
|
||||
{project_name} provides built-in support for enabling the *{project_name} Policy Enforcer* to Java applications with built-in support to secure JakartaEE-compliant frameworks and web containers.
|
||||
If you are using Maven, you should configure the following dependency to your project:
|
||||
|
||||
However, if you are not using UMA, you can also send regular access tokens to the resource server. In this case, the policy enforcer will try to obtain permissions directly from the server.
|
||||
|
||||
If you are using any of the {project_name} OIDC adapters, you can easily enable the policy enforcer by adding the following property to your *keycloak.json* file:
|
||||
|
||||
.keycloak.json
|
||||
```json
|
||||
{
|
||||
"policy-enforcer": {}
|
||||
}
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-policy-enforcer</artifactId>
|
||||
<version>${keycloak.version}</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
When you enable the policy enforcer all requests sent to your application are intercepted and access to protected resources will be granted
|
||||
|
|
|
@ -1,26 +1,10 @@
|
|||
[[_getting_started_overview]]
|
||||
= Getting started
|
||||
= Getting Started
|
||||
|
||||
Before you can use this tutorial, you need to complete the installation of {project_name} and create the initial admin user as shown in the link:{gettingstarted_link}[{gettingstarted_name}] tutorial.
|
||||
There is one caveat to this. You have to run a separate {appserver_name} instance on the same machine as {project_name} Server. This separate instance will run your Java Servlet application. Because of this you will have to run the {project_name} under a different port so that there are no port conflicts when running on the same machine. Use the `jboss.socket.binding.port-offset` system property on the command line. The value of this property is a number that will be added to the base value of every port opened by {project_name} Server.
|
||||
If you are using Wildfly, Spring Boot, or Quarkus, you can look at the following quickstarts and documentation to quickly
|
||||
get started with {project_name} Authorization Services:
|
||||
|
||||
To boot {project_name} Server:
|
||||
|
||||
.Linux/Unix
|
||||
[source]
|
||||
----
|
||||
$ .../bin/kc.sh start-dev --http-port 8180
|
||||
----
|
||||
|
||||
.Windows
|
||||
[source]
|
||||
----
|
||||
> ...\bin\kc.bat start-dev --http-port 8180
|
||||
----
|
||||
|
||||
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
|
||||
http://localhost:8080.
|
||||
|
||||
[role="_additional-resources"]
|
||||
.Additional resources
|
||||
* For more details about installing and configuring {appserver_name} instances, see link:{adapterguide_link}[{adapterguide_name}].
|
||||
* {quickstartRepo_link}/tree/latest/jakarta/servlet-authz-client[Securing a JakartaEE Application in Wildfly]
|
||||
* {quickstartRepo_link}/tree/latest/spring/rest-authz-resource-server[Securing a Spring Boot Application]
|
||||
* link:https://quarkus.io/guides/security-keycloak-authorization[Securing Quarkus Applications]
|
||||
* {adapterguide_link_nodejs_adapter}[Securing Node.js Applications]
|
|
@ -1,15 +0,0 @@
|
|||
= Before you start
|
||||
|
||||
This guide is based on the *{project_name} Demo Distribution*. Download the demo distribution before proceeding.
|
||||
|
||||
[NOTE]
|
||||
This guide assumes that you are already familiar with {project_name} and that you are able to install and boot a {project_name} Server. For more information, see https://keycloak.gitbooks.io/getting-started-tutorials/content/[the Getting Started tutorials].
|
||||
|
||||
Ensure you have a {project_name} instance running; the default configuration is http://localhost:8080/auth[http://localhost:8080/auth]. After logging in to the
|
||||
Administration Console, a page similar to this one is displayed:
|
||||
|
||||
.{project_name} Admin Console
|
||||
image:images/getting-started/kc-start-page.png[alt="{project_name} Admin Console"]
|
||||
|
||||
The source code for the getting started tutorials can be obtained from the demo distributions. The authorization-related examples
|
||||
are located at *${KEYCLOAK_DEMO_SERVER_DIR}/examples/authz*.
|
|
@ -1,33 +0,0 @@
|
|||
[[_getting_started_hello_world_create_realm]]
|
||||
= Creating a realm and a user
|
||||
|
||||
The first step in this tutorial is to create a realm and a user in that realm. Then, within the realm we will create a single client application, which then becomes a <<_overview_terminology, resource server>> for which you need to enable authorization services.
|
||||
|
||||
.Procedure
|
||||
|
||||
. Create a realm with a name *hello-world-authz*. Once created, a page similar to the following is displayed:
|
||||
+
|
||||
.Realm hello-world-authz
|
||||
image:images/getting-started/hello-world/create-realm.png[alt="Realm hello-world-authz"]
|
||||
|
||||
. Click *Users*.
|
||||
+
|
||||
The user list page displays where you can create a user.
|
||||
|
||||
. Click *Create user*.
|
||||
. Complete the *Username*, *Email*, *First Name*, and *Last Name* fields.
|
||||
. Toggle *User Enabled* to *ON*.
|
||||
. Click *Create*.
|
||||
+
|
||||
.Add User
|
||||
image:images/getting-started/hello-world/create-user.png[alt="Add User"]
|
||||
|
||||
. Set a password for the user by clicking the *Credentials* tab.
|
||||
+
|
||||
.Set user password
|
||||
image:images/getting-started/hello-world/reset-user-pwd.png[alt="Set user password"]
|
||||
|
||||
. Complete the *New Password* and *Password Confirmation* fields and toggle *Temporary* to *OFF*.
|
||||
|
||||
. Click *Save*.
|
||||
. Click *Save password*.
|
|
@ -1,39 +0,0 @@
|
|||
[[_getting_started_hello_world_enabling_authz_services]]
|
||||
= Enabling authorization services
|
||||
|
||||
You can enable authorization services in an existing client application configured to use the OpenID Connect Protocol. You can also create a client using the following procedure.
|
||||
|
||||
.Procedure
|
||||
|
||||
. Click *Clients* in the menu.
|
||||
|
||||
. Fill in the *Client type*.
|
||||
. Click *Next*.
|
||||
. Toggle *Client authentication* to *ON*.
|
||||
. Toggle *Authorization* to *ON*.
|
||||
. Click *Save*.
|
||||
. Scroll down to the *Capability config* section.
|
||||
. Fill in the *Root URL* field.
|
||||
. Click *Save*.
|
||||
+
|
||||
.Create client application
|
||||
image:images/getting-started/hello-world/create-client.png[alt="Create client application"]
|
||||
+
|
||||
A new *Authorization* tab is displayed for the client.
|
||||
+
|
||||
.Client Settings
|
||||
image:images/getting-started/hello-world/enable-authz.png[alt="Client Settings"]
|
||||
|
||||
. Click the *Authorization* tab.
|
||||
+
|
||||
An Authorization Settings page similar to the following is displayed:
|
||||
+
|
||||
.Authorization settings
|
||||
image:images/getting-started/hello-world/authz-settings.png[alt="Authorization settings"]
|
||||
|
||||
When you enable authorization services for a client application, {project_name} automatically creates several default settings for your client authorization configuration.
|
||||
|
||||
[role="_additional-resources"]
|
||||
.Additional resources
|
||||
* <<_resource_server_enable_authorization, Enabling authorization services>>
|
||||
* <<_resource_server_default_config, Default configuration>>
|
|
@ -1,129 +0,0 @@
|
|||
[[_getting_started_hello_world_deploy]]
|
||||
= Build, deploy, and test your application
|
||||
|
||||
Now that the *app-authz-vanilla* resource server (or client) is properly configured and authorization services are enabled, it can be deployed to the server.
|
||||
|
||||
The project and code for the application you are going to deploy is available in link:{quickstartRepo_link}[{quickstartRepo_name}]. You will need the following
|
||||
installed on your machine and available in your PATH before you can continue:
|
||||
|
||||
* Java JDK 8
|
||||
* Apache Maven 3.1.1 or higher
|
||||
* Git
|
||||
|
||||
ifeval::[{project_community}==true]
|
||||
You can obtain the code by cloning the repository at {quickstartRepo_link}. The quickstarts are designed to work with the most recent Keycloak release.
|
||||
endif::[]
|
||||
|
||||
ifeval::[{project_product}==true]
|
||||
You can obtain the code by cloning the repository at {quickstartRepo_link}. Use the branch matching the version of {project_name} in use.
|
||||
endif::[]
|
||||
|
||||
Follow these steps to download the code.
|
||||
|
||||
.Clone Project
|
||||
[source, subs="attributes"]
|
||||
----
|
||||
$ git clone {quickstartRepo_link}
|
||||
----
|
||||
|
||||
The application we are about to build and deploy is located at
|
||||
|
||||
[source, subs="attributes"]
|
||||
----
|
||||
$ cd {quickstartRepo_dir}/app-authz-jee-vanilla
|
||||
----
|
||||
|
||||
== Obtaining the adapter configuration
|
||||
|
||||
You must first obtain the adapter configuration before building and deploying the application.
|
||||
|
||||
.Procedure
|
||||
|
||||
. Log into the Admin Console.
|
||||
|
||||
. Click *Clients* in the menu.
|
||||
|
||||
. In the client listing, click the *app-authz-vanilla* client application. The Client Settings page opens.
|
||||
+
|
||||
.Client Settings
|
||||
image:images/getting-started/hello-world/enable-authz.png[alt="Client Settings"]
|
||||
|
||||
. From the *Action* list, select *Download adapter config*.
|
||||
. From the Format Option list, select *Keycloak OIDC JSON*.
|
||||
+
|
||||
The adapter configuration is displayed in JSON format.
|
||||
|
||||
. Click *Download*.
|
||||
+
|
||||
.Adapter configuration
|
||||
image:images/getting-started/hello-world/adapter-config.png[alt="Adapter configuration"]
|
||||
|
||||
. Move the file `keycloak.json` to the `app-authz-jee-vanilla/config` directory.
|
||||
|
||||
. Optionally, specify a redirection URL.
|
||||
+
|
||||
By default, the policy enforcer responds with a `403` status code when the user lacks permission to access protected resources on the resource server. However, you can also specify a redirection URL for unauthorized users. To specify a redirection URL, edit the *keycloak.json* file that you updated and replace the `policy-enforcer` configuration with the following:
|
||||
+
|
||||
```json
|
||||
"policy-enforcer": {
|
||||
"on-deny-redirect-to" : "/app-authz-vanilla/error.jsp"
|
||||
}
|
||||
```
|
||||
+
|
||||
This change specifies to the policy enforcer to redirect users to a `/app-authz-vanilla/error.jsp` page if a user does not have the necessary permissions to access a protected resource, rather than an unhelpful `403 Unauthorized` message.
|
||||
|
||||
== Building and deploying the application
|
||||
|
||||
To build and deploy the application execute the following command:
|
||||
|
||||
[source, subs="attributes"]
|
||||
----
|
||||
$ cd {quickstartRepo_dir}/app-authz-jee-vanilla
|
||||
$ mvn clean package wildfly:deploy
|
||||
----
|
||||
|
||||
== Testing the application
|
||||
|
||||
If your application was successfully deployed, you can access it at http://localhost:8080/app-authz-vanilla[http://localhost:8080/app-authz-vanilla]. The {project_name} Login page opens.
|
||||
|
||||
.Login page
|
||||
image:images/getting-started/hello-world/login-page.png[alt="Login page"]
|
||||
|
||||
.Procedure
|
||||
|
||||
. Log in as *alice* using the password you specified for that user. The following page is displayed:
|
||||
+
|
||||
.Hello World Authz main page
|
||||
image:images/getting-started/hello-world/main-page.png[alt="Hello World Authz main page"]
|
||||
+
|
||||
The <<_resource_server_default_config, default settings>> defined by {project_name} when you enable authorization services for a client application provide a simple
|
||||
policy that always grants access to the resources protected by this policy.
|
||||
|
||||
You can start by changing the default permissions and policies and test how your application responds, or even create new policies using the different
|
||||
<<_policy_overview, policy types>> provided by {project_name}.
|
||||
|
||||
There are a plenty of things you can do now to test this application. For example, you can change the default policy by clicking
|
||||
the `Authorization` tab for the client, then client on the `Policies` tab, then click on the `Default Policy` in the list.
|
||||
Now we are going to change the `Logic` to `Negative` using the dropdown list in this page.
|
||||
|
||||
. Log out of the demo application and log in again.
|
||||
+
|
||||
You can no longer access the application.
|
||||
+
|
||||
image:images/getting-started/hello-world/access-denied-page.png[alt="Access Denied page"]
|
||||
|
||||
[role="_additional-resources"]
|
||||
.Additional resources
|
||||
* <<_policy_overview, Policy types>>
|
||||
|
||||
== Next steps
|
||||
|
||||
There are additional things you can do, such as:
|
||||
|
||||
* Create a scope, define a policy and permission for it, and test it on the application side. Can the user perform an action (or anything else represented by the scope you created)?
|
||||
* Create different types of policies and associate these policies with the `Default Permission`.
|
||||
* Apply multiple policies to the `Default Permission` and test the behavior. For example, combine multiple policies and change the `Decision Strategy` accordingly.
|
||||
|
||||
[role="_additional-resources"]
|
||||
.Additional resources
|
||||
* For more information about how to view and test permissions inside your application see <<_enforcer_authorization_context, Obtaining the authorization context>>.
|
|
@ -1,14 +0,0 @@
|
|||
[[_getting_started_hello_world_overview]]
|
||||
= Securing a servlet application
|
||||
|
||||
The purpose of this getting started guide is to get you up and running as quickly as possible so that you can experiment with and test various authorization features provided by {project_name}.
|
||||
This quick tour relies heavily on the default database and server configurations and does not cover complex deployment options.
|
||||
For more information on features or configuration options, see the appropriate sections in this documentation.
|
||||
|
||||
This guide explains key concepts about {project_name} Authorization Services:
|
||||
|
||||
* Enabling fine-grained authorization for a client application
|
||||
* Configuring a client application to be a resource server, with protected resources
|
||||
* Defining permissions and authorization policies to govern access to protected resources
|
||||
* Enabling policy enforcement in your applications.
|
||||
|
|
@ -1,41 +1,21 @@
|
|||
include::topics/overview/overview.adoc[]
|
||||
include::topics/overview/what-are-client-adapters.adoc[]
|
||||
include::topics/overview/supported-platforms.adoc[]
|
||||
include::topics/overview/supported-protocols.adoc[]
|
||||
include::topics/overview/terminology.adoc[]
|
||||
|
||||
include::topics/overview/basic-steps.adoc[]
|
||||
|
||||
include::topics/overview/getting-started.adoc[]
|
||||
|
||||
include::topics/overview/terminology.adoc[]
|
||||
|
||||
include::topics/oidc/oidc-overview.adoc[]
|
||||
|
||||
include::topics/oidc/available-endpoints.adoc[]
|
||||
|
||||
include::topics/oidc/supported-grant-types.adoc[]
|
||||
|
||||
ifeval::[{project_community}==true]
|
||||
include::topics/oidc/java/java-adapters.adoc[]
|
||||
include::topics/oidc/java/java-adapter-config.adoc[]
|
||||
include::topics/oidc/java/jboss-adapter.adoc[]
|
||||
ifeval::[{project_product}==true]
|
||||
include::topics/oidc/java/jboss-adapter-rpms.adoc[]
|
||||
endif::[]
|
||||
|
||||
include::topics/oidc/java/spring-boot-adapter.adoc[]
|
||||
|
||||
ifeval::[{project_community}==true]
|
||||
include::topics/oidc/java/tomcat-adapter.adoc[]
|
||||
include::topics/oidc/java/jetty9-adapter.adoc[]
|
||||
include::topics/oidc/java/spring-security-adapter.adoc[]
|
||||
endif::[]
|
||||
|
||||
include::topics/oidc/java/servlet-filter-adapter.adoc[]
|
||||
|
||||
ifeval::[{project_community}==true]
|
||||
include::topics/oidc/java/jaas.adoc[]
|
||||
include::topics/oidc/java/installed-adapter.adoc[]
|
||||
endif::[]
|
||||
|
||||
include::topics/oidc/java/adapter-context.adoc[]
|
||||
include::topics/oidc/java/adapter_error_handling.adoc[]
|
||||
include::topics/oidc/java/logout.adoc[]
|
||||
include::topics/oidc/java/params_forwarding.adoc[]
|
||||
include::topics/oidc/java/client-authentication.adoc[]
|
||||
include::topics/oidc/java/multi-tenancy.adoc[]
|
||||
include::topics/oidc/java/application-clustering.adoc[]
|
||||
|
||||
include::topics/oidc/javascript-adapter.adoc[]
|
||||
|
||||
include::topics/oidc/nodejs-adapter.adoc[]
|
||||
|
@ -44,9 +24,10 @@ ifeval::[{project_community}==true]
|
|||
include::topics/oidc/mod-auth-openidc.adoc[]
|
||||
endif::[]
|
||||
|
||||
include::topics/oidc/oidc-generic.adoc[]
|
||||
include::topics/oidc/fapi-support.adoc[]
|
||||
|
||||
include::topics/oidc/recommendations.adoc[]
|
||||
|
||||
include::topics/saml/saml-overview.adoc[]
|
||||
include::topics/saml/java/java-adapters.adoc[]
|
||||
include::topics/saml/java/general-config.adoc[]
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
=== Available Endpoints
|
||||
|
||||
As a fully-compliant OpenID Connect Provider implementation, {project_name} exposes a set of endpoints that applications
|
||||
and services can use to authenticate and authorize their users.
|
||||
|
||||
This section describes some of the key endpoints that your application and service should be use when
|
||||
interacting with {project_name}.
|
||||
|
||||
==== Endpoints
|
||||
|
||||
The most important endpoint to understand is the `well-known` configuration endpoint. It lists endpoints and other configuration options relevant to the OpenID Connect implementation in {project_name}. The endpoint is:
|
||||
|
||||
....
|
||||
/realms/{realm-name}/.well-known/openid-configuration
|
||||
....
|
||||
|
||||
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{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.
|
||||
|
||||
===== Authorization endpoint
|
||||
....
|
||||
/realms/{realm-name}/protocol/openid-connect/auth
|
||||
....
|
||||
|
||||
The authorization endpoint performs authentication of the end-user. This authentication is done by redirecting the user agent to this endpoint.
|
||||
|
||||
For more details see the https://openid.net/specs/openid-connect-core-1_0.html#AuthorizationEndpoint[Authorization Endpoint] section in the OpenID Connect specification.
|
||||
|
||||
===== Token endpoint
|
||||
....
|
||||
/realms/{realm-name}/protocol/openid-connect/token
|
||||
....
|
||||
|
||||
The token endpoint is used to obtain tokens. Tokens can either be obtained by exchanging an authorization code or by supplying credentials directly depending on what flow is used.
|
||||
The token endpoint is also used to obtain new access tokens when they expire.
|
||||
|
||||
For more details, see the https://openid.net/specs/openid-connect-core-1_0.html#TokenEndpoint[Token Endpoint] section in the OpenID Connect specification.
|
||||
|
||||
===== Userinfo endpoint
|
||||
....
|
||||
/realms/{realm-name}/protocol/openid-connect/userinfo
|
||||
....
|
||||
|
||||
The userinfo endpoint returns standard claims about the authenticated user; this endpoint is protected by a bearer token.
|
||||
|
||||
For more details, see the https://openid.net/specs/openid-connect-core-1_0.html#UserInfo[Userinfo Endpoint] section in the OpenID Connect specification.
|
||||
|
||||
===== Logout endpoint
|
||||
....
|
||||
/realms/{realm-name}/protocol/openid-connect/logout
|
||||
....
|
||||
|
||||
The logout endpoint logs out the authenticated user.
|
||||
|
||||
The user agent can be redirected to the endpoint, which causes the active user session to be logged out. The user agent is then redirected back to the application.
|
||||
|
||||
The endpoint can also be invoked directly by the application. To invoke this endpoint directly, the refresh token needs to be included as well as the credentials required to authenticate the client.
|
||||
|
||||
[[_certificate_endpoint]]
|
||||
===== Certificate endpoint
|
||||
....
|
||||
/realms/{realm-name}/protocol/openid-connect/certs
|
||||
....
|
||||
|
||||
The certificate endpoint returns the public keys enabled by the realm, encoded as a JSON Web Key (JWK). Depending on the realm settings, one or more keys can be enabled for verifying tokens. For more information, see the link:{adminguide_link}[{adminguide_name}] and the https://datatracker.ietf.org/doc/html/rfc7517[JSON Web Key specification].
|
||||
|
||||
[[_token_introspection_endpoint]]
|
||||
===== Introspection endpoint
|
||||
....
|
||||
/realms/{realm-name}/protocol/openid-connect/token/introspect
|
||||
....
|
||||
|
||||
The introspection endpoint is used to retrieve the active state of a token. In other words, you can use it to validate an access or refresh token.
|
||||
This endpoint can only be invoked by confidential clients.
|
||||
|
||||
For more details on how to invoke on this endpoint, see https://datatracker.ietf.org/doc/html/rfc7662[OAuth 2.0 Token Introspection specification].
|
||||
|
||||
===== Dynamic Client Registration endpoint
|
||||
....
|
||||
/realms/{realm-name}/clients-registrations/openid-connect
|
||||
....
|
||||
|
||||
The dynamic client registration endpoint is used to dynamically register clients.
|
||||
|
||||
For more details, see the <<_client_registration,Client Registration chapter>> and the
|
||||
https://openid.net/specs/openid-connect-registration-1_0.html[OpenID Connect Dynamic Client Registration specification].
|
||||
|
||||
[[_token_revocation_endpoint]]
|
||||
===== Token Revocation endpoint
|
||||
....
|
||||
/realms/{realm-name}/protocol/openid-connect/revoke
|
||||
....
|
||||
|
||||
The token revocation endpoint is used to revoke tokens. Both refresh tokens and access tokens are supported by this endpoint. When revoking a refresh token, the user consent for the corresponding client is also revoked.
|
||||
|
||||
For more details on how to invoke on this endpoint, see https://datatracker.ietf.org/doc/html/rfc7009[OAuth 2.0 Token Revocation specification].
|
||||
|
||||
===== Device Authorization endpoint
|
||||
....
|
||||
/realms/{realm-name}/protocol/openid-connect/auth/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.
|
||||
|
||||
For more details on how to invoke on this endpoint, see https://datatracker.ietf.org/doc/html/rfc8628[OAuth 2.0 Device Authorization Grant specification].
|
||||
|
||||
[[_backchannel_authentication_endpoint]]
|
||||
===== Backchannel Authentication endpoint
|
||||
....
|
||||
/realms/{realm-name}/protocol/openid-connect/ext/ciba/auth
|
||||
....
|
||||
|
||||
The backchannel authentication endpoint is used to obtain an auth_req_id that identifies the authentication request made by the client. It can only be invoked by confidential clients.
|
||||
|
||||
For more details on how to invoke on this endpoint, see https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html[OpenID Connect Client Initiated Backchannel Authentication Flow specification].
|
||||
|
||||
Also refer to other places of {project_name} documentation like <<_client_initiated_backchannel_authentication_grant,Client Initiated Backchannel Authentication Grant section of this guide>> and link:{adminguide_link}#_client_initiated_backchannel_authentication_grant[Client Initiated Backchannel Authentication Grant section] of {adminguide_name}.
|
|
@ -0,0 +1,5 @@
|
|||
[WARNING]
|
||||
====
|
||||
This adapter is deprecated and will be removed in a future release of Keycloak. No further enhancements or new features
|
||||
will be added to this adapter.
|
||||
====
|
|
@ -1,6 +1,8 @@
|
|||
[[_jaas_adapter]]
|
||||
==== JAAS plugin
|
||||
|
||||
include::adapter-deprecation-notice.adoc[]
|
||||
|
||||
It's generally not needed to use JAAS for most of the applications, especially if they are HTTP based, and you should most likely choose one of our other adapters.
|
||||
However, some applications and systems may still rely on pure legacy JAAS solution.
|
||||
{project_name} provides two login modules to help in these situations.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
[[_java_adapter_config]]
|
||||
==== Java adapter configuration
|
||||
==== Configuration
|
||||
|
||||
Each Java adapter supported by {project_name} can be configured by a simple JSON file.
|
||||
This is what one might look like:
|
||||
|
|
|
@ -1,13 +1,45 @@
|
|||
=== Java adapters
|
||||
=== {project_name} Java adapters
|
||||
|
||||
ifeval::[{project_community}==true]
|
||||
[WARNING]
|
||||
====
|
||||
{project_name} Java Adapters are now deprecated and will be removed in a future release. No further enhancements or features will be added to the adapters until then.
|
||||
|
||||
WARNING: {project_name} OpenID Connect java adapters are deprecated and may not work with the most recent versions of the particular servers or frameworks. We encourage
|
||||
you to migrate to different OIDC adapters usually provided by the particular server/framework or any other party. In case your application is on WildFly/EAP, the
|
||||
recommended alternative is Elytron OIDC client.
|
||||
|
||||
endif::[]
|
||||
For more details about how to integrate {project_name} with Java applications, consider looking at the
|
||||
{quickstartRepo_link}[Keycloak Quickstart GitHub Repository].
|
||||
====
|
||||
|
||||
{project_name} comes with a range of different adapters for Java application. Selecting the correct adapter depends on the target platform.
|
||||
|
||||
All Java adapters share a set of common configuration options described in the <<_java_adapter_config,Java Adapters Config>> chapter.
|
||||
All Java adapters share a set of common configuration options described in the <<_java_adapter_config,Java Adapters Config>> chapter.
|
||||
|
||||
ifeval::[{project_community}==true]
|
||||
include::java-adapter-config.adoc[]
|
||||
endif::[]
|
||||
include::jboss-adapter.adoc[]
|
||||
|
||||
include::spring-boot-adapter.adoc[]
|
||||
|
||||
ifeval::[{project_community}==true]
|
||||
include::tomcat-adapter.adoc[]
|
||||
include::jetty9-adapter.adoc[]
|
||||
include::spring-security-adapter.adoc[]
|
||||
endif::[]
|
||||
|
||||
ifeval::[{project_community}==true]
|
||||
include::servlet-filter-adapter.adoc[]
|
||||
endif::[]
|
||||
|
||||
ifeval::[{project_community}==true]
|
||||
include::jaas.adoc[]
|
||||
include::installed-adapter.adoc[]
|
||||
endif::[]
|
||||
|
||||
ifeval::[{project_community}==true]
|
||||
include::adapter-context.adoc[]
|
||||
include::adapter_error_handling.adoc[]
|
||||
include::logout.adoc[]
|
||||
include::params_forwarding.adoc[]
|
||||
include::client-authentication.adoc[]
|
||||
include::multi-tenancy.adoc[]
|
||||
include::application-clustering.adoc[]
|
||||
endif::[]
|
||||
|
|
|
@ -1,95 +0,0 @@
|
|||
[id="jboss7_adapter_rpm"]
|
||||
===== Installing JBoss EAP 7 adapters from an RPM
|
||||
|
||||
NOTE: With Red Hat Enterprise Linux 7, the term channel was replaced with the term repository. In these instructions only the term repository is used.
|
||||
|
||||
.Prerequisites
|
||||
|
||||
You must subscribe to the {appserver_name} {appserver_version} repository before you can install the {appserver_name} 7 adapters from an RPM.
|
||||
|
||||
* Ensure that your Red Hat Enterprise Linux system is registered to your account using Red Hat Subscription Manager. For more information see the link:https://access.redhat.com/documentation/en-us/red_hat_subscription_management/2022[Red Hat Subscription Management documentation].
|
||||
|
||||
* If you are already subscribed to another JBoss EAP repository, you must unsubscribe from that repository first.
|
||||
+
|
||||
For Red Hat Enterprise Linux 6, 7: Using Red Hat Subscription Manager, subscribe to the {appserver_name} {appserver_version} repository using the following command. Replace <RHEL_VERSION> with either 6 or 7 depending on your Red Hat Enterprise Linux version.
|
||||
+
|
||||
[source,bash,subs="attributes+"]
|
||||
----
|
||||
$ sudo subscription-manager repos --enable=jb-eap-7-for-rhel-<RHEL_VERSION>-server-rpms
|
||||
----
|
||||
+
|
||||
For Red Hat Enterprise Linux 8: Using Red Hat Subscription Manager, subscribe to the {appserver_name} {appserver_version} repository using the following command:
|
||||
+
|
||||
[source,bash,subs="attributes+"]
|
||||
----
|
||||
$ sudo subscription-manager repos --enable=jb-eap-{appserver_version}-for-rhel-8-x86_64-rpms --enable=rhel-8-for-x86_64-baseos-rpms --enable=rhel-8-for-x86_64-appstream-rpms
|
||||
----
|
||||
|
||||
.Procedure
|
||||
|
||||
. Install the {appserver_name} 7 adapters for OIDC based on your version of Red Hat Enterprise Linux.
|
||||
|
||||
* Install on Red Hat Enterprise Linux 6, 7:
|
||||
+
|
||||
[source,bash,subs="attributes+"]
|
||||
----
|
||||
$ sudo yum install eap7-keycloak-adapter-sso7_6
|
||||
----
|
||||
|
||||
* Install on Red Hat Enterprise Linux 8:
|
||||
+
|
||||
[source,bash,subs="attributes+"]
|
||||
----
|
||||
$ sudo dnf install eap7-keycloak-adapter-sso7_6
|
||||
----
|
||||
+
|
||||
NOTE: The default EAP_HOME path for the RPM installation is /opt/rh/eap7/root/usr/share/wildfly.
|
||||
|
||||
. Run the installation script for the OIDC module.
|
||||
+
|
||||
[source,bash,subs="attributes+"]
|
||||
----
|
||||
$ $EAP_HOME/bin/jboss-cli.sh -c --file=$EAP_HOME/bin/adapter-install.cli
|
||||
----
|
||||
|
||||
Your installation is complete.
|
||||
|
||||
[id="jboss6_adapter_rpm"]
|
||||
===== Installing JBoss EAP 6 adapters from an RPM
|
||||
|
||||
NOTE: With Red Hat Enterprise Linux 7, the term channel was replaced with the term repository. In these instructions only the term repository is used.
|
||||
|
||||
You must subscribe to the JBoss EAP 6 repository before you can install the EAP 6 adapters from an RPM.
|
||||
|
||||
.Prerequisites
|
||||
|
||||
* Ensure that your Red Hat Enterprise Linux system is registered to your account using Red Hat Subscription Manager. For more information see the link:https://access.redhat.com/documentation/en-us/red_hat_subscription_management/2022[Red Hat Subscription Management documentation].
|
||||
|
||||
* If you are already subscribed to another JBoss EAP repository, you must unsubscribe from that repository first.
|
||||
+
|
||||
Using Red Hat Subscription Manager, subscribe to the JBoss EAP 6 repository using the following command. Replace <RHEL_VERSION> with either 6 or 7 depending on your Red Hat Enterprise Linux version.
|
||||
+
|
||||
[source,bash,subs="attributes+"]
|
||||
----
|
||||
$ sudo subscription-manager repos --enable=jb-eap-6-for-rhel-<RHEL_VERSION>-server-rpms
|
||||
----
|
||||
|
||||
.Procedure
|
||||
|
||||
. Install the EAP 6 adapters for OIDC using the following command:
|
||||
+
|
||||
[source,bash,subs="attributes+"]
|
||||
----
|
||||
$ sudo yum install keycloak-adapter-sso7_6-eap6
|
||||
----
|
||||
+
|
||||
NOTE: The default EAP_HOME path for the RPM installation is /opt/rh/eap6/root/usr/share/wildfly.
|
||||
|
||||
. Run the installation script for the OIDC module.
|
||||
+
|
||||
[source,bash,subs="attributes+"]
|
||||
----
|
||||
$ $EAP_HOME/bin/jboss-cli.sh -c --file=$EAP_HOME/bin/adapter-install.cli
|
||||
----
|
||||
|
||||
Your installation is complete.
|
|
@ -18,9 +18,17 @@ endif::[]
|
|||
|
||||
ifeval::[{project_community}==true]
|
||||
|
||||
WARNING: We do not regularly test and maintain WildFly/EAP adapters. They may work only with WildFly version 23 or earlier or with JBoss EAP 7. Also note
|
||||
that they may work only with JEE applications, but not with Jakarta applications. We recommend that you switch to Elytron OIDC Java adapter to
|
||||
secure your applications. This adapter has a similar configuration to Keycloak Java adapters and migrating your applications to it should be smooth.
|
||||
[WARNING]
|
||||
====
|
||||
This adapter is deprecated and will be removed in a future release of Keycloak. No further enhancements or new features
|
||||
will be added to this adapter.
|
||||
|
||||
We recommend that you switch to the Elytron OIDC library to secure your applications.
|
||||
This library has a similar configuration to the Keycloak WildFly adapters, so you can expect a smooth migration of your applications.
|
||||
|
||||
For more details about how to integrate {project_name} with JakartaEE applications running on latest Wildfly/EAP, consider looking at the
|
||||
{quickstartRepo_link}[Keycloak Quickstart GitHub Repository].
|
||||
====
|
||||
|
||||
To be able to secure WAR apps deployed on JBoss EAP, WildFly or JBoss AS, you must install and configure the
|
||||
{project_name} adapter subsystem. You then have two options to secure your WARs.
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
[[_jetty9_adapter]]
|
||||
==== Jetty 9.4 adapter
|
||||
|
||||
include::adapter-deprecation-notice.adoc[]
|
||||
|
||||
Keycloak has a separate adapter for Jetty 9.4 that you will have to install into your Jetty installation.
|
||||
You then have to provide some extra configuration in each WAR you deploy to Jetty.
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
[[_servlet_filter_adapter]]
|
||||
==== Java servlet filter adapter
|
||||
|
||||
include::adapter-deprecation-notice.adoc[]
|
||||
|
||||
If you are deploying your Java Servlet application on a platform where there is no {project_name} adapter you opt to use the servlet filter adapter.
|
||||
This adapter works a bit differently than the other adapters. You do not define security constraints in web.xml.
|
||||
Instead you define a filter mapping using the {project_name} servlet filter adapter to secure the url patterns you want to secure.
|
||||
|
|
|
@ -1,12 +1,16 @@
|
|||
[[_spring_boot_adapter]]
|
||||
==== Spring Boot adapter
|
||||
|
||||
ifeval::[{project_product}==true]
|
||||
[WARNING]
|
||||
====
|
||||
[NOTE]
|
||||
The Spring Boot Adapter is deprecated and will not be included in the 8.0 and higher versions of RH-SSO. This adapter will be maintained during the lifecycle of RH-SSO 7.x. Users are urged to migrate to Spring Security to integrate their Spring Boot applications with RH-SSO.
|
||||
This adapter is deprecated and will be removed in a future release of Keycloak. No further enhancements or new features
|
||||
will be added to this adapter.
|
||||
|
||||
We recommend that you leverage the OAuth2/OpenID Connect support from Spring Security.
|
||||
|
||||
For more details about how to integrate {project_name} with Spring Boot applications, consider looking at the
|
||||
{quickstartRepo_link}[Keycloak Quickstart GitHub Repository].
|
||||
====
|
||||
endif::[]
|
||||
|
||||
|
||||
[[_spring_boot_adapter_installation]]
|
||||
|
|
|
@ -2,6 +2,17 @@
|
|||
[[_spring_security_adapter]]
|
||||
==== Spring Security adapter
|
||||
|
||||
[WARNING]
|
||||
====
|
||||
This adapter is deprecated and will be removed in a future release of Keycloak. No further enhancements or new features
|
||||
will be added to this adapter.
|
||||
|
||||
We recommend that you leverage the OAuth2/OpenID Connect support from Spring Security.
|
||||
|
||||
For more details about how to integrate {project_name} with Spring Boot applications, consider looking at the
|
||||
{quickstartRepo_link}[Keycloak Quickstart GitHub Repository].
|
||||
====
|
||||
|
||||
To secure an application with Spring Security and Keycloak, add this adapter as a dependency to your project.
|
||||
You then have to provide some extra beans in your Spring Security configuration file and add the Keycloak security filter to your pipeline.
|
||||
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
[[_tomcat_adapter]]
|
||||
==== Tomcat 8 and 9 adapters
|
||||
|
||||
include::adapter-deprecation-notice.adoc[]
|
||||
|
||||
To be able to secure WAR apps deployed on Tomcat 8, and 9, you install the Keycloak Tomcat adapter into your Tomcat installation. You then perform extra configuration to secure each WAR you deploy to Tomcat.
|
||||
|
||||
[[_tomcat_adapter_installation]]
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
[[_javascript_adapter]]
|
||||
=== JavaScript adapter
|
||||
=== {project_name} JavaScript adapter
|
||||
|
||||
{project_name} comes with a client-side JavaScript library called `keycloak-js` that can be used to secure web applications. The adapter also comes with built-in support for Cordova applications.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
[[_nodejs_adapter]]
|
||||
=== Node.js adapter
|
||||
=== {project_name} Node.js adapter
|
||||
|
||||
{project_name} provides a Node.js adapter built on top of https://github.com/senchalabs/connect[Connect] to protect server-side JavaScript apps - the goal was to be flexible enough to integrate with frameworks like https://expressjs.com/[Express.js].
|
||||
|
||||
|
|
|
@ -1,257 +0,0 @@
|
|||
=== Other OpenID Connect libraries
|
||||
|
||||
{project_name} can be secured by supplied adapters that are usually easier to use and provide better integration with {project_name}. However, if an adapter is not available for your programming language, framework, or platform you might opt to use a generic OpenID Connect Relying Party (RP) library instead. This chapter describes details specific to {project_name} and does not contain specific protocol details. For more information see the https://openid.net/developers/how-connect-works/[OpenID Connect specifications] and https://datatracker.ietf.org/doc/html/rfc6749[OAuth2 specification].
|
||||
|
||||
==== Endpoints
|
||||
|
||||
The most important endpoint to understand is the `well-known` configuration endpoint. It lists endpoints and other configuration options relevant to the OpenID Connect implementation in {project_name}. The endpoint is:
|
||||
|
||||
....
|
||||
/realms/{realm-name}/.well-known/openid-configuration
|
||||
....
|
||||
|
||||
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{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.
|
||||
|
||||
===== Authorization endpoint
|
||||
....
|
||||
/realms/{realm-name}/protocol/openid-connect/auth
|
||||
....
|
||||
|
||||
The authorization endpoint performs authentication of the end-user. This is done by redirecting the user agent to this endpoint.
|
||||
|
||||
For more details see the https://openid.net/specs/openid-connect-core-1_0.html#AuthorizationEndpoint[Authorization Endpoint] section in the OpenID Connect specification.
|
||||
|
||||
===== Token endpoint
|
||||
....
|
||||
/realms/{realm-name}/protocol/openid-connect/token
|
||||
....
|
||||
|
||||
The token endpoint is used to obtain tokens. Tokens can either be obtained by exchanging an authorization code or by supplying credentials directly depending on what flow is used.
|
||||
The token endpoint is also used to obtain new access tokens when they expire.
|
||||
|
||||
For more details see the https://openid.net/specs/openid-connect-core-1_0.html#TokenEndpoint[Token Endpoint] section in the OpenID Connect specification.
|
||||
|
||||
===== Userinfo endpoint
|
||||
....
|
||||
/realms/{realm-name}/protocol/openid-connect/userinfo
|
||||
....
|
||||
|
||||
The userinfo endpoint returns standard claims about the authenticated user, and is protected by a bearer token.
|
||||
|
||||
For more details see the https://openid.net/specs/openid-connect-core-1_0.html#UserInfo[Userinfo Endpoint] section in the OpenID Connect specification.
|
||||
|
||||
===== Logout endpoint
|
||||
....
|
||||
/realms/{realm-name}/protocol/openid-connect/logout
|
||||
....
|
||||
|
||||
The logout endpoint logs out the authenticated user.
|
||||
|
||||
The user agent can be redirected to the endpoint, in which case the active user session is logged out. Afterward the user agent is redirected back to the application.
|
||||
|
||||
The endpoint can also be invoked directly by the application. To invoke this endpoint directly the refresh token needs to be included as well as the credentials required to authenticate the client.
|
||||
|
||||
[[_certificate_endpoint]]
|
||||
===== Certificate endpoint
|
||||
....
|
||||
/realms/{realm-name}/protocol/openid-connect/certs
|
||||
....
|
||||
|
||||
The certificate endpoint returns the public keys enabled by the realm, encoded as a JSON Web Key (JWK). Depending on the realm settings there can be one or more keys enabled for verifying tokens. For more information see the link:{adminguide_link}[{adminguide_name}] and the https://datatracker.ietf.org/doc/html/rfc7517[JSON Web Key specification].
|
||||
|
||||
[[_token_introspection_endpoint]]
|
||||
===== Introspection endpoint
|
||||
....
|
||||
/realms/{realm-name}/protocol/openid-connect/token/introspect
|
||||
....
|
||||
|
||||
The introspection endpoint is used to retrieve the active state of a token. In other words, you can use it to validate an access or refresh token.
|
||||
It can only be invoked by confidential clients.
|
||||
|
||||
For more details on how to invoke on this endpoint, see https://datatracker.ietf.org/doc/html/rfc7662[OAuth 2.0 Token Introspection specification].
|
||||
|
||||
===== Dynamic Client Registration endpoint
|
||||
....
|
||||
/realms/{realm-name}/clients-registrations/openid-connect
|
||||
....
|
||||
|
||||
The dynamic client registration endpoint is used to dynamically register clients.
|
||||
|
||||
For more details see the <<_client_registration,Client Registration chapter>> and the
|
||||
https://openid.net/specs/openid-connect-registration-1_0.html[OpenID Connect Dynamic Client Registration specification].
|
||||
|
||||
[[_token_revocation_endpoint]]
|
||||
===== Token Revocation endpoint
|
||||
....
|
||||
/realms/{realm-name}/protocol/openid-connect/revoke
|
||||
....
|
||||
|
||||
The token revocation endpoint is used to revoke tokens. Both refresh tokens and access tokens are supported by this endpoint. When revoking a refresh token the user consent for the corresponding client is also revoked.
|
||||
|
||||
For more details on how to invoke on this endpoint, see https://datatracker.ietf.org/doc/html/rfc7009[OAuth 2.0 Token Revocation specification].
|
||||
|
||||
===== Device Authorization endpoint
|
||||
....
|
||||
/realms/{realm-name}/protocol/openid-connect/auth/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.
|
||||
|
||||
For more details on how to invoke on this endpoint, see https://datatracker.ietf.org/doc/html/rfc8628[OAuth 2.0 Device Authorization Grant specification].
|
||||
|
||||
[[_backchannel_authentication_endpoint]]
|
||||
===== Backchannel Authentication endpoint
|
||||
....
|
||||
/realms/{realm-name}/protocol/openid-connect/ext/ciba/auth
|
||||
....
|
||||
|
||||
The backchannel authentication endpoint is used to obtain an auth_req_id that identifies the authentication request made by the client. It can only be invoked by confidential clients.
|
||||
|
||||
For more details on how to invoke on this endpoint, see https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html[OpenID Connect Client Initiated Backchannel Authentication Flow specification].
|
||||
|
||||
Also please refer to other places of {project_name} documentation like <<_client_initiated_backchannel_authentication_grant,Client Initiated Backchannel Authentication Grant section of this guide>> and link:{adminguide_link}#_client_initiated_backchannel_authentication_grant[Client Initiated Backchannel Authentication Grant section] of {adminguide_name}.
|
||||
|
||||
==== Validating access tokens
|
||||
|
||||
If you need to manually validate access tokens issued by {project_name} you can invoke the <<_token_introspection_endpoint,Introspection Endpoint>>.
|
||||
The downside to this approach is that you have to make a network invocation to the {project_name} server. This can be slow and possibly overload the
|
||||
server if you have too many validation requests going on at the same time. {project_name} issued access tokens are https://datatracker.ietf.org/doc/html/rfc7519[JSON Web Tokens (JWT)] digitally signed and encoded using https://datatracker.ietf.org/doc/html/rfc7515[JSON Web Signature (JWS)].
|
||||
Because they are encoded in this way, this allows you to locally validate access tokens using the public key of the issuing realm. You can either hard code the
|
||||
realm's public key in your validation code, or lookup and cache the public key using the <<_certificate_endpoint, certificate endpoint>> with the Key ID (KID) embedded within the
|
||||
JWS. Depending on what language you code in, there are a multitude of third party libraries out there that can help you with JWS validation.
|
||||
|
||||
|
||||
==== Flows
|
||||
|
||||
===== Authorization code
|
||||
|
||||
The Authorization Code flow redirects the user agent to {project_name}. Once the user has successfully authenticated with {project_name} an
|
||||
Authorization Code is created and the user agent is redirected back to the application. The application then uses the authorization code along with its
|
||||
credentials to obtain an Access Token, Refresh Token and ID Token from {project_name}.
|
||||
|
||||
The flow is targeted towards web applications, but is also recommended for native applications, including mobile applications, where it is possible to embed
|
||||
a user agent.
|
||||
|
||||
For more details refer to the https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth[Authorization Code Flow] in the OpenID Connect specification.
|
||||
|
||||
===== Implicit
|
||||
|
||||
The Implicit flow redirects works similarly to the Authorization Code flow, but instead of returning an Authorization Code the Access Token and ID Token is
|
||||
returned. This reduces the need for the extra invocation to exchange the Authorization Code for an Access Token. However, it does not include a Refresh
|
||||
Token. This results in the need to either permit Access Tokens with a long expiration, which is problematic as it's very hard to invalidate these. Or
|
||||
requires a new redirect to obtain new Access Token once the initial Access Token has expired. The Implicit flow is useful if the application only wants to
|
||||
authenticate the user and deals with logout itself.
|
||||
|
||||
There's also a Hybrid flow where both the Access Token and an Authorization Code is returned.
|
||||
|
||||
One thing to note is that both the Implicit flow and Hybrid flow has potential security risks as the Access Token may be leaked through web server logs and
|
||||
browser history. This is somewhat mitigated by using short expiration for Access Tokens.
|
||||
|
||||
For more details refer to the https://openid.net/specs/openid-connect-core-1_0.html#ImplicitFlowAuth[Implicit Flow] in the OpenID Connect specification.
|
||||
|
||||
[[_resource_owner_password_credentials_flow]]
|
||||
===== Resource Owner Password Credentials
|
||||
|
||||
Resource Owner Password Credentials, referred to as Direct Grant in {project_name}, allows exchanging user credentials for tokens. It's not recommended
|
||||
to use this flow unless you absolutely need to. Examples where this could be useful are legacy applications and command-line interfaces.
|
||||
|
||||
There are a number of limitations of using this flow, including:
|
||||
|
||||
* User credentials are exposed to the application
|
||||
* Applications need login pages
|
||||
* Application needs to be aware of the authentication scheme
|
||||
* Changes to authentication flow requires changes to application
|
||||
* No support for identity brokering or social login
|
||||
* Flows are not supported (user self-registration, required actions, etc.)
|
||||
|
||||
For a client to be permitted to use the Resource Owner Password Credentials grant the client has to have the `Direct Access Grants Enabled` option enabled.
|
||||
|
||||
This flow is not included in OpenID Connect, but is a part of the OAuth 2.0 specification.
|
||||
|
||||
For more details refer to the https://datatracker.ietf.org/doc/html/rfc6749#section-4.3[Resource Owner Password Credentials Grant] chapter in the OAuth 2.0 specification.
|
||||
|
||||
====== Example using CURL
|
||||
|
||||
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`:
|
||||
|
||||
[source,bash,subs="attributes+"]
|
||||
----
|
||||
curl \
|
||||
-d "client_id=myclient" \
|
||||
-d "client_secret=40cc097b-2a57-4c17-b36a-8fdf3fc2d578" \
|
||||
-d "username=user" \
|
||||
-d "password=password" \
|
||||
-d "grant_type=password" \
|
||||
"http://localhost:8080{kc_realms_path}/master/protocol/openid-connect/token"
|
||||
----
|
||||
|
||||
===== Client credentials
|
||||
|
||||
Client Credentials is used when clients (applications and services) wants to obtain access on behalf of themselves rather than on behalf of a user. This can
|
||||
for example be useful for background services that applies changes to the system in general rather than for a specific user.
|
||||
|
||||
{project_name} provides support for clients to authenticate either with a secret or with public/private keys.
|
||||
|
||||
This flow is not included in OpenID Connect, but is a part of the OAuth 2.0 specification.
|
||||
|
||||
For more details refer to the https://datatracker.ietf.org/doc/html/rfc6749#section-4.4[Client Credentials Grant] chapter in the OAuth 2.0 specification.
|
||||
|
||||
===== Device Authorization Grant
|
||||
|
||||
Device Authorization Grant is used by clients running on internet-connected devices that have limited input capabilities or lack a suitable browser.
|
||||
The application requests {project_name} a device code and a user code. {project_name} creates a device code and a user code.
|
||||
{project_name} returns a response including the device code and the user code to the application.
|
||||
Then the application provides the user with the user code and the verification URI. The user accesses a verification URI to be authenticated by using another browser.
|
||||
The application repeatedly polls {project_name} until {project_name} completes the user authorization.
|
||||
If user authentication is complete, the application obtains the device code. Then the application uses the device code along with its credentials to obtain an Access Token, Refresh Token and ID Token from {project_name}.
|
||||
|
||||
For more details refer to the https://datatracker.ietf.org/doc/html/rfc8628[OAuth 2.0 Device Authorization Grant specification].
|
||||
|
||||
[[_client_initiated_backchannel_authentication_grant]]
|
||||
===== Client Initiated Backchannel Authentication Grant
|
||||
|
||||
Client Initiated Backchannel Authentication Grant is used by clients who want to initiate the authentication flow by communicating with the OpenID Provider directly without redirect through the user's browser like OAuth 2.0's authorization code grant.
|
||||
|
||||
The client requests {project_name} an auth_req_id that identifies the authentication request made by the client. {project_name} creates the auth_req_id.
|
||||
|
||||
After receiving this auth_req_id, this client repeatedly needs to poll {project_name} to obtain an Access Token, Refresh Token and ID Token from {project_name} in return for the auth_req_id until the user is authenticated.
|
||||
|
||||
In case that client uses `ping` mode, it does not need to repeatedly poll the token endpoint, but it can wait for the notification sent by {project_name} to the specified Client Notification Endpoint.
|
||||
The Client Notification Endpoint can be configured in the {project_name} Admin Console. The details of the contract for Client Notification Endpoint are described in the CIBA specification.
|
||||
|
||||
For more details refer to https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html[OpenID Connect Client Initiated Backchannel Authentication Flow specification].
|
||||
|
||||
Also please refer to other places of {project_name} documentation like <<_backchannel_authentication_endpoint,Backchannel Authentication Endpoint of this guide>> and link:{adminguide_link}#_client_initiated_backchannel_authentication_grant[Client Initiated Backchannel Authentication Grant section] of {adminguide_name}.
|
||||
For the details about FAPI CIBA compliance, please refer to the <<_fapi-support,FAPI section of this guide>>.
|
||||
|
||||
==== Redirect URIs
|
||||
|
||||
When using the redirect based flows it's important to use valid redirect uris for your clients. The redirect uris should be as specific as possible. This
|
||||
especially applies to client-side (public clients) applications. Failing to do so could result in:
|
||||
|
||||
* Open redirects - this can allow attackers to create spoof links that looks like they are coming from your domain
|
||||
* Unauthorized entry - when users are already authenticated with {project_name} an attacker can use a public client where redirect uris have not be configured correctly to gain access by redirecting the user without the users knowledge
|
||||
|
||||
In production for web applications always use `https` for all redirect URIs. Do not allow redirects to http.
|
||||
|
||||
There's also a few special redirect URIs:
|
||||
|
||||
[[_installed_applications_url]]
|
||||
`$$http://127.0.0.1$$`::
|
||||
|
||||
This redirect URI is useful for native applications and allows the native application to create a web server on a random port that can be used to obtain the
|
||||
authorization code. This redirect uri allows any port. Note that per https://datatracker.ietf.org/doc/html/rfc8252#section-8.3[OAuth 2.0 for Native Apps] the use of
|
||||
`localhost` is *not* recommended and the IP literal `127.0.0.1` should be used instead.
|
||||
|
||||
[[_installed_applications_urn]]
|
||||
`urn:ietf:wg:oauth:2.0:oob`::
|
||||
|
||||
If its not possible to start a web server in the client (or a browser is not available) it is possible to use the special `urn:ietf:wg:oauth:2.0:oob` redirect uri.
|
||||
When this redirect uri is used {project_name} displays a page with the code in the title and in a box on the page.
|
||||
The application can either detect that the browser title has changed, or the user can copy/paste the code manually to the application.
|
||||
With this redirect uri it is also possible for a user to use a different device to obtain a code to paste back to the application.
|
|
@ -1,5 +1,4 @@
|
|||
[[_oidc]]
|
||||
== Using OpenID Connect to secure applications and services
|
||||
|
||||
This section describes how you can secure applications and services with OpenID Connect using either {project_name} adapters or generic OpenID Connect
|
||||
Relying Party libraries.
|
||||
This section describes how you can secure applications and services with OpenID Connect using {project_name}.
|
|
@ -0,0 +1,39 @@
|
|||
=== Recommendations
|
||||
|
||||
This section describes some recommendations when securing your applications with {project_name}.
|
||||
|
||||
==== Validating access tokens
|
||||
|
||||
If you need to manually validate access tokens issued by {project_name}, you can invoke the <<_token_introspection_endpoint,Introspection Endpoint>>.
|
||||
The downside to this approach is that you have to make a network invocation to the {project_name} server. This can be slow and possibly overload the
|
||||
server if you have too many validation requests going on at the same time. {project_name} issued access tokens are https://datatracker.ietf.org/doc/html/rfc7519[JSON Web Tokens (JWT)] digitally signed and encoded using https://datatracker.ietf.org/doc/html/rfc7515[JSON Web Signature (JWS)].
|
||||
Because they are encoded in this way, you can locally validate access tokens using the public key of the issuing realm. You can either hard code the
|
||||
realm's public key in your validation code, or lookup and cache the public key using the <<_certificate_endpoint, certificate endpoint>> with the Key ID (KID) embedded within the
|
||||
JWS. Depending on what language you code in, many third party libraries exist and they can help you with JWS validation.
|
||||
|
||||
==== Redirect URIs
|
||||
|
||||
When using the redirect based flows, be sure to use valid redirect uris for your clients. The redirect uris should be as specific as possible. This
|
||||
especially applies to client-side (public clients) applications. Failing to do so could result in:
|
||||
|
||||
* Open redirects - this can allow attackers to create spoof links that looks like they are coming from your domain
|
||||
* Unauthorized entry - when users are already authenticated with {project_name}, an attacker can use a public client where redirect uris have not be configured correctly to gain access by redirecting the user without the users knowledge
|
||||
|
||||
In production for web applications always use `https` for all redirect URIs. Do not allow redirects to http.
|
||||
|
||||
A few special redirect URIs also exist:
|
||||
|
||||
[[_installed_applications_url]]
|
||||
`$$http://127.0.0.1$$`::
|
||||
|
||||
This redirect URI is useful for native applications and allows the native application to create a web server on a random port that can be used to obtain the
|
||||
authorization code. This redirect uri allows any port. Note that per https://datatracker.ietf.org/doc/html/rfc8252#section-8.3[OAuth 2.0 for Native Apps], the use of
|
||||
`localhost` is *not* recommended and the IP literal `127.0.0.1` should be used instead.
|
||||
|
||||
[[_installed_applications_urn]]
|
||||
`urn:ietf:wg:oauth:2.0:oob`::
|
||||
|
||||
If you cannot start a web server in the client (or a browser is not available), you can use the special `urn:ietf:wg:oauth:2.0:oob` redirect uri.
|
||||
When this redirect uri is used, {project_name} displays a page with the code in the title and in a box on the page.
|
||||
The application can either detect that the browser title has changed, or the user can copy and paste the code manually to the application.
|
||||
With this redirect uri, a user can use a different device to obtain a code to paste back to the application.
|
|
@ -0,0 +1,106 @@
|
|||
=== Supported Grant Types
|
||||
|
||||
This section describes the different grant types available to relaying parties.
|
||||
|
||||
==== Authorization code
|
||||
|
||||
The Authorization Code flow redirects the user agent to {project_name}. Once the user has successfully authenticated with {project_name}, an
|
||||
Authorization Code is created and the user agent is redirected back to the application. The application then uses the authorization code along with its
|
||||
credentials to obtain an Access Token, Refresh Token and ID Token from {project_name}.
|
||||
|
||||
The flow is targeted towards web applications, but is also recommended for native applications, including mobile applications, where it is possible to embed
|
||||
a user agent.
|
||||
|
||||
For more details refer to the https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth[Authorization Code Flow] in the OpenID Connect specification.
|
||||
|
||||
==== Implicit
|
||||
|
||||
The Implicit flow works similarly to the Authorization Code flow, but instead of returning an Authorization Code, the Access Token and ID Token is
|
||||
returned. This approach reduces the need for the extra invocation to exchange the Authorization Code for an Access Token. However, it does not include a Refresh
|
||||
Token. This results in the need to permit Access Tokens with a long expiration; however, that approach is not practical because it is very hard to invalidate these tokens. Alternatively, you can
|
||||
require a new redirect to obtain a new Access Token once the initial Access Token has expired. The Implicit flow is useful if the application only wants to
|
||||
authenticate the user and deals with logout itself.
|
||||
|
||||
You can instead use a Hybrid flow where both the Access Token and an Authorization Code are returned.
|
||||
|
||||
One thing to note is that both the Implicit flow and Hybrid flow have potential security risks as the Access Token may be leaked through web server logs and
|
||||
browser history. You can somewhat mitigate this problem by using short expiration for Access Tokens.
|
||||
|
||||
For more details, see the https://openid.net/specs/openid-connect-core-1_0.html#ImplicitFlowAuth[Implicit Flow] in the OpenID Connect specification.
|
||||
|
||||
[[_resource_owner_password_credentials_flow]]
|
||||
==== Resource Owner Password Credentials
|
||||
|
||||
Resource Owner Password Credentials, referred to as Direct Grant in {project_name}, allows exchanging user credentials for tokens. Using this flow is not recommended unlesss it is essential. Examples where this flow could be useful are legacy applications and command-line interfaces.
|
||||
|
||||
The limitations of using this flow include:
|
||||
|
||||
* User credentials are exposed to the application
|
||||
* Applications need login pages
|
||||
* Application needs to be aware of the authentication scheme
|
||||
* Changes to authentication flow requires changes to application
|
||||
* No support for identity brokering or social login
|
||||
* Flows are not supported (user self-registration, required actions, and so on.)
|
||||
|
||||
For a client to be permitted to use the Resource Owner Password Credentials grant, the client has to have the `Direct Access Grants Enabled` option enabled.
|
||||
|
||||
This flow is not included in OpenID Connect, but is a part of the OAuth 2.0 specification.
|
||||
|
||||
For more details, see the https://datatracker.ietf.org/doc/html/rfc6749#section-4.3[Resource Owner Password Credentials Grant] chapter in the OAuth 2.0 specification.
|
||||
|
||||
===== Example using CURL
|
||||
|
||||
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`:
|
||||
|
||||
[source,bash,subs="attributes+"]
|
||||
----
|
||||
curl \
|
||||
-d "client_id=myclient" \
|
||||
-d "client_secret=40cc097b-2a57-4c17-b36a-8fdf3fc2d578" \
|
||||
-d "username=user" \
|
||||
-d "password=password" \
|
||||
-d "grant_type=password" \
|
||||
"http://localhost:8080{kc_realms_path}/master/protocol/openid-connect/token"
|
||||
----
|
||||
|
||||
==== Client credentials
|
||||
|
||||
Client Credentials are used when clients (applications and services) want to obtain access on behalf of themselves rather than on behalf of a user. For example, these credentials can
|
||||
be useful for background services that apply changes to the system in general rather than for a specific user.
|
||||
|
||||
{project_name} provides support for clients to authenticate either with a secret or with public/private keys.
|
||||
|
||||
This flow is not included in OpenID Connect, but is a part of the OAuth 2.0 specification.
|
||||
|
||||
For more details, see the https://datatracker.ietf.org/doc/html/rfc6749#section-4.4[Client Credentials Grant] chapter in the OAuth 2.0 specification.
|
||||
|
||||
==== Device Authorization Grant
|
||||
|
||||
Device Authorization Grant is used by clients running on internet-connected devices that have limited input capabilities or lack a suitable browser.
|
||||
. The application requests {project_name} a device code and a user code.
|
||||
. {project_name} creates a device code and a user code.
|
||||
. {project_name} returns a response including the device code and the user code to the application.
|
||||
. The application provides the user with the user code and the verification URI. The user accesses a verification URI to be authenticated by using another browser.
|
||||
. The application repeatedly polls {project_name} until {project_name} completes the user authorization.
|
||||
. If user authentication is complete, the application obtains the device code.
|
||||
. The application uses the device code along with its credentials to obtain an Access Token, Refresh Token and ID Token from {project_name}.
|
||||
|
||||
For more details, see the https://datatracker.ietf.org/doc/html/rfc8628[OAuth 2.0 Device Authorization Grant specification].
|
||||
|
||||
[[_client_initiated_backchannel_authentication_grant]]
|
||||
==== Client Initiated Backchannel Authentication Grant
|
||||
|
||||
Client Initiated Backchannel Authentication Grant is used by clients who want to initiate the authentication flow by communicating with the OpenID Provider directly without redirect through the user's browser like OAuth 2.0's authorization code grant.
|
||||
|
||||
The client requests from {project_name} an auth_req_id that identifies the authentication request made by the client. {project_name} creates the auth_req_id.
|
||||
|
||||
After receiving this auth_req_id, this client repeatedly needs to poll {project_name} to obtain an Access Token, Refresh Token, and ID Token from {project_name} in return for the auth_req_id until the user is authenticated.
|
||||
|
||||
In case that client uses `ping` mode, it does not need to repeatedly poll the token endpoint, but it can wait for the notification sent by {project_name} to the specified Client Notification Endpoint.
|
||||
The Client Notification Endpoint can be configured in the {project_name} Admin Console. The details of the contract for Client Notification Endpoint are described in the CIBA specification.
|
||||
|
||||
For more details, see https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html[OpenID Connect Client Initiated Backchannel Authentication Flow specification].
|
||||
|
||||
Also refer to other places of {project_name} documentation such as <<_backchannel_authentication_endpoint,Backchannel Authentication Endpoint of this guide>> and link:{adminguide_link}#_client_initiated_backchannel_authentication_grant[Client Initiated Backchannel Authentication Grant section] of {adminguide_name}.
|
||||
For the details about FAPI CIBA compliance, see the <<_fapi-support,FAPI section of this guide>>.
|
|
@ -2,13 +2,7 @@
|
|||
|
||||
These are the basic steps for securing an application or a service in {project_name}.
|
||||
|
||||
. Configure a client using one of these options:
|
||||
|
||||
* A {project_name} adapter
|
||||
|
||||
* A generic OpenID connect or SAML library
|
||||
|
||||
. Register a client using one of these options:
|
||||
. Register a client to a realm using one of these options:
|
||||
|
||||
* The {project_name} Admin Console
|
||||
|
||||
|
@ -16,9 +10,11 @@ These are the basic steps for securing an application or a service in {project_n
|
|||
|
||||
* The CLI
|
||||
|
||||
[role="_additional-resources"]
|
||||
. Enable OpenID Connect or SAML protocols in your application using one these options:
|
||||
|
||||
.Additional resources
|
||||
|
||||
* This guide provides the detailed instructions for these steps. Related information exists in the link:{adminguide_link}[Server Administration Guide]. That guide provides instructions for using Admin Console to create a client. Creating a client is the same task as registering a client using the {project_name} Client Registration Service.
|
||||
* Leveraging existing OpenID Connect and SAML support from the application ecosystem
|
||||
* Using a {project_name} Adapter
|
||||
|
||||
This guide provides the detailed instructions for these steps. You can find more details
|
||||
in the link:{adminguide_link}[Server Administration Guide] about how to register a client to {project_name} through the
|
||||
administration console.
|
|
@ -0,0 +1,64 @@
|
|||
=== Getting Started
|
||||
|
||||
The link:{quickstartRepo_link}[{quickstartRepo_name}] provides examples about how to secure applications and services
|
||||
using different programming languages and frameworks. By going through their documentation and codebase, you will
|
||||
understand the bare minimum changes required in your application and service in order to secure it with {project_name}.
|
||||
|
||||
Also, see the following sections for recommendations for trusted and well-known client-side implementations for both OpenID
|
||||
Connect and SAML protocols.
|
||||
|
||||
==== OpenID Connect
|
||||
|
||||
===== Java
|
||||
ifeval::[{project_community}==true]
|
||||
* {quickstartRepo_link}/tree/latest/jakarta/servlet-authz-client[Wildfly Elytron OIDC]
|
||||
* {quickstartRepo_link}/tree/latest/spring/rest-authz-resource-server[Spring Boot]
|
||||
* <<_jboss_adapter, {project_name} Wildfly Adapter>> (Deprecated)
|
||||
* <<_tomcat_adapter,{project_name} Tomcat Adapter>> (Deprecated)
|
||||
* <<_jetty9_adapter,{project_name} Jetty 9>> (Deprecated)
|
||||
* <<_servlet_filter_adapter,{project_name} Servlet Filter>> (Deprecated)
|
||||
* <<_spring_boot_adapter,{project_name} Spring Boot>> (Deprecated)
|
||||
* <<_spring_security_adapter,{project_name} Spring Security>> (Deprecated)
|
||||
endif::[]
|
||||
|
||||
===== JavaScript (client-side)
|
||||
* <<_javascript_adapter,JavaScript>>
|
||||
|
||||
===== Node.js (server-side)
|
||||
* <<_nodejs_adapter,Node.js>>
|
||||
|
||||
|
||||
ifeval::[{project_community}==true]
|
||||
===== C#
|
||||
* https://github.com/dylanplecki/KeycloakOwinAuthentication[OWIN]
|
||||
|
||||
===== Python
|
||||
* https://pypi.org/project/oic/[oidc]
|
||||
|
||||
===== Android
|
||||
* https://github.com/openid/AppAuth-Android[AppAuth]
|
||||
|
||||
===== iOS
|
||||
* https://github.com/openid/AppAuth-iOS[AppAuth]
|
||||
|
||||
===== Apache HTTP Server
|
||||
* https://github.com/OpenIDC/mod_auth_openidc[mod_auth_openidc]
|
||||
endif::[]
|
||||
|
||||
==== SAML
|
||||
|
||||
===== Java
|
||||
|
||||
* <<_saml_jboss_adapter,JBoss EAP>>
|
||||
ifeval::[{project_community}==true]
|
||||
* <<_saml_jboss_adapter,WildFly>>
|
||||
* <<_saml-tomcat-adapter,Tomcat>>
|
||||
endif::[]
|
||||
* <<_java-servlet-filter-adapter,Servlet filter>>
|
||||
ifeval::[{project_community}==true]
|
||||
* <<_jetty_saml_adapter,Jetty>>
|
||||
endif::[]
|
||||
|
||||
===== Apache HTTP Server
|
||||
|
||||
* <<_mod_auth_mellon,mod_auth_mellon>>
|
|
@ -1,9 +1,16 @@
|
|||
== Planning for securing applications and services
|
||||
|
||||
{project_name} supports both OpenID Connect (an extension to OAuth 2.0) and SAML 2.0. When securing clients and services the first thing you need to
|
||||
decide is which of the two you are going to use. If you want you can also choose to secure some with OpenID Connect and others with SAML.
|
||||
As an OAuth2, OpenID Connect, and SAML compliant server, {project_name} can secure any application and service as long
|
||||
as the technology stack they are using supports any of these protocols. For more details about the security protocols
|
||||
supported by {project_name}, consider looking at link:{adminguide_link}#sso-protocols[{adminguide_name}].
|
||||
|
||||
To secure clients and services you are also going to need an adapter or library for the protocol you've selected. {project_name} comes with its own
|
||||
adapters for selected platforms, but it is also possible to use generic OpenID Connect Relying Party and SAML Service Provider libraries.
|
||||
Most of the support for some of these protocols is already available from the programming language, framework,
|
||||
or reverse proxy they are using. Leveraging the support already available from the application ecosystem is a key aspect to make your
|
||||
application fully compliant with security standards and best practices, so that you avoid vendor lock-in.
|
||||
|
||||
For some programming languages, {project_name} provides libraries that try to fill the gap for the lack of support of
|
||||
a particular security protocol or to provide a more rich and tightly coupled integration with the server. These libraries
|
||||
are known by *Keycloak Client Adapters*, and they should be used as a last resort if you cannot rely on what is available
|
||||
from the application ecosystem.
|
||||
|
||||
|
||||
|
|
|
@ -1,64 +0,0 @@
|
|||
=== Supported Platforms
|
||||
|
||||
{project_name} enables you to protect applications running on different platforms and using different technology stacks using OpenID Connect and SAML protocols.
|
||||
|
||||
==== OpenID Connect
|
||||
|
||||
===== Java
|
||||
* <<_jboss_adapter,JBoss EAP>>
|
||||
ifeval::[{project_community}==true]
|
||||
* <<_jboss_adapter,WildFly>>
|
||||
endif::[]
|
||||
ifeval::[{project_community}==true]
|
||||
* <<_tomcat_adapter,Tomcat>>
|
||||
* <<_jetty9_adapter,Jetty 9>>
|
||||
endif::[]
|
||||
|
||||
* <<_servlet_filter_adapter,Servlet Filter>>
|
||||
* <<_spring_boot_adapter,Spring Boot>>
|
||||
|
||||
ifeval::[{project_community}==true]
|
||||
* <<_spring_security_adapter,Spring Security>>
|
||||
endif::[]
|
||||
|
||||
===== JavaScript (client-side)
|
||||
* <<_javascript_adapter,JavaScript>>
|
||||
|
||||
===== Node.js (server-side)
|
||||
* <<_nodejs_adapter,Node.js>>
|
||||
|
||||
|
||||
ifeval::[{project_community}==true]
|
||||
===== C#
|
||||
* https://github.com/dylanplecki/KeycloakOwinAuthentication[OWIN] (community)
|
||||
|
||||
===== Python
|
||||
* https://pypi.org/project/oic/[oidc] (generic)
|
||||
|
||||
===== Android
|
||||
* https://github.com/openid/AppAuth-Android[AppAuth] (generic)
|
||||
|
||||
===== iOS
|
||||
* https://github.com/openid/AppAuth-iOS[AppAuth] (generic)
|
||||
|
||||
===== Apache HTTP Server
|
||||
* https://github.com/OpenIDC/mod_auth_openidc[mod_auth_openidc]
|
||||
endif::[]
|
||||
|
||||
==== SAML
|
||||
|
||||
===== Java
|
||||
|
||||
* <<_saml_jboss_adapter,JBoss EAP>>
|
||||
ifeval::[{project_community}==true]
|
||||
* <<_saml_jboss_adapter,WildFly>>
|
||||
* <<_saml-tomcat-adapter,Tomcat>>
|
||||
endif::[]
|
||||
* <<_java-servlet-filter-adapter,Servlet filter>>
|
||||
ifeval::[{project_community}==true]
|
||||
* <<_jetty_saml_adapter,Jetty>>
|
||||
endif::[]
|
||||
|
||||
===== Apache HTTP Server
|
||||
|
||||
* <<_mod_auth_mellon,mod_auth_mellon>>
|
|
@ -1,59 +0,0 @@
|
|||
[[_supported_protocols]]
|
||||
|
||||
=== Supported Protocols
|
||||
|
||||
{project_name} supports both OpenID Connect and SAML protocols.
|
||||
|
||||
==== OpenID Connect
|
||||
|
||||
link:https://openid.net/developers/how-connect-works/[OpenID Connect] (OIDC) is an authentication protocol that is an extension of link:https://datatracker.ietf.org/doc/html/rfc6749[OAuth 2.0].
|
||||
While OAuth 2.0 is only a framework for building authorization protocols and is mainly incomplete, OIDC is a full-fledged authentication and authorization
|
||||
protocol. OIDC also makes heavy use of the link:https://jwt.io[Json Web Token] (JWT) set of standards. These standards define an
|
||||
identity token JSON format and ways to digitally sign and encrypt that data in a compact and web-friendly way.
|
||||
|
||||
There are really two types of use cases when using OIDC. The first is an application that asks the {project_name} server to authenticate
|
||||
a user for them. After a successful login, the application will receive an _identity token_ and an _access token_. The _identity token_
|
||||
contains information about the user such as username, email, and other profile information. The _access token_ is digitally signed by
|
||||
the realm and contains access information (like user role mappings) that the application can use to determine what resources the user
|
||||
is allowed to access on the application.
|
||||
|
||||
The second type of use cases is that of a client that wants to gain access to remote services. In this case, the client asks {project_name}
|
||||
to obtain an _access token_ it can use to invoke on other remote services on behalf of the user. {project_name} authenticates the user
|
||||
then asks the user for consent to grant access to the client requesting it. The client then receives the _access token_. This _access token_
|
||||
is digitally signed by the realm. The client can make REST invocations on remote services using this _access token_. The REST service
|
||||
extracts the _access token_, verifies the signature of the token, then decides based on access information within the token whether or not to process
|
||||
the request.
|
||||
|
||||
==== SAML 2.0
|
||||
|
||||
link:https://saml.xml.org/saml-specifications[SAML 2.0] is a similar specification to OIDC but a lot older and more mature. It has its roots in SOAP and the plethora
|
||||
of WS-* specifications so it tends to be a bit more verbose than OIDC. SAML 2.0 is primarily an authentication protocol
|
||||
that works by exchanging XML documents between the authentication server and the application. XML signatures and encryption are used to verify requests and responses.
|
||||
|
||||
In {project_name} SAML serves two types of use cases: browser applications and REST invocations.
|
||||
|
||||
There are really two types of use cases when using SAML. The first is an application that asks the {project_name} server to authenticate
|
||||
a user for them. After a successful login, the application will receive an XML document that contains
|
||||
something called a SAML assertion that specifies various attributes about the user. This XML document is digitally signed by
|
||||
the realm and contains access information (like user role mappings) that the application can use to determine what resources the user
|
||||
is allowed to access on the application.
|
||||
|
||||
The second type of use cases is that of a client that wants to gain access to remote services. In this case, the client asks {project_name}
|
||||
to obtain a SAML assertion it can use to invoke on other remote services on behalf of the user.
|
||||
|
||||
==== OpenID Connect vs. SAML
|
||||
|
||||
Choosing between OpenID Connect and SAML is not just a matter of using a newer protocol (OIDC) instead of the older more mature protocol (SAML).
|
||||
|
||||
In most cases {project_name} recommends using OIDC.
|
||||
|
||||
SAML tends to be a bit more verbose than OIDC.
|
||||
|
||||
Beyond verbosity of exchanged data, if you compare the specifications you'll find that OIDC was designed to work with the web while SAML was retrofitted to work on top of the web. For example, OIDC is also more suited for HTML5/JavaScript applications because it is
|
||||
easier to implement on the client side than SAML. As tokens are in the JSON format,
|
||||
they are easier to consume by JavaScript. You will also find several nice features that
|
||||
make implementing security in your web applications easier. For example, check out the link:https://openid.net/specs/openid-connect-session-1_0.html#ChangeNotification[iframe trick] that the specification uses to easily determine if a user is still logged in or not.
|
||||
|
||||
SAML has its uses though. As you see the OIDC specifications evolve you see they implement more and more features that SAML has had for years. What we often see is that people pick SAML over OIDC because of the perception that it is more mature and also because they already have existing applications that are secured with it.
|
||||
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
=== Client adapters
|
||||
|
||||
{project_name} client adapters are libraries that make it very easy to secure applications and services with {project_name}. We call them
|
||||
adapters rather than libraries as they provide a tight integration to the underlying platform and framework. This makes our adapters easy to use and they
|
||||
require less boilerplate code than what is typically required by a library.
|
||||
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
|
||||
=== Java adapters
|
||||
=== {project_name} Java adapters
|
||||
|
||||
{project_name} comes with a range of different adapters for Java application. Selecting the correct adapter depends on the target platform.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
[[_saml_multi_tenancy]]
|
||||
==== Multi Tenancy
|
||||
|
||||
SAML offers the same functionality as OIDC for <<_multi_tenancy,Multi Tenancy>>, meaning that a single target application (WAR) can be secured with multiple {project_name} realms. The realms can be located on the same {project_name} instance or on different instances.
|
||||
SAML offers Multi Tenancy, meaning that a single target application (WAR) can be secured with multiple {project_name} realms. The realms can be located on the same {project_name} instance or on different instances.
|
||||
|
||||
To do this, the application must have multiple `keycloak-saml.xml` adapter configuration files.
|
||||
|
||||
|
|
|
@ -11,6 +11,6 @@ Providers implementations are required to be plain java objects which implement
|
|||
|
||||
You can still implement your custom `UserStorageProvider` class, which is able to integrate an external database by JPA Entity Manager, as shown in this example:
|
||||
|
||||
- https://github.com/keycloak/keycloak-quickstarts/tree/latest/user-storage-jpa
|
||||
- {quickstartRepo_link}/tree/latest/user-storage-jpa
|
||||
|
||||
CDI is not supported.
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
:adapterguide_name_short: Securing Apps
|
||||
:adapterguide_link: {project_doc_base_url}/securing_apps/
|
||||
:adapterguide_link_js_adapter: {adapterguide_link}#_javascript_adapter
|
||||
:adapterguide_link_nodejs_adapter: {adapterguide_link}#_nodejs_adapter
|
||||
:adapterguide_link_latest: {project_doc_base_url_latest}/securing_apps/
|
||||
:adapterguide_logout_link: {adapterguide_link}#_java_adapter_logout
|
||||
:adminguide_name: Server Administration Guide
|
||||
|
|
Loading…
Reference in a new issue