diff --git a/jpro-auth/example/src/main/java/one/jpro/platform/auth/example/login/LoginApp.java b/jpro-auth/example/src/main/java/one/jpro/platform/auth/example/login/LoginApp.java index 28a706e2..e2562baa 100644 --- a/jpro-auth/example/src/main/java/one/jpro/platform/auth/example/login/LoginApp.java +++ b/jpro-auth/example/src/main/java/one/jpro/platform/auth/example/login/LoginApp.java @@ -2,8 +2,6 @@ import atlantafx.base.theme.CupertinoLight; import com.jpro.webapi.WebAPI; -import javafx.beans.property.ObjectProperty; -import javafx.beans.property.SimpleObjectProperty; import javafx.collections.ObservableMap; import one.jpro.platform.auth.core.AuthAPI; import one.jpro.platform.auth.core.authentication.User; @@ -12,7 +10,7 @@ import one.jpro.platform.auth.example.login.page.LoginPage; import one.jpro.platform.auth.example.login.page.SignedInPage; import one.jpro.platform.auth.example.oauth.OAuthApp; -import one.jpro.platform.auth.routing.AuthFilters; +import one.jpro.platform.auth.routing.OAuth2Filter; import one.jpro.platform.routing.Redirect; import one.jpro.platform.routing.Route; import one.jpro.platform.routing.RouteApp; @@ -78,7 +76,7 @@ public Route createRoute() { .when((r) -> getUser() != null, Route.empty() .and(getNode("/user/signed-in", (r) -> new SignedInPage(this, googleAuthProvider)))) .filter(DevFilter.create()) - .filter(AuthFilters.oauth2(googleAuthProvider, googleCredentials, user -> { + .filter(OAuth2Filter.create(googleAuthProvider, googleCredentials, user -> { setUser(user); return FXFuture.unit(new Redirect("/user/signed-in")); }, error -> FXFuture.unit(viewFromNode(new ErrorPage(error))))); diff --git a/jpro-auth/example/src/main/java/one/jpro/platform/auth/example/login/page/SignedInPage.java b/jpro-auth/example/src/main/java/one/jpro/platform/auth/example/login/page/SignedInPage.java index 7aeac2a4..453b92c7 100644 --- a/jpro-auth/example/src/main/java/one/jpro/platform/auth/example/login/page/SignedInPage.java +++ b/jpro-auth/example/src/main/java/one/jpro/platform/auth/example/login/page/SignedInPage.java @@ -1,6 +1,5 @@ package one.jpro.platform.auth.example.login.page; -import javafx.beans.binding.Bindings; import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.control.TextArea; diff --git a/jpro-auth/example/src/main/java/one/jpro/platform/auth/example/oauth/OAuthApp.java b/jpro-auth/example/src/main/java/one/jpro/platform/auth/example/oauth/OAuthApp.java index 6898398c..83c534f1 100644 --- a/jpro-auth/example/src/main/java/one/jpro/platform/auth/example/oauth/OAuthApp.java +++ b/jpro-auth/example/src/main/java/one/jpro/platform/auth/example/oauth/OAuthApp.java @@ -5,7 +5,7 @@ import one.jpro.platform.auth.core.oauth2.OAuth2AuthenticationProvider; import one.jpro.platform.auth.core.oauth2.OAuth2Credentials; import one.jpro.platform.auth.example.oauth.page.*; -import one.jpro.platform.auth.routing.AuthFilters; +import one.jpro.platform.auth.routing.OAuth2Filter; import one.jpro.platform.routing.Filter; import one.jpro.platform.routing.Redirect; import one.jpro.platform.routing.Route; @@ -90,9 +90,9 @@ public Route createRoute() { .and(getNode("/keycloak", (r) -> new AuthProviderDiscoveryPage(this, keycloakAuth))))) .filter(DevFilter.create()) .filter(StatisticsFilter.create()) - .filter(oauth2(googleAuth, googleCredentials)) - .filter(oauth2(microsoftAuth, microsoftCredentials)) - .filter(oauth2(keycloakAuth, keycloakCredentials)); + .filter(oauth2Filter(googleAuth, googleCredentials)) + .filter(oauth2Filter(microsoftAuth, microsoftCredentials)) + .filter(oauth2Filter(keycloakAuth, keycloakCredentials)); } /** @@ -105,8 +105,8 @@ public Route createRoute() { * @param credentials The OAuth2 credentials used for authentication. * @return A {@link Filter} object configured for OAuth2 authentication flow. */ - private Filter oauth2(OAuth2AuthenticationProvider authProvider, OAuth2Credentials credentials) { - return AuthFilters.oauth2(authProvider, credentials, user -> { + private Filter oauth2Filter(OAuth2AuthenticationProvider authProvider, OAuth2Credentials credentials) { + return OAuth2Filter.create(authProvider, credentials, user -> { setUser(user); setAuthProvider(authProvider); return FXFuture.unit(new Redirect(USER_CONSOLE_PATH)); diff --git a/jpro-auth/routing/src/main/java/one/jpro/platform/auth/routing/AuthFilters.java b/jpro-auth/routing/src/main/java/one/jpro/platform/auth/routing/JWTFilter.java similarity index 51% rename from jpro-auth/routing/src/main/java/one/jpro/platform/auth/routing/AuthFilters.java rename to jpro-auth/routing/src/main/java/one/jpro/platform/auth/routing/JWTFilter.java index bff3af83..b2c17048 100644 --- a/jpro-auth/routing/src/main/java/one/jpro/platform/auth/routing/AuthFilters.java +++ b/jpro-auth/routing/src/main/java/one/jpro/platform/auth/routing/JWTFilter.java @@ -14,11 +14,11 @@ import java.util.function.Function; /** - * Utility class with authorization filters used in the routing process. + * Defines a {@link Route} filter using JWT authentication mechanism. * * @author Besmir Beqiri */ -public final class AuthFilters { +public interface JWTFilter { /** * Creates {@link Route} filter from a given {@link OAuth2AuthenticationProvider}, @@ -33,12 +33,12 @@ public final class AuthFilters { * @param errorFunction operation on the given error argument * @return a {@link Filter} object */ - static Filter jwt(JWTAuthenticationProvider authProvider, - JSONObject credentials, - String authPath, - String tokenPath, - Function> userFunction, - Function> errorFunction) { + static Filter create(JWTAuthenticationProvider authProvider, + JSONObject credentials, + String authPath, + String tokenPath, + Function> userFunction, + Function> errorFunction) { Objects.requireNonNull(authProvider, "auth provider cannot be null"); Objects.requireNonNull(credentials, "credentials cannot be null"); Objects.requireNonNull(authPath, "authentication path cannot be null"); @@ -57,39 +57,4 @@ static Filter jwt(JWTAuthenticationProvider authProvider, } }; } - - /** - * Creates {@link Route} filter from a given {@link OAuth2AuthenticationProvider}, - * {@link OAuth2Credentials} and an operation a given user if the authentication - * is successful. - * - * @param authProvider the OAuth2 authentication provider - * @param credentials the OAuth2 credentials - * @param userFunction operation on the given user argument - * @param errorFunction operation on the given error argument - * @return a {@link Filter} object - */ - public static Filter oauth2(OAuth2AuthenticationProvider authProvider, - OAuth2Credentials credentials, - Function> userFunction, - Function> errorFunction) { - Objects.requireNonNull(authProvider, "auth provider can not be null"); - Objects.requireNonNull(credentials, "credentials can not be null"); - Objects.requireNonNull(userFunction, "user function can not be null"); - Objects.requireNonNull(errorFunction, "error function cannot be null"); - - return (route) -> (request) -> { - if (request.path().equals(credentials.getRedirectUri())) { - return FXFuture.fromJava(authProvider.authenticate(credentials)) - .flatMap(userFunction::apply) - .flatExceptionally(errorFunction::apply); - } else { - return route.apply(request); - } - }; - } - - private AuthFilters() { - // Hide the default constructor. - } } diff --git a/jpro-auth/routing/src/main/java/one/jpro/platform/auth/routing/OAuth2Filter.java b/jpro-auth/routing/src/main/java/one/jpro/platform/auth/routing/OAuth2Filter.java new file mode 100644 index 00000000..a2d9f977 --- /dev/null +++ b/jpro-auth/routing/src/main/java/one/jpro/platform/auth/routing/OAuth2Filter.java @@ -0,0 +1,51 @@ +package one.jpro.platform.auth.routing; + +import one.jpro.platform.auth.core.authentication.User; +import one.jpro.platform.auth.core.oauth2.OAuth2AuthenticationProvider; +import one.jpro.platform.auth.core.oauth2.OAuth2Credentials; +import one.jpro.platform.routing.Filter; +import one.jpro.platform.routing.Response; +import one.jpro.platform.routing.Route; +import simplefx.experimental.parts.FXFuture; + +import java.util.Objects; +import java.util.function.Function; + +/** + * Defines a {@link Route} filter using OAuth2 authentication mechanism. + * + * @author Besmir Beqiri + */ +public interface OAuth2Filter { + + /** + * Creates {@link Route} filter from a given {@link OAuth2AuthenticationProvider}, + * {@link OAuth2Credentials} and an operation a given user if the authentication + * is successful. + * + * @param authProvider the OAuth2 authentication provider + * @param credentials the OAuth2 credentials + * @param userFunction operation on the given user argument + * @param errorFunction operation on the given error argument + * @return a {@link Filter} object + */ + static Filter create(OAuth2AuthenticationProvider authProvider, + OAuth2Credentials credentials, + Function> userFunction, + Function> errorFunction) { + Objects.requireNonNull(authProvider, "auth provider can not be null"); + Objects.requireNonNull(credentials, "credentials can not be null"); + Objects.requireNonNull(userFunction, "user function can not be null"); + Objects.requireNonNull(errorFunction, "error function cannot be null"); + + return (route) -> (request) -> { + if (request.path().equals(credentials.getRedirectUri())) { + return FXFuture.fromJava(authProvider.authenticate(credentials)) + .flatMap(userFunction::apply) + .flatExceptionally(errorFunction::apply); + } else { + return route.apply(request); + } + }; + } +}