Fix minor typos in the 'Server Developer' guide (#1702)

This commit is contained in:
Marc Wrobel 2022-10-19 08:43:27 +02:00 committed by GitHub
parent 0ea743e15e
commit 8ab8c4e3e6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 23 additions and 23 deletions

View file

@ -1,7 +1,7 @@
[[_action_token_handler_spi]]
== Action Token Handler SPI
An action token is a special instance of Json Web Token (JWT) that permits its bearer to perform some actions, e. g. to
An action token is a special instance of Json Web Token (JWT) that permits its bearer to perform some actions, e.g. to
reset a password or validate e-mail address. They are usually sent to users in form of a link that points to an endpoint
processing action tokens for a particular realm.
@ -160,7 +160,7 @@ token, only the last token would be invalidated. In that case, you should use
`org.keycloak.models.SingleUseObjectProvider` in action token handler to invalidate the used tokens manually.
+
Default implementation of most of the `ActionTokenHandler` methods is the
`org.keycloak.authentication.actiontoken.AbstractActionTokenHander` abstract class in `keycloak-services` module. The
`org.keycloak.authentication.actiontoken.AbstractActionTokenHandler` abstract class in `keycloak-services` module. The
only method that needs to be implemented is `handleToken(token, context)` that performs the actual action.
* `org.keycloak.authentication.actiontoken.ActionTokenHandlerFactory` - factory that instantiates action token

View file

@ -10,7 +10,7 @@ The Admin Console supports applying, ordering, and configuring these new mechani
Different aspects of this form can be enabled and disabled for example
Recaptcha support can be turned off and on.
The same authentication SPI can be used to add another page to the registration flow or reimplement it entirely.
There's also an additional fine-grained SPI you can use to add specific validations and user extensions to the built in registration form.
There's also an additional fine-grained SPI you can use to add specific validations and user extensions to the built-in registration form.
A required action in {project_name} is an action that a user has to perform after he authenticates.
After the action is performed successfully, the user doesn't have to perform the action again.
@ -700,7 +700,7 @@ public class SecretQuestionAuthenticatorFactory implements AuthenticatorFactory,
The next thing the factory is responsible for is to specify the allowed requirement switches.
While there are four different requirement types: ALTERNATIVE, REQUIRED, CONDITIONAL, DISABLED, AuthenticatorFactory implementations can limit which
requirement options are shown in the Admin Console when defining a flow. CONDITIONAL should only always be used for subflows, and unless there's a good
reason for doing otherwise, the requirement on a authenticator should be REQUIRED, ALTERNATIVE and DISABLED:
reason for doing otherwise, the requirement on an authenticator should be REQUIRED, ALTERNATIVE and DISABLED:
[source,java]
----
@ -792,7 +792,7 @@ Let's take a bigger look at secret-question.ftl Here's a small code snippet:
</form>
----
Any piece of text enclosed in `${}` corresponds to an attribute or template funtion.
Any piece of text enclosed in `${}` corresponds to an attribute or template function.
If you see the form's action, you see it points to `${url.loginAction}`.
This value is automatically generated when you invoke the AuthenticationFlowContext.form() method.
You can also obtain this value by calling the AuthenticationFlowContext.getActionURL() method in Java code.
@ -940,7 +940,7 @@ Your new required action should now be displayed and enabled in the required act
=== Modifying or extending the registration form
It is entirely possible for you to implement your own flow with a set of Authenticators to totally change how registration is done in {project_name}.
But what you'll usually want to do is just add a little bit of validation to the out of the box registration page.
But what you'll usually want to do is just add a bit of validation to the out-of-the-box registration page.
An additional SPI was created to be able to do this.
It basically allows you to add validation of form elements on the page as well as to initialize UserModel attributes and data after the user has been registered.
We'll look at both the implementation of the user profile registration processing as well as the registration Google Recaptcha plugin.
@ -1153,7 +1153,7 @@ One thing to note if you are extending the reset credentials flow.
The first "authenticator" is just a page to obtain the username or email.
If the username or email exists, then the AuthenticationFlowContext.getUser() will return the located user.
Otherwise this will be null.
This form *WILL NOT* re-ask the user to enter in an email or username if the previous email or username did not exist.
This form *WILL NOT* re-ask the user to enter an email or username if the previous email or username did not exist.
You need to prevent attackers from being able to guess valid users.
So, if AuthenticationFlowContext.getUser() returns null, you should proceed with the flow to make it look like a valid user was selected.
I suggest that if you want to add secret questions to this flow, you should ask these questions after the email is sent.
@ -1187,7 +1187,7 @@ Actually {project_name} has 2 default implementations of client authentication:
Traditional authentication with client_id and client_secret::
This is default mechanism mentioned in the https://openid.net/specs/openid-connect-core-1_0.html[OpenID Connect] or https://datatracker.ietf.org/doc/html/rfc6749[OAuth2] specification and {project_name} supports it since it's early days.
The public client needs to include `client_id` parameter with its ID in the POST request (so it's defacto not authenticated) and the confidential client needs to include `Authorization: Basic` header with the clientId and clientSecret used as username and password.
The public client needs to include `client_id` parameter with its ID in the POST request (so it's de facto not authenticated) and the confidential client needs to include `Authorization: Basic` header with the clientId and clientSecret used as username and password.
Authentication with signed JWT::
This is based on the https://datatracker.ietf.org/doc/html/rfc7523[JWT Bearer Token Profiles for OAuth 2.0] specification.

View file

@ -1,7 +1,7 @@
[[_events]]
== Event Listener SPI
Writing a Event Listener Provider starts by implementing the `EventListenerProvider` and `EventListenerProviderFactory` interfaces. Please see the Javadoc
Writing an Event Listener Provider starts by implementing the `EventListenerProvider` and `EventListenerProviderFactory` interfaces. Please see the Javadoc
and examples for complete details on how to do this.
For details on how to package and deploy a custom provider refer to the <<_providers,Service Provider Interfaces>> chapter.

View file

@ -152,4 +152,4 @@ The DB schema will be automatically updated at startup.
For more details, take a look at the example distribution at example `providers/domain-extension`, which shows the `ExampleJpaEntityProvider` and `example-changelog.xml` described above.
NOTE: Don't forget to always backup your database before doing any changes in the Liquibase changelog and triggering a DB update.
NOTE: Don't forget to always back up your database before doing any changes in the Liquibase changelog and triggering a DB update.

View file

@ -2,7 +2,7 @@
== Identity Brokering APIs
{project_name} can delegate authentication to a parent IDP for login. A typical example of this is the case
where you want users to be able to login through a social provider such as Facebook or Google. You can
where you want users to be able to log in through a social provider such as Facebook or Google. You can
also link existing accounts to a brokered IDP. This section describes some APIs that your applications
can use as it pertains to identity brokering.

View file

@ -9,7 +9,7 @@ This behavior can be changed through the `LocaleSelectorSPI` by implementing the
The `LocaleSelectorProvider` interface has a single method, `resolveLocale`, which must return a locale given a `RealmModel` and a nullable `UserModel`. The actual request is available from the `KeycloakSession#getContext` method.
Custom implementations can extend the `DefaultLocaleSelectorProvider` in order to reuse parts of the default behavior. For example to ignore the `Accept-Language` request header, a custom implementation could extend the default provider, override it's `getAcceptLanguageHeaderLocale`, and return a null value. As a result the locale selection will fall back on the realms's default language.
Custom implementations can extend the `DefaultLocaleSelectorProvider` in order to reuse parts of the default behavior. For example to ignore the `Accept-Language` request header, a custom implementation could extend the default provider, override it's `getAcceptLanguageHeaderLocale`, and return a null value. As a result the locale selection will fall back on the realm's default language.
[role="_additional-resources"]
=== Additional resources

View file

@ -100,7 +100,7 @@ public void init(Config.Scope config) {
}
----
Your provider can also lookup other providers if needed. For example:
Your provider can also look up other providers if needed. For example:
[source,java]
----
@ -123,7 +123,7 @@ public class MyThemeSelectorProvider implements ThemeSelectorProvider {
==== Show info from your SPI implementation in the Admin Console
Sometimes it is useful to show additional info about your Provider to a {project_name} administrator. You can show provider build time information (for example, version of
custom provider currently installed), current configuration of the provider (eg. url of remote system your provider talks to) or some operational info
custom provider currently installed), current configuration of the provider (e.g. url of remote system your provider talks to) or some operational info
(average time of response from remote system your provider talks to). {project_name} Admin Console provides Server Info page to show this kind of information.
To show info from your provider it is enough to implement `org.keycloak.provider.ServerInfoAwareProviderFactory` interface in your `ProviderFactory`.

View file

@ -1,7 +1,7 @@
[[_saml_role_mappings_spi]]
== SAML role mappings SPI
{project_name} defines a SPI for mapping SAML roles into roles that exist in the SP environment. The roles returned by
{project_name} defines an SPI for mapping SAML roles into roles that exist in the SP environment. The roles returned by
a third-party IDP might not always correspond to the roles that were defined for the SP application so there is a need for a
mechanism that allows mapping the SAML roles into different roles. It is used by the SAML adapter after it extracts the roles
from the SAML assertion to set up the container's security context.

View file

@ -97,7 +97,7 @@ import=common/keycloak
+
You have now created a theme with support for the login type.
. Log into the Admin Console to checkout your new theme
. Log into the Admin Console to check out your new theme
. Select your realm
. Click *Realm Settings* from the menu.
. Click on the *Themes* tab.

View file

@ -3,7 +3,7 @@
=== LDAP mapper
For the more advanced usecases, you have the possibility to create your own implementation of LDAP mapper or just subclass from some already existing mapper
For the more advanced use cases, you have the possibility to create your own implementation of LDAP mapper or just subclass from some already existing mapper
implementation. You will need to implement `UserFederationMapperFactory` interface.
In most cases, instead of creating `UserFederationMapperFactory` from scratch, you can create subclasses of `AbstractLDAPFederationMapperFactory`, which itself

View file

@ -1,7 +1,7 @@
=== Augmenting external storage
The `PropertyFileUserStorageProvider` example is really limited. While we will be able to login with users stored
The `PropertyFileUserStorageProvider` example is really limited. While we will be able to log in with users stored
in a property file, we won't be able to do much else. If users loaded by this provider need special role or group
mappings to fully access particular applications there is no way for us to add additional role mappings to these users.
You also can't modify or add additional important attributes like email, first and last name.

View file

@ -63,7 +63,7 @@ return a `ReadOnlyException`.
The `UserFederationProvider` query methods such as `searchByAttributes()` and `getGroupMembers()` are now encapsulated
in an optional interface `UserQueryProvider`. If you do not implement this interface, then users will not be viewable
in the admin console. You'll still be able to login though.
in the admin console. You'll still be able to log in though.
==== UserFederationProviderFactory versus UserStorageProviderFactory

View file

@ -88,7 +88,7 @@ The `createAdapter()` method uses the helper class `org.keycloak.storage.adapter
Every get method of `AbstractUserAdapter` either returns null or empty collections. However, methods that return role and group mappings will return the default roles and groups configured for the realm for every user. Every set method of `AbstractUserAdapter` will throw a `org.keycloak.storage.ReadOnlyException`. So if you attempt to modify the user in the Admin Console, you will get an error.
The `getUserById()` method parses the `id` parameter using the `org.keycloak.storage.StorageId` helper class. The `StorageId.getExternalId()` method is invoked to obtain the username embeded in the `id` parameter. The method then delegates to `getUserByUsername()`.
The `getUserById()` method parses the `id` parameter using the `org.keycloak.storage.StorageId` helper class. The `StorageId.getExternalId()` method is invoked to obtain the username embedded in the `id` parameter. The method then delegates to `getUserByUsername()`.
Emails are not stored, so the `getUserByEmail()` method returns null.

View file

@ -24,13 +24,13 @@ ifeval::[{project_community}==true]
| `org.keycloak.models` | `GroupModel`, `RoleMapperModel`, `UserCredentialManager`, `UserModel`, `UserProvider`
| `org.keycloak.models.cache` | `CachedUserModel`, `UserCache`
| `org.keycloak.storage.federated` | All interfaces
| `org.kecyloak.storage.user` | `UserQueryProvider`(*)
| `org.keycloak.storage.user` | `UserQueryProvider`(*)
endif::[]
ifeval::[{project_product}==true]
| `org.keycloak.credential` | `CredentialInputUpdater`(*)
| `org.keycloak.models` | `GroupModel`, `RoleMapperModel`, `UserModel`
| `org.keycloak.storage.federated` | All interfaces
| `org.kecyloak.storage.user` | `UserQueryProvider`(*)
| `org.keycloak.storage.user` | `UserQueryProvider`(*)
endif::[]
|===
(*) indicates the interface is a _<<_provider_capability_interfaces,capability interface>>_
@ -54,4 +54,4 @@ public class CustomQueryProvider extends UserQueryProvider.Streams {
}
...
}
----
----