diff --git a/vertx-auth-sql-client/src/main/asciidoc/index.adoc b/vertx-auth-sql-client/src/main/asciidoc/index.adoc index 352b2293f..b2af96727 100644 --- a/vertx-auth-sql-client/src/main/asciidoc/index.adoc +++ b/vertx-auth-sql-client/src/main/asciidoc/index.adoc @@ -39,6 +39,18 @@ The out of the box config assumes certain queries for authentication and authori {@link io.vertx.ext.auth.sqlclient.SqlAuthorizationOptions#setPermissionsQuery(String)} and {@link io.vertx.ext.auth.sqlclient.SqlAuthorizationOptions#setRolesQuery(String)}, if you want to use them with a different database schema. +When the authentication query returns more columns than the password, the extra columns can be mapped to attributes of the +authenticated {@link io.vertx.ext.auth.User} by providing a mapping function: + +[source,$lang] +---- +{@link examples.AuthSqlExamples#example10} +---- + +The password is always expected in the first column, any other column is available to the mapping function and the returned +JSON object is merged into the user attributes. This avoids a second query to load user data, such as its id, right after +authentication. + The basic data definition for the storage should look like this: [source,sql] diff --git a/vertx-auth-sql-client/src/main/java/examples/AuthSqlExamples.java b/vertx-auth-sql-client/src/main/java/examples/AuthSqlExamples.java index 6f7cceb9a..ccae8c54b 100644 --- a/vertx-auth-sql-client/src/main/java/examples/AuthSqlExamples.java +++ b/vertx-auth-sql-client/src/main/java/examples/AuthSqlExamples.java @@ -17,6 +17,7 @@ package examples; import io.vertx.core.Vertx; +import io.vertx.core.json.JsonObject; import io.vertx.ext.auth.User; import io.vertx.ext.auth.prng.VertxContextPRNG; import io.vertx.ext.auth.authentication.AuthenticationProvider; @@ -46,6 +47,20 @@ public void example5(Vertx vertx, SqlClient sqlClient) { SqlAuthentication.create(sqlClient, options); } + public void example10(Vertx vertx, SqlClient sqlClient) { + + SqlAuthenticationOptions options = new SqlAuthenticationOptions() + // the password is expected in the first column, any other + // column is available to the attribute mapper + .setAuthenticationQuery( + "SELECT password, email FROM users WHERE username = ?"); + + AuthenticationProvider authenticationProvider = + SqlAuthentication.create(sqlClient, options, row -> + new JsonObject() + .put("email", row.getString("email"))); + } + public void example6(AuthenticationProvider authProvider) { Credentials authInfo = new UsernamePasswordCredentials( diff --git a/vertx-auth-sql-client/src/main/java/io/vertx/ext/auth/sqlclient/SqlAuthentication.java b/vertx-auth-sql-client/src/main/java/io/vertx/ext/auth/sqlclient/SqlAuthentication.java index 00198fbf6..4bf8c108c 100644 --- a/vertx-auth-sql-client/src/main/java/io/vertx/ext/auth/sqlclient/SqlAuthentication.java +++ b/vertx-auth-sql-client/src/main/java/io/vertx/ext/auth/sqlclient/SqlAuthentication.java @@ -17,11 +17,14 @@ package io.vertx.ext.auth.sqlclient; import io.vertx.codegen.annotations.VertxGen; +import io.vertx.core.json.JsonObject; import io.vertx.ext.auth.authentication.AuthenticationProvider; import io.vertx.ext.auth.sqlclient.impl.SqlAuthenticationImpl; +import io.vertx.sqlclient.Row; import io.vertx.sqlclient.SqlClient; import java.util.Map; +import java.util.function.Function; /** * Factory interface for creating {@link io.vertx.ext.auth.authentication.AuthenticationProvider} instances that use the Vert.x SQL client. @@ -52,6 +55,24 @@ static SqlAuthentication create(SqlClient client, SqlAuthenticationOptions optio return new SqlAuthenticationImpl(client, options); } + /** + * Create a JDBC auth provider implementation that enriches the authenticated user with + * attributes extracted from the authentication query row. + *
+ * The authentication query is expected to return the password in the first column, any other
+ * column is available to the given {@code attributeMapper}. The JSON object returned by the
+ * mapper is merged into the {@link io.vertx.ext.auth.User#attributes()} of the authenticated
+ * user.
+ *
+ * @param client the JDBC client instance
+ * @param options authentication options
+ * @param attributeMapper maps the authenticated row to extra user attributes, may return {@code null}
+ * @return the auth provider
+ */
+ static SqlAuthentication create(SqlClient client, SqlAuthenticationOptions options, Function
diff --git a/vertx-auth-sql-client/src/main/java/io/vertx/ext/auth/sqlclient/impl/SqlAuthenticationImpl.java b/vertx-auth-sql-client/src/main/java/io/vertx/ext/auth/sqlclient/impl/SqlAuthenticationImpl.java
index 0716fa454..e71cba308 100644
--- a/vertx-auth-sql-client/src/main/java/io/vertx/ext/auth/sqlclient/impl/SqlAuthenticationImpl.java
+++ b/vertx-auth-sql-client/src/main/java/io/vertx/ext/auth/sqlclient/impl/SqlAuthenticationImpl.java
@@ -28,9 +28,12 @@
import io.vertx.sqlclient.SqlClient;
import io.vertx.sqlclient.Tuple;
+import io.vertx.core.json.JsonObject;
+
import java.util.Collections;
import java.util.Map;
import java.util.Objects;
+import java.util.function.Function;
/**
* @author Tim Fox
@@ -39,11 +42,17 @@ public class SqlAuthenticationImpl implements SqlAuthentication {
private final SqlClient client;
private final SqlAuthenticationOptions options;
+ private final Function