Update Securing Apps guide (#1569)

Revise guide for new admin console

Closes 1568
This commit is contained in:
andymunro 2022-07-25 16:37:28 -04:00 committed by GitHub
parent 89cc9960ac
commit babbe50dcc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 121 additions and 85 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View file

@ -45,7 +45,6 @@ For set up on the adapter side you need to have something like this in your `key
"client-keystore-password": "storepass",
"client-key-password": "keypass",
"client-key-alias": "clientkey",
"algorithm": "RS256",
"token-expiration": 10
}
}
@ -54,10 +53,6 @@ For set up on the adapter side you need to have something like this in your `key
With this configuration, the keystore file `keystore-client.jks` must be available on classpath in your WAR. If you do not use the prefix `classpath:`
you can point to any file on the file system where the client application is running.
The `algorithm` field specifies the algorithm used for the Signed JWT and it defaults to `RS256`. This field should be in sync with the key pair.
For example, the `RS256` algorithm needs a RSA key pair while the `ES256` algorithm requires an EC key pair. Please refer to
https://datatracker.ietf.org/doc/html/rfc7518#section-3[Cryptographic Algorithms for Digital Signatures and MACs] for more information.
ifeval::[{project_community}==true]
For inspiration, you can take a look at the examples distribution into the main demo example into the `product-portal` application.

View file

@ -55,76 +55,72 @@ on the corresponding client. Once the page for the client is opened click on the
Here is a description of each configuration option:
realm::
_REQUIRED._
Name of the realm.
This is _REQUIRED._
resource::
The client-id of the application. Each application has a client-id that is used to identify the application.
This is _REQUIRED._
_REQUIRED._ The client-id of the application. Each application has a client-id that is used to identify the application.
realm-public-key::
PEM format of the realm public key. You can obtain this from the Admin Console.
This is _OPTIONAL_ and it's not recommended to set it. If not set, the adapter will download this from {project_name} and
_OPTIONAL_ and it's not recommended to set it. PEM format of the realm public key. You can obtain this from the Admin Console.
If not set, the adapter will download this from {project_name} and
it will always re-download it when needed (eg. {project_name} rotates its keys). However if realm-public-key is set, then adapter
will never download new keys from {project_name}, so when {project_name} rotate it's keys, adapter will break.
auth-server-url::
The base URL of the {project_name} server. All other {project_name} pages and REST service endpoints are derived from this. It is usually of the form `\https://host:port{kc_base_path}`.
This is _REQUIRED._
_REQUIRED._ The base URL of the {project_name} server. All other {project_name} pages and REST service endpoints are derived from this. It is usually of the form `\https://host:port{kc_base_path}`.
ssl-required::
Ensures that all communication to and from the {project_name} server is over HTTPS.
_OPTIONAL_. Ensures that all communication to and from the {project_name} server is over HTTPS.
In production this should be set to `all`.
This is _OPTIONAL_.
The default value is _external_ meaning that HTTPS is required by default for external requests.
Valid values are 'all', 'external' and 'none'.
confidential-port::
The confidential port used by the {project_name} server for secure connections over SSL/TLS.
This is _OPTIONAL_.
_OPTIONAL_. The confidential port used by the {project_name} server for secure connections over SSL/TLS.
The default value is _8443_.
use-resource-role-mappings::
_OPTIONAL_.
If set to true, the adapter will look inside the token for application level role mappings for the user. If false, it will look at the realm level for user role mappings.
This is _OPTIONAL_.
The default value is _false_.
public-client::
If set to true, the adapter will not send credentials for the client to {project_name}.
This is _OPTIONAL_.
_OPTIONAL_. If set to true, the adapter will not send credentials for the client to {project_name}.
The default value is _false_.
enable-cors::
This enables CORS support. It will handle CORS preflight requests. It will also look into the access token to determine valid origins.
This is _OPTIONAL_.
_OPTIONAL_. This enables CORS support. It will handle CORS preflight requests. It will also look into the access token to determine valid origins.
The default value is _false_.
cors-max-age::
_OPTIONAL_.
If CORS is enabled, this sets the value of the `Access-Control-Max-Age` header.
This is _OPTIONAL_.
If not set, this header is not returned in CORS responses.
cors-allowed-methods::
_OPTIONAL_.
If CORS is enabled, this sets the value of the `Access-Control-Allow-Methods` header.
This should be a comma-separated string.
This is _OPTIONAL_.
If not set, this header is not returned in CORS responses.
cors-allowed-headers::
_OPTIONAL_.
If CORS is enabled, this sets the value of the `Access-Control-Allow-Headers` header.
This should be a comma-separated string.
This is _OPTIONAL_.
If not set, this header is not returned in CORS responses.
cors-exposed-headers::
_OPTIONAL_.
If CORS is enabled, this sets the value of the `Access-Control-Expose-Headers` header.
This should be a comma-separated string.
This is _OPTIONAL_.
If not set, this header is not returned in CORS responses.
bearer-only::
_OPTIONAL_.
This should be set to _true_ for services. If enabled the adapter will not attempt to authenticate users, but only verify bearer tokens.
This is _OPTIONAL_.
The default value is _false_.
autodetect-bearer-only::
@ -135,52 +131,53 @@ autodetect-bearer-only::
The default value is _false_.
enable-basic-auth::
_OPTIONAL_.
This tells the adapter to also support basic authentication. If this option is enabled, then _secret_ must also be provided.
This is _OPTIONAL_.
The default value is _false_.
expose-token::
_OPTIONAL_.
If `true`, an authenticated browser client (via a JavaScript HTTP invocation) can obtain the signed access token via the URL `root/k_query_bearer_token`.
This is _OPTIONAL_.
The default value is _false_.
credentials::
Specify the credentials of the application. This is an object notation where the key is the credential type and the value is the value of the credential type.
Currently password and jwt is supported. This is _REQUIRED_ only for clients with 'Confidential' access type.
_REQUIRED_ only for clients with 'Confidential' access type. Specify the credentials of the application. This is an object notation where the key is the credential type and the value is the value of the credential type.
Currently password and jwt is supported. T
connection-pool-size::
_OPTIONAL_.
This config option defines how many connections to the {project_name} server should be pooled.
This is _OPTIONAL_.
The default value is `20`.
socket-timeout-millis::
_OPTIONAL_.
Timeout for socket waiting for data after establishing the connection in milliseconds.
Maximum time of inactivity between two data packets.
A timeout value of zero is interpreted as an infinite timeout.
A negative value is interpreted as undefined (system default if applicable).
The default value is `-1`.
This is _OPTIONAL_.
connection-timeout-millis::
onnection-timeout-millis::
Timeout for establishing the connection with the remote host in milliseconds.
A timeout value of zero is interpreted as an infinite timeout.
A negative value is interpreted as undefined (system default if applicable).
The default value is `-1`.
This is _OPTIONAL_.
connection-ttl-millis::
_OPTIONAL_.
Connection time-to-live for client in milliseconds.
A value less than or equal to zero is interpreted as an infinite value.
The default value is `-1`.
This is _OPTIONAL_.
disable-trust-manager::
_OPTIONAL_.
If the {project_name} server requires HTTPS and this config option is set to `true` you do not have to specify a truststore.
This setting should only be used during development and *never* in production as it will disable verification of SSL certificates.
This is _OPTIONAL_.
The default value is `false`.
allow-any-hostname::
_OPTIONAL_.
If the {project_name} server requires HTTPS and this config option is set to `true` the {project_name} server's certificate is validated via the truststore,
but host name validation is not done.
This setting should only be used during development and *never* in production as it will disable verification of SSL certificates.
@ -198,24 +195,24 @@ truststore::
This is what the trustore does.
The keystore contains one or more trusted host certificates or certificate authorities.
You can create this truststore by extracting the public certificate of the {project_name} server's SSL keystore.
This is _REQUIRED_ unless `ssl-required` is `none` or `disable-trust-manager` is `true`.
_REQUIRED_ unless `ssl-required` is `none` or `disable-trust-manager` is `true`.
truststore-password::
Password for the truststore.
This is _REQUIRED_ if `truststore` is set and the truststore requires a password.
_REQUIRED_ if `truststore` is set and the truststore requires a password.
client-keystore::
_OPTIONAL_.
This is the file path to a keystore file.
This keystore contains client certificate for two-way SSL when the adapter makes HTTPS requests to the {project_name} server.
This is _OPTIONAL_.
client-keystore-password::
_REQUIRED_ if `client-keystore` is set.
Password for the client keystore.
This is _REQUIRED_ if `client-keystore` is set.
client-key-password::
_REQUIRED_ if `client-keystore` is set.
Password for the client's key.
This is _REQUIRED_ if `client-keystore` is set.
always-refresh-token::
If _true_, the adapter will refresh token in every request.
@ -248,14 +245,15 @@ principal-attribute::
Possible values are `sub`, `preferred_username`, `email`, `name`, `nickname`, `given_name`, `family_name`.
turn-off-change-session-id-on-login::
The session id is changed by default on a successful login on some platforms to plug a security attack vector. Change this to true if you want to turn this off This is _OPTIONAL_.
_OPTIONAL_. The session id is changed by default on a successful login on some platforms to plug a security attack vector. Change this to true if you want to turn this off
The default value is _false_.
token-minimum-time-to-live::
_OPTIONAL_.
Amount of time, in seconds, to preemptively refresh an active access token with the {project_name} server before it expires.
This is especially useful when the access token is sent to another REST client where it could expire before being evaluated.
This value should never exceed the realm's access token lifespan.
This is _OPTIONAL_. The default value is `0` seconds, so adapter will refresh access token just if it's expired.
The default value is `0` seconds, so adapter will refresh access token just if it's expired.
min-time-between-jwks-requests::
Amount of time, in seconds, specifying minimum interval between two requests to {project_name} to retrieve new public keys.
@ -284,4 +282,4 @@ verify-token-audience::
If set to `true`, then during authentication with the bearer token, the adapter will verify whether the token contains this
client name (resource) as an audience. The option is especially useful for services, which primarily serve requests authenticated
by the bearer token. This is set to `false` by default, however for improved security, it is recommended to enable this.
See link:{adminguide_link}#audience-support[Audience Support] for more details about audience support.
See link:{adminguide_link}#audience-support[Audience Support] for more details about audience

View file

@ -1,5 +1,5 @@
[id="jboss7_adapter_rpm"]
==== Installing JBoss EAP 7 adapters from an 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.
@ -55,7 +55,7 @@ $ $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
===== 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.

View file

@ -11,10 +11,11 @@ You can install this adapter from a ZIP file or from an RPM.
* xref:jboss_adapter_installation[Installing JBOSS EAP adapters from a ZIP file]
* xref:jboss7_adapter_rpm[Installing JBoss EAP 7 Adapters from an RPM]
* xref:jboss6_adapter_rpm[Installing JBoss EAP 6 Adapters from an RPM]
endif::[]
[id="jboss_adapter_installation"]
==== Installing JBOSS EAP adapters from a ZIP file
===== Installing JBOSS EAP adapters from a ZIP file
endif::[]
ifeval::[{project_community}==true]
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.

View file

@ -415,14 +415,14 @@ adapter::
* "default" - the library uses the browser api for redirects (this is the default)
* "cordova" - the library will try to use the InAppBrowser cordova plugin to load keycloak login/registration pages (this is used automatically when the library is working in a cordova ecosystem)
* "cordova-native" - the library tries to open the login and registration page using the phone's system browser using the BrowserTabs cordova plugin. This requires extra setup for redirecting back to the app (see <<hybrid-apps-with-cordova>>).
* custom - allows you to implement a custom adapter (only for advanced use cases)
* "custom" - allows you to implement a custom adapter (only for advanced use cases)
responseType::
Response type sent to {project_name} with login requests. This is determined based on the flow value used during initialization, but can be overridden by setting this value.
===== Methods
====== init(options)
*init(options)*
Called to initialize the adapter.
@ -447,7 +447,7 @@ Options is an Object, where:
Returns a promise that resolves when initialization completes.
====== login(options)
*login(options)*
Redirects to login form.
@ -472,13 +472,13 @@ and link:{adminguide_link}#_step-up-flow[Step-up authentication documentation] f
* locale - Sets the 'ui_locales' query param in compliance with https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest[section 3.1.2.1 of the OIDC 1.0 specification].
* cordovaOptions - Specifies the arguments that are passed to the Cordova in-app-browser (if applicable). Options `hidden` and `location` are not affected by these arguments. All available options are defined at https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-inappbrowser/. Example of use: `{ zoom: "no", hardwareback: "yes" }`;
====== createLoginUrl(options)
*createLoginUrl(options)*
Returns the URL to login form.
Options is an optional Object, which supports same options as the function `login` .
====== logout(options)
*logout(options)*
Redirects to logout.
@ -486,7 +486,7 @@ Options is an Object, where:
* redirectUri - Specifies the uri to redirect to after logout.
====== createLogoutUrl(options)
*createLogoutUrl(options)*
Returns the URL to logout the user.
@ -494,23 +494,23 @@ Options is an Object, where:
* redirectUri - Specifies the uri to redirect to after logout.
====== register(options)
*register(options)*
Redirects to registration form. Shortcut for login with option action = 'register'
Options are same as for the login method but 'action' is set to 'register'
====== createRegisterUrl(options)
*createRegisterUrl(options)*
Returns the url to registration page. Shortcut for createLoginUrl with option action = 'register'
Options are same as for the createLoginUrl method but 'action' is set to 'register'
====== accountManagement()
*accountManagement()*
Redirects to the Account Management Console.
====== createAccountUrl(options)
*createAccountUrl(options)*
Returns the URL to the Account Management Console.
@ -518,15 +518,15 @@ Options is an Object, where:
* redirectUri - Specifies the uri to redirect to when redirecting back to the application.
====== hasRealmRole(role)
*hasRealmRole(role)*
Returns true if the token has the given realm role.
====== hasResourceRole(role, resource)
*hasResourceRole(role, resource)*
Returns true if the token has the given role for the resource (resource is optional, if not specified clientId is used).
====== loadUserProfile()
*loadUserProfile()*
Loads the users profile.
@ -544,11 +544,11 @@ keycloak.loadUserProfile()
});
----
====== isTokenExpired(minValidity)
*isTokenExpired(minValidity)*
Returns true if the token has less than minValidity seconds left before it expires (minValidity is optional, if not specified 0 is used).
====== updateToken(minValidity)
*updateToken(minValidity)*
If the token expires within minValidity seconds (minValidity is optional, if not specified 5 is used) the token is refreshed.
If the session status iframe is enabled, the session status is also checked.
@ -571,7 +571,7 @@ keycloak.updateToken(5)
});
----
====== clearToken()
*clearToken()*
Clear authentication state, including tokens.
This can be useful if application has detected the session was expired, for example if updating token fails.
@ -590,10 +590,10 @@ keycloak.onAuthSuccess = function() { alert('authenticated'); }
The available events are:
* onReady(authenticated) - Called when the adapter is initialized.
* onAuthSuccess - Called when a user is successfully authenticated.
* onAuthError - Called if there was an error during authentication.
* onAuthRefreshSuccess - Called when the token is refreshed.
* onAuthRefreshError - Called if there was an error while trying to refresh the token.
* onAuthLogout - Called if the user is logged out (will only be called if the session status iframe is enabled, or in Cordova mode).
* onTokenExpired - Called when the access token is expired. If a refresh token is available the token can be refreshed with updateToken, or in cases where it is not (that is, with implicit flow) you can redirect to login screen to obtain a new access token.
* *onReady(authenticated)* - Called when the adapter is initialized.
* *onAuthSuccess* - Called when a user is successfully authenticated.
* *onAuthError* - Called if there was an error during authentication.
* *onAuthRefreshSuccess* - Called when the token is refreshed.
* *onAuthRefreshError* - Called if there was an error while trying to refresh the token.
* *onAuthLogout* - Called if the user is logged out (will only be called if the session status iframe is enabled, or in Cordova mode).
* *onTokenExpired* - Called when the access token is expired. If a refresh token is available the token can be refreshed with updateToken, or in cases where it is not (that is, with implicit flow) you can redirect to login screen to obtain a new access token.

