Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@ src/main/java/io/vertx/java/**/*.java
src/main/groovy/io/vertx/groovy/**/*.groovy
*.swp
node_modules

.vscode
31 changes: 31 additions & 0 deletions vertx-auth-oauth2/src/main/asciidoc/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -400,3 +400,34 @@ In such event the server will start emitting tokens with a different kid than th
----

A special note on this is that if a user will send many requests with a missing key, your handler should throttle the calls to refresh the new key set, or you might end up DDoS your IdP server.

== Dynamic Client Registration (RFC 7591)
https://datatracker.ietf.org/doc/html/rfc7591[RFC 7591] was written to standardize the process of client registration in OAuth 2.0 and OpenID Connect ecosystems to address the limitations of manual, inconsistent, and non-scalable client registration methods that were common before its publication.
The current implementation has been tested with Keycloak. If you want to enable dynamic client registration, here are the steps to follow:
Prerequisite: Create an initial access token from the Keycloak server. You can create an initial access token using either the https://www.keycloak.org/securing-apps/client-registration#_initial_access_token[admin] console or programmatically.

To create a client in Keycloak using the initial access token and a client ID of your choice, follow the example below.
[source,$lang]
----
{@link examples.AuthOAuth2Examples#example23}
----
To read a client that you have already presented in Keycloak, follow the following example.
[source,$lang]
----
{@link examples.AuthOAuth2Examples#example24}
----
To remove a client that is already present in Keycloak, follow the following example.
[source,$lang]
----
{@link examples.AuthOAuth2Examples#example27}
----
To create an initial access token programmatically, refer to the following example.
[source,$lang]
----
{@link examples.AuthOAuth2Examples#example28}
----
To create an admin access token programmatically, refer to the following example.
[source,$lang]
----
{@link examples.AuthOAuth2Examples#example29}
----
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package io.vertx.ext.auth.oauth2;

import io.vertx.core.json.JsonObject;
import io.vertx.core.json.JsonArray;

/**
* Converter and mapper for {@link io.vertx.ext.auth.oauth2.DCROptions}.
* NOTE: This class has been automatically generated from the {@link io.vertx.ext.auth.oauth2.DCROptions} original class using Vert.x codegen.
*/
public class DCROptionsConverter {

static void fromJson(Iterable<java.util.Map.Entry<String, Object>> json, DCROptions obj) {
for (java.util.Map.Entry<String, Object> member : json) {
switch (member.getKey()) {
case "httpClientOptions":
if (member.getValue() instanceof JsonObject) {
obj.setHttpClientOptions(new io.vertx.core.http.HttpClientOptions((io.vertx.core.json.JsonObject)member.getValue()));
}
break;
case "initialAccessToken":
if (member.getValue() instanceof String) {
obj.setInitialAccessToken((String)member.getValue());
}
break;
case "site":
if (member.getValue() instanceof String) {
obj.setSite((String)member.getValue());
}
break;
case "tenant":
if (member.getValue() instanceof String) {
obj.setTenant((String)member.getValue());
}
break;
}
}
}

static void toJson(DCROptions obj, JsonObject json) {
toJson(obj, json.getMap());
}

static void toJson(DCROptions obj, java.util.Map<String, Object> json) {
if (obj.getHttpClientOptions() != null) {
json.put("httpClientOptions", obj.getHttpClientOptions().toJson());
}
if (obj.getInitialAccessToken() != null) {
json.put("initialAccessToken", obj.getInitialAccessToken());
}
if (obj.getSite() != null) {
json.put("site", obj.getSite());
}
if (obj.getTenant() != null) {
json.put("tenant", obj.getTenant());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package io.vertx.ext.auth.oauth2;

import io.vertx.core.json.JsonObject;
import io.vertx.core.json.JsonArray;

/**
* Converter and mapper for {@link io.vertx.ext.auth.oauth2.DCRRequest}.
* NOTE: This class has been automatically generated from the {@link io.vertx.ext.auth.oauth2.DCRRequest} original class using Vert.x codegen.
*/
public class DCRRequestConverter {

static void fromJson(Iterable<java.util.Map.Entry<String, Object>> json, DCRRequest obj) {
for (java.util.Map.Entry<String, Object> member : json) {
switch (member.getKey()) {
case "clientId":
if (member.getValue() instanceof String) {
obj.setClientId((String)member.getValue());
}
break;
case "registrationAccessToken":
if (member.getValue() instanceof String) {
obj.setRegistrationAccessToken((String)member.getValue());
}
break;
}
}
}

static void toJson(DCRRequest obj, JsonObject json) {
toJson(obj, json.getMap());
}

static void toJson(DCRRequest obj, java.util.Map<String, Object> json) {
if (obj.getClientId() != null) {
json.put("clientId", obj.getClientId());
}
if (obj.getRegistrationAccessToken() != null) {
json.put("registrationAccessToken", obj.getRegistrationAccessToken());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package io.vertx.ext.auth.oauth2;

import io.vertx.core.json.JsonObject;
import io.vertx.core.json.JsonArray;

/**
* Converter and mapper for {@link io.vertx.ext.auth.oauth2.DCRResponse}.
* NOTE: This class has been automatically generated from the {@link io.vertx.ext.auth.oauth2.DCRResponse} original class using Vert.x codegen.
*/
public class DCRResponseConverter {

static void fromJson(Iterable<java.util.Map.Entry<String, Object>> json, DCRResponse obj) {
for (java.util.Map.Entry<String, Object> member : json) {
switch (member.getKey()) {
case "id":
if (member.getValue() instanceof String) {
obj.setId((String)member.getValue());
}
break;
case "clientId":
if (member.getValue() instanceof String) {
obj.setClientId((String)member.getValue());
}
break;
case "enabled":
if (member.getValue() instanceof Boolean) {
obj.setEnabled((Boolean)member.getValue());
}
break;
case "clientAuthenticatorType":
if (member.getValue() instanceof String) {
obj.setClientAuthenticatorType((String)member.getValue());
}
break;
case "secret":
if (member.getValue() instanceof String) {
obj.setSecret((String)member.getValue());
}
break;
case "registrationAccessToken":
if (member.getValue() instanceof String) {
obj.setRegistrationAccessToken((String)member.getValue());
}
break;
}
}
}

static void toJson(DCRResponse obj, JsonObject json) {
toJson(obj, json.getMap());
}

static void toJson(DCRResponse obj, java.util.Map<String, Object> json) {
if (obj.getId() != null) {
json.put("id", obj.getId());
}
if (obj.getClientId() != null) {
json.put("clientId", obj.getClientId());
}
json.put("enabled", obj.isEnabled());
if (obj.getClientAuthenticatorType() != null) {
json.put("clientAuthenticatorType", obj.getClientAuthenticatorType());
}
if (obj.getSecret() != null) {
json.put("secret", obj.getSecret());
}
if (obj.getRegistrationAccessToken() != null) {
json.put("registrationAccessToken", obj.getRegistrationAccessToken());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

import io.vertx.core.json.JsonObject;
import io.vertx.core.json.JsonArray;
import java.time.Instant;
import java.time.format.DateTimeFormatter;

/**
* Converter and mapper for {@link io.vertx.ext.auth.oauth2.OAuth2Options}.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

import io.vertx.core.json.JsonObject;
import io.vertx.core.json.JsonArray;
import java.time.Instant;
import java.time.format.DateTimeFormatter;

/**
* Converter and mapper for {@link io.vertx.ext.auth.oauth2.Oauth2Credentials}.
Expand Down
Loading
Loading