View file

@ -144,10 +144,15 @@ image:{project_images}/exchange-target-client-permission-unset.png[Target Client
.Procedure
ifeval::[{project_community}==true]
. Toggle *Permissions Enabled* to *On*.
endif::[]
ifeval::[{project_product}==true]
. Toggle *Permissions Enabled* to *ON*.
endif::[]
+
.Target Client Permission
image:{project_images}/exchange-target-client-permission-set.png[]
image:{project_images}/exchange-target-client-permission-set.png[Target Client Exchange Permission Set]
+
That page displays a *token-exchange* link.
@ -158,21 +163,33 @@ This setup page displays.
.Target Client Exchange Permission Setup
image:{project_images}/exchange-target-client-permission-setup.png[Target Client Exchange Permission Setup]
. Define a policy for this permission by clicking the *Authorization* link
ifeval::[{project_community}==true]
. Click *Client details* in the breadcrumbs at the top of the screen.
. Define a policy for this permission.
endif::[]
ifeval::[{project_product}==true]
. Click *Authorization* in the breadcrumbs at the top of the screen.
. Define a policy for this permission.
endif::[]
. Click the *Policies* tab.
ifeval::[{project_community}==true]
. Create a *Client* Policy by clicking *Create policy* button.
endif::[]
ifeval::[{project_product}==true]
. Create a *Client* Policy.
endif::[]
+
.Client Policy Creation
image:{project_images}/exchange-target-client-policy.png[]
image:{project_images}/exchange-target-client-policy.png[Client Policy Creation]
. Enter in the starting client that is the authenticated client that is requesting a token exchange.
. After you create this policy, go back to the target client's *token-exchange* permission and add the client policy you just defined.
+
.Apply Client Policy
image:{project_images}/exchange-target-client-exchange-apply-policy.png[]
image:{project_images}/exchange-target-client-exchange-apply-policy.png[Apply Client Policy]
Your client now has permission to invoke. If you do not do this correctly, you will get a 403 Forbidden response if you
try to make an exchange.
@ -232,14 +249,19 @@ discussed more in the <<_internal_external_making_request, Making the Request>>
Internal to external token exchange requests will be denied with a 403, Forbidden response until you grant permission for the calling client to exchange tokens with the external identity provider. To grant permission to the client, you go to the identity provider's configuration page to the *Permissions* tab.
.Identity Provider Permission
image:{project_images}/exchange-idp-permission-unset.png[]
image:{project_images}/exchange-idp-permission-unset.png[Identity Provider Exchange Permission]
.Procedure
ifeval::[{project_community}==true]
. Toggle *Permissions Enabled* to *On*.
endif::[]
ifeval::[{project_product}==true]
. Toggle *Permissions Enabled* to *ON*.
endif::[]
+
.Identity Provider Permission
image:{project_images}/exchange-idp-permission-set.png[]
image:{project_images}/exchange-idp-permission-set.png[Identity Provider Exchange Permission Set]
+
The page displays *token-exchange* link.
@ -250,7 +272,14 @@ This setup page appears.
.Identity Provider Exchange Permission Setup
image:{project_images}/exchange-idp-permission-setup.png[Identity Provider Exchange Permission Setup]
. Click the *Authorization* link and go to the *Policies* tab to create a client policy.
ifeval::[{project_community}==true]
. Click *Client details* in the breadcrumbs at the top of the screen.
endif::[]
ifeval::[{project_product}==true]
. Click *Authorization* in the breadcrumbs at the top of the screen.
endif::[]
. Click *Policies* tab to create a client policy.
+
.Client Policy Creation
image:{project_images}/exchange-idp-client-policy.png[Client Policy Creation]
@ -431,7 +460,7 @@ WARNING: It is very risky to enable direct naked impersonation for a client. If
If the `audience` parameter is provided, then the calling client must have permission to exchange to the client. How
to set this up is discussed earlier in this chapter.
Additionally, the calling client must be granted permission to impersonate users. In the Admin Console.
Additionally, the calling client must be granted permission to impersonate users.
.Procedure
@ -442,12 +471,18 @@ Additionally, the calling client must be granted permission to impersonate users
.User Permissions
image:{project_images}/exchange-users-permission-unset.png[User Permissions]
. Toggle *Permissions Enabled* to true.
. Toggle *Permissions Enabled* to *On*.
+
.Identity Provider Permission
image:{project_images}/exchange-users-permission-set.png[]
image:{project_images}/exchange-users-permission-set.png[Users Impersonation Permission Set]
+
ifeval::[{project_community}==true]
The page displays an *impersonate* link.
endif::[]
ifeval::[{project_product}==true]
The page displays an *impersonation* link.
endif::[]
. Click that link to start defining the permission.
+
@ -456,7 +491,14 @@ This setup page displays.
.Users Impersonation Permission Setup
image:{project_images}/exchange-users-permission-setup.png[Users Impersonation Permission Setup]
. Click the *Authorization* link
ifeval::[{project_community}==true]
. Click *Client details* in the breadcrumbs at the top of the screen.
. Define a policy for this permission.
endif::[]
ifeval::[{project_product}==true]
. Click *Authorization* in the breadcrumbs at the top of the screen.
. Define a policy for this permission.
endif::[]
. Go to the *Policies* tab and create a client policy.
+