From 2e90b1fad0ffaee5ede7c230c24b74f325753e81 Mon Sep 17 00:00:00 2001 From: Michael Kohlsche <100409187+SiMiKohl@users.noreply.github.com> Date: Thu, 10 Mar 2022 17:16:23 +0100 Subject: [PATCH] Changes and rework for pac4j 5 (#239) * added .fbExcludeFilterFile to .gitignore, changed pac4j to 5.3.1, changed jersey-pac4j back to 2.35, added tests to jersey228-pac4j, reworked dependencies-management * Refactoring for SessionStore providers and simplified usage by providing an implementation specific feature * We will need Java 11 for pac4j 5 Co-authored-by: Michael Kohlsche --- .github/workflows/ci.yml | 2 +- .gitignore | 3 +- README.md | 17 +- core/pom.xml | 40 +++-- .../jax/rs/features/JaxRsConfigProvider.java | 5 +- .../features/JaxRsContextFactoryProvider.java | 19 +-- .../features/JaxRsSessionStoreProvider.java | 30 ++++ .../pac4j/jax/rs/features/Pac4JFeature.java | 46 ++++++ .../pac4j/jax/rs/filters/AbstractFilter.java | 30 ++-- .../pac4j/jax/rs/filters/CallbackFilter.java | 18 ++- .../rs/filters/JaxRsHttpActionAdapter.java | 20 +-- .../pac4j/jax/rs/filters/LogoutFilter.java | 19 ++- .../pac4j/jax/rs/filters/SecurityFilter.java | 40 +++-- .../jax/rs/helpers/RequestJaxRsContext.java | 21 ++- .../jax/rs/helpers/RequestProfileManager.java | 10 +- .../rs/pac4j/JaxRsAjaxRequestResolver.java | 6 +- .../org/pac4j/jax/rs/pac4j/JaxRsContext.java | 34 ++-- .../jax/rs/pac4j/JaxRsProfileManager.java | 24 ++- .../servlet/features/Pac4JServletFeature.java | 34 ++++ .../ServletJaxRsContextFactoryProvider.java | 6 +- .../features/ServletSessionStoreProvider.java | 29 ++++ .../rs/servlet/pac4j/ServletJaxRsContext.java | 18 ++- .../rs/servlet/pac4j/ServletSessionStore.java | 42 +++-- jersey/pom.xml | 46 ++++-- .../GrizzlyJaxRsContextFactoryProvider.java | 13 +- .../features/GrizzlySessionStoreProvider.java | 30 ++++ .../grizzly/features/Pac4JGrizzlyFeature.java | 34 ++++ .../rs/grizzly/pac4j/GrizzlyJaxRsContext.java | 17 +- .../rs/grizzly/pac4j/GrizzlySessionStore.java | 38 +++-- .../features/Pac4JValueFactoryProvider.java | 151 +++++++++-------- .../pac4j/jax/rs/rules/JerseyGrizzlyRule.java | 4 +- .../rs/rules/JerseyGrizzlyServletRule.java | 4 +- .../jax/rs/rules/JerseyInMemoryRule.java | 8 +- .../org/pac4j/jax/rs/rules/JerseyRule.java | 2 - jersey225/pom.xml | 48 +++++- .../GrizzlyJaxRsContextFactoryProvider.java | 7 +- .../features/GrizzlySessionStoreProvider.java | 30 ++++ .../grizzly/features/Pac4JGrizzlyFeature.java | 34 ++++ .../rs/grizzly/pac4j/GrizzlyJaxRsContext.java | 17 +- .../rs/grizzly/pac4j/GrizzlySessionStore.java | 42 +++-- .../features/Pac4JValueFactoryProvider.java | 48 +++--- .../pac4j/jax/rs/rules/JerseyGrizzlyRule.java | 4 +- .../rs/rules/JerseyGrizzlyServletRule.java | 4 +- .../jax/rs/rules/JerseyInMemoryRule.java | 8 +- .../org/pac4j/jax/rs/rules/JerseyRule.java | 2 - jersey228/pom.xml | 67 ++++++-- .../GrizzlyJaxRsContextFactoryProvider.java | 13 +- .../features/GrizzlySessionStoreProvider.java | 30 ++++ .../grizzly/features/Pac4JGrizzlyFeature.java | 34 ++++ .../rs/grizzly/pac4j/GrizzlyJaxRsContext.java | 23 +-- .../rs/grizzly/pac4j/GrizzlySessionStore.java | 44 +++-- .../features/Pac4JValueFactoryProvider.java | 152 +++++++++--------- .../jax/rs/JerseyGrizzlyServletTest.java | 17 ++ .../org/pac4j/jax/rs/JerseyGrizzlyTest.java | 17 ++ .../org/pac4j/jax/rs/JerseyInMemoryTest.java | 17 ++ .../jax/rs/resources/JerseyResource.java | 56 +++++++ .../pac4j/jax/rs/rules/JerseyGrizzlyRule.java | 38 +++++ .../rs/rules/JerseyGrizzlyServletRule.java | 40 +++++ .../jax/rs/rules/JerseyInMemoryRule.java | 46 ++++++ .../org/pac4j/jax/rs/rules/JerseyRule.java | 76 +++++++++ pom.xml | 47 ++++-- resteasy/pom.xml | 119 ++++++++++---- .../features/Pac4JProfileInjectorFactory.java | 27 +++- .../helpers/RestEasyRequestContext.java | 3 +- .../rs/rules/RestEasyUndertowServletRule.java | 6 +- spotbugs-exclude.xml | 1 - testing/pom.xml | 35 ++-- .../java/org/pac4j/jax/rs/TestConfig.java | 14 +- .../jax/rs/resources/TestProxyResource.java | 7 +- .../pac4j/jax/rs/resources/TestResource.java | 7 +- 70 files changed, 1482 insertions(+), 558 deletions(-) create mode 100644 core/src/main/java/org/pac4j/jax/rs/features/JaxRsSessionStoreProvider.java create mode 100644 core/src/main/java/org/pac4j/jax/rs/features/Pac4JFeature.java create mode 100644 core/src/main/java/org/pac4j/jax/rs/servlet/features/Pac4JServletFeature.java create mode 100644 core/src/main/java/org/pac4j/jax/rs/servlet/features/ServletSessionStoreProvider.java create mode 100644 jersey/src/main/java/org/pac4j/jax/rs/grizzly/features/GrizzlySessionStoreProvider.java create mode 100644 jersey/src/main/java/org/pac4j/jax/rs/grizzly/features/Pac4JGrizzlyFeature.java create mode 100644 jersey225/src/main/java/org/pac4j/jax/rs/grizzly/features/GrizzlySessionStoreProvider.java create mode 100644 jersey225/src/main/java/org/pac4j/jax/rs/grizzly/features/Pac4JGrizzlyFeature.java create mode 100644 jersey228/src/main/java/org/pac4j/jax/rs/grizzly/features/GrizzlySessionStoreProvider.java create mode 100644 jersey228/src/main/java/org/pac4j/jax/rs/grizzly/features/Pac4JGrizzlyFeature.java create mode 100644 jersey228/src/test/java/org/pac4j/jax/rs/JerseyGrizzlyServletTest.java create mode 100644 jersey228/src/test/java/org/pac4j/jax/rs/JerseyGrizzlyTest.java create mode 100644 jersey228/src/test/java/org/pac4j/jax/rs/JerseyInMemoryTest.java create mode 100644 jersey228/src/test/java/org/pac4j/jax/rs/resources/JerseyResource.java create mode 100644 jersey228/src/test/java/org/pac4j/jax/rs/rules/JerseyGrizzlyRule.java create mode 100644 jersey228/src/test/java/org/pac4j/jax/rs/rules/JerseyGrizzlyServletRule.java create mode 100644 jersey228/src/test/java/org/pac4j/jax/rs/rules/JerseyInMemoryRule.java create mode 100644 jersey228/src/test/java/org/pac4j/jax/rs/rules/JerseyRule.java diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fabdd62..12a446f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,7 +1,7 @@ name: Java CI env: - JDK_CURRENT: 8 + JDK_CURRENT: 11 DISTRIBUTION: zulu on: diff --git a/.gitignore b/.gitignore index 9139863..c2fbd16 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,5 @@ target/ jax-rs-pac4j.iml .pmd .pmdruleset.xml -*.iml \ No newline at end of file +*.iml +.fbExcludeFilterFile \ No newline at end of file diff --git a/README.md b/README.md index 09c9c1b..19eddc1 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ The `jax-rs-pac4j` project is an **easy and powerful security library for JAX-RS web applications and web services** which supports authentication and authorization, but also logout and advanced features like session fixation and CSRF protection. -It's based on Java 8, servlet 3 (when present), JAX-RS 2 and on the **[pac4j security engine](https://github.com/pac4j/pac4j) v4**. It's available under the Apache 2 license. +It's based on Java 11, servlet 4 (when present), JAX-RS 2 and on the **[pac4j security engine](https://github.com/pac4j/pac4j) v5**. It's available under the Apache 2 license. [**Main concepts and components:**](http://www.pac4j.org/docs/main-concepts-and-components.html) @@ -28,15 +28,22 @@ These filters can be directly registered by hand, or instead, the following feat 5) Generic JAX-RS Providers and Features activate the use of some of the filters on the JAX-RS implementation based on various conditions -- The `JaxRsContextFactoryProvider` enables generic JAX-RS based pac4j functioning, without session handling (i.e., it will only work with direct clients) +- The `Pac4JFeature` enables generic JAX-RS based pac4j functionality. The default configuration does not provide session handling (i.e., it will only work with direct clients). The feature registers the following default providers: + - `JaxRsContextFactoryProvider` to create the generic pac4j context for JAX-RS + - `JaxRsConfigProvider` to provide the pac4j configuration + - `JaxRsSessionStoreProvider` to provide the configured pac4j `SessionStore` + + - The `Pac4JSecurityFeature` enables annotation-based activation of the filters at the resource method level - The `Pac4JSecurityFilterFeature` activates a global filter that will be applied to every resources. 6) Container/Implementation-specific Providers and Features extend the basic functionality provided by the generic ones - The `Pac4JValueFactoryProvider` enables injection of the security profile in resource method -- The `ServletJaxRsContextFactoryProvider` provides session handling (and thus indirect clients support) by replacing the generic `JaxRsContextFactoryProvider` (for Servlet-based JAX-RS implementations, e.g., Jersey on Netty or Grizzly Servlet, Resteasy on Undertow). -- The `GrizzlyJaxRsContextFactoryProvider` provides session handling (and thus indirect clients support) by replacing the generic `JaxRsContextFactoryProvider` (for Grizzly2 without Servlet support). + +- The `Pac4JServletFeature` provides session handling (and thus indirect clients support) by replacing the generic `JaxRsContextFactoryProvider` with `ServletJaxRsContextFactoryProvider` (for Servlet-based JAX-RS implementations, e.g., Jersey on Netty or Grizzly Servlet, Resteasy on Undertow) and `JaxRsSessionStoreProvider` with `ServletSessionStoreProvider`. + +- The `Pac4JGrizzlyFeature` provides session handling (and thus indirect clients support) by replacing the generic `JaxRsContextFactoryProvider` with `GrizzlyJaxRsContextFactoryProvider` (for Grizzly2 without Servlet support) and `JaxRsSessionStoreProvider` with `GrizzlySessionStoreProvider`. ## Usage @@ -59,7 +66,7 @@ These filters can be directly registered by hand, or instead, the following feat The latest released version is the [![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.pac4j.jax-rs/core/badge.svg?style=flat)](https://maven-badges.herokuapp.com/maven-central/org.pac4j.jax-rs/core), available in the [Maven central repository](https://repo.maven.apache.org/maven2). The [next version](https://github.com/pac4j/jax-rs-pac4j/wiki/Next-version) is under development. -See the [release notes](https://github.com/pac4j/jax-rs-pac4j/wiki/Release-Notes). Learn more by browsing the [pac4j documentation](https://www.javadoc.io/doc/org.pac4j/pac4j-core/4.0.0/index.html) and the [jax-rs-pac4j Javadoc](http://www.javadoc.io/doc/org.pac4j.jax-rs/core/4.0.0). +See the [release notes](https://github.com/pac4j/jax-rs-pac4j/wiki/Release-Notes). Learn more by browsing the [pac4j documentation](https://www.javadoc.io/doc/org.pac4j/pac4j-core/5.0.0/index.html) and the [jax-rs-pac4j Javadoc](http://www.javadoc.io/doc/org.pac4j.jax-rs/core/4.0.0). See the [migration guide](https://github.com/pac4j/jax-rs-pac4j/wiki/Migration-guide) as well. diff --git a/core/pom.xml b/core/pom.xml index 934655c..eed738f 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -8,40 +8,51 @@ core + + 2.1.6 + 1.3.5 + 1.0.5 + 4.0.4 + + 2.2 + + - javax.ws.rs - javax.ws.rs-api - 2.0.1 + jakarta.ws.rs + jakarta.ws.rs-api + ${ws.rs-api.version} provided - javax.annotation - javax.annotation-api - 1.2 + jakarta.annotation + jakarta.annotation-api + ${annotation-api.version} provided - javax.inject - javax.inject - 1 + jakarta.inject + jakarta.inject-api + ${inject-api.version} org.pac4j pac4j-core + - javax.servlet - javax.servlet-api - 3.0.1 + jakarta.servlet + jakarta.servlet-api + ${servlet-api.version} provided true + + junit junit - 4.12 test @@ -53,12 +64,13 @@ org.hamcrest hamcrest-core - 2.2 + ${hamcrest.version} test org.mockito mockito-core + test \ No newline at end of file diff --git a/core/src/main/java/org/pac4j/jax/rs/features/JaxRsConfigProvider.java b/core/src/main/java/org/pac4j/jax/rs/features/JaxRsConfigProvider.java index d4b0d04..13dec6d 100644 --- a/core/src/main/java/org/pac4j/jax/rs/features/JaxRsConfigProvider.java +++ b/core/src/main/java/org/pac4j/jax/rs/features/JaxRsConfigProvider.java @@ -6,7 +6,8 @@ /** * - * This class can be used to inject the pac4j {@link Config} in the JAX-RS runtime. + * This class can be used to inject the pac4j {@link Config} in the JAX-RS + * runtime. * * @author Victor Noel - Linagora * @since 2.0.0 @@ -18,7 +19,7 @@ public class JaxRsConfigProvider implements ContextResolver { public JaxRsConfigProvider(Config config) { this.config = config; } - + @Override public Config getContext(Class type) { return config; diff --git a/core/src/main/java/org/pac4j/jax/rs/features/JaxRsContextFactoryProvider.java b/core/src/main/java/org/pac4j/jax/rs/features/JaxRsContextFactoryProvider.java index 25d65d5..a2d5542 100644 --- a/core/src/main/java/org/pac4j/jax/rs/features/JaxRsContextFactoryProvider.java +++ b/core/src/main/java/org/pac4j/jax/rs/features/JaxRsContextFactoryProvider.java @@ -5,18 +5,13 @@ import javax.ws.rs.ext.ContextResolver; import javax.ws.rs.ext.Providers; -import org.pac4j.core.client.IndirectClient; -import org.pac4j.core.config.Config; import org.pac4j.jax.rs.features.JaxRsContextFactoryProvider.JaxRsContextFactory; -import org.pac4j.jax.rs.helpers.ProvidersContext; import org.pac4j.jax.rs.pac4j.JaxRsContext; /** * - * This provides to the JAX-RS runtime a way to build a {@link JaxRsContext} adequate for the container. - * - * This is the generic implementation and will not support session management (and hence won't support pac4j - * {@link IndirectClient}). + * This provides the JAX-RS runtime a way to build a {@link JaxRsContext} + * adequate for the container. * * This can be subclassed for specific containers. * @@ -30,7 +25,7 @@ public class JaxRsContextFactoryProvider implements ContextResolver type) { - return context -> new JaxRsContext(getProviders(), context, getConfig().getSessionStore()); + return context -> new JaxRsContext(getProviders(), context); } protected Providers getProviders() { @@ -38,13 +33,9 @@ protected Providers getProviders() { return providers; } - protected Config getConfig() { - return new ProvidersContext(providers).resolveNotNull(Config.class); - } - /** - * We need to provide a factory because it is not possible to get the {@link ContainerRequestContext} injected - * directly here... + * We need to provide a factory because it is not possible to get the + * {@link ContainerRequestContext} injected directly here... */ @FunctionalInterface public interface JaxRsContextFactory { diff --git a/core/src/main/java/org/pac4j/jax/rs/features/JaxRsSessionStoreProvider.java b/core/src/main/java/org/pac4j/jax/rs/features/JaxRsSessionStoreProvider.java new file mode 100644 index 0000000..d8068f3 --- /dev/null +++ b/core/src/main/java/org/pac4j/jax/rs/features/JaxRsSessionStoreProvider.java @@ -0,0 +1,30 @@ +package org.pac4j.jax.rs.features; + +import javax.ws.rs.ext.ContextResolver; + +import org.pac4j.core.config.Config; +import org.pac4j.core.context.session.SessionStore; + +/** + * This class can be used to inject the pac4j {@link SessionStore} in the + * JAX-RS runtime. + * + * This can be subclassed for container specific implementations. + * + * @author Michael Kohlsche + * @since 5.0.0 + */ +public class JaxRsSessionStoreProvider implements ContextResolver { + + protected final Config config; + + public JaxRsSessionStoreProvider(Config config) { + this.config = config; + } + + @Override + public SessionStore getContext(Class type) { + return config.getSessionStore(); + } + +} diff --git a/core/src/main/java/org/pac4j/jax/rs/features/Pac4JFeature.java b/core/src/main/java/org/pac4j/jax/rs/features/Pac4JFeature.java new file mode 100644 index 0000000..8686056 --- /dev/null +++ b/core/src/main/java/org/pac4j/jax/rs/features/Pac4JFeature.java @@ -0,0 +1,46 @@ +package org.pac4j.jax.rs.features; + +import javax.ws.rs.core.Feature; +import javax.ws.rs.core.FeatureContext; + +import org.pac4j.core.config.Config; + +/** + * This feature can be used to register the default set of necessary providers. + * + * This should be subclassed for container specific implementations and override + * the necessary registration methods. + * + * @author Michael Kohlsche + * @since 5.0.0 + */ +public class Pac4JFeature implements Feature { + + protected final Config config; + + public Pac4JFeature(Config config) { + this.config = config; + } + + @Override + public boolean configure(FeatureContext context) { + return registerConfigProvider(context) && registerSessionStoreProvider(context) + && registerContextFactoryProvider(context); + } + + protected boolean registerConfigProvider(FeatureContext context) { + context.register(new JaxRsConfigProvider(config)); + return true; + } + + protected boolean registerContextFactoryProvider(FeatureContext context) { + context.register(JaxRsContextFactoryProvider.class); + return true; + } + + protected boolean registerSessionStoreProvider(FeatureContext context) { + context.register(new JaxRsSessionStoreProvider(config)); + return true; + } + +} diff --git a/core/src/main/java/org/pac4j/jax/rs/filters/AbstractFilter.java b/core/src/main/java/org/pac4j/jax/rs/filters/AbstractFilter.java index 3cf25c7..56547ee 100644 --- a/core/src/main/java/org/pac4j/jax/rs/filters/AbstractFilter.java +++ b/core/src/main/java/org/pac4j/jax/rs/filters/AbstractFilter.java @@ -10,6 +10,7 @@ import org.pac4j.core.authorization.authorizer.Authorizer; import org.pac4j.core.config.Config; +import org.pac4j.core.context.session.SessionStore; import org.pac4j.core.http.adapter.HttpActionAdapter; import org.pac4j.jax.rs.helpers.ProvidersContext; import org.pac4j.jax.rs.helpers.RequestJaxRsContext; @@ -35,6 +36,10 @@ protected Config getConfig() { return new ProvidersContext(providers).resolveNotNull(Config.class); } + protected SessionStore getSessionStore() { + return new ProvidersContext(providers).resolveNotNull(SessionStore.class); + } + protected abstract void filter(JaxRsContext context) throws IOException; @Override @@ -45,9 +50,12 @@ public void filter(ContainerRequestContext requestContext) throws IOException { @Override public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException { - // in case the filter aborts the request, we never arrive here, but if it is not aborted - // there is case when pac4j sets things on the response, this is the role of this method. - // unfortunately, if skipResponse is used, we can't do that because pac4j considers + // in case the filter aborts the request, we never arrive here, but if it is not + // aborted + // there is case when pac4j sets things on the response, this is the role of + // this method. + // unfortunately, if skipResponse is used, we can't do that because pac4j + // considers // its abort response in the same way as the normal response if (skipResponse == null || !skipResponse) { new RequestJaxRsContext(providers, requestContext).contextOrNew().getResponseHolder() @@ -56,13 +64,14 @@ public void filter(ContainerRequestContext requestContext, ContainerResponseCont } /** - * Prefer to set a specific {@link HttpActionAdapter} on the {@link Config} instead of overriding this method. + * Prefer to set a specific {@link HttpActionAdapter} on the {@link Config} + * instead of overriding this method. * * @param config the security configuration * * @return an {@link HttpActionAdapter} */ - protected HttpActionAdapter adapter(Config config) { + protected HttpActionAdapter adapter(Config config) { final HttpActionAdapter adapter; if (config.getHttpActionAdapter() != null) { @@ -84,12 +93,13 @@ public Boolean isSkipResponse() { } /** - * Note that if this is set to true, this will also disable the effects of {@link Authorizer} and such - * that set things on the HTTP response! Use with caution! + * Note that if this is set to true, this will also disable the + * effects of {@link Authorizer} and such that set things on the HTTP response! + * Use with caution! * - * @param skipResponse - * If set to true, the pac4j response, such as redirect, will be skipped (the annotated - * method will be executed instead). + * @param skipResponse If set to true, the pac4j response, such as + * redirect, will be skipped (the annotated method will be + * executed instead). */ public void setSkipResponse(Boolean skipResponse) { this.skipResponse = skipResponse; diff --git a/core/src/main/java/org/pac4j/jax/rs/filters/CallbackFilter.java b/core/src/main/java/org/pac4j/jax/rs/filters/CallbackFilter.java index 2ef6912..f2af7b0 100644 --- a/core/src/main/java/org/pac4j/jax/rs/filters/CallbackFilter.java +++ b/core/src/main/java/org/pac4j/jax/rs/filters/CallbackFilter.java @@ -7,6 +7,7 @@ import javax.ws.rs.ext.Providers; import org.pac4j.core.config.Config; +import org.pac4j.core.context.session.SessionStore; import org.pac4j.core.engine.CallbackLogic; import org.pac4j.core.engine.DefaultCallbackLogic; import org.pac4j.jax.rs.pac4j.JaxRsContext; @@ -21,7 +22,7 @@ @Priority(Priorities.AUTHORIZATION) public class CallbackFilter extends AbstractFilter { - private CallbackLogic callbackLogic; + private CallbackLogic callbackLogic; private String defaultUrl; @@ -40,28 +41,29 @@ public CallbackFilter(Providers providers) { @Override protected void filter(JaxRsContext context) throws IOException { Config config = getConfig(); + SessionStore sessionStore = getSessionStore(); - buildLogic(config).perform(context, config, adapter(config), context.getAbsolutePath(defaultUrl, false), - saveInSession, multiProfile, renewSession, defaultClient); + buildLogic(config).perform(context, sessionStore, config, adapter(config), + context.getAbsolutePath(defaultUrl, false), renewSession, defaultClient); } - protected CallbackLogic buildLogic(Config config) { + protected CallbackLogic buildLogic(Config config) { if (callbackLogic != null) { return callbackLogic; } else if (config.getCallbackLogic() != null) { return config.getCallbackLogic(); } else { - DefaultCallbackLogic logic = new DefaultCallbackLogic<>(); - logic.setProfileManagerFactory(ctx -> new JaxRsProfileManager((JaxRsContext) ctx)); + DefaultCallbackLogic logic = new DefaultCallbackLogic(); + logic.setProfileManagerFactory((ctx, sessionStore) -> new JaxRsProfileManager(ctx, sessionStore)); return logic; } } - public CallbackLogic getCallbackLogic() { + public CallbackLogic getCallbackLogic() { return callbackLogic; } - public void setCallbackLogic(CallbackLogic callbackLogic) { + public void setCallbackLogic(CallbackLogic callbackLogic) { this.callbackLogic = callbackLogic; } diff --git a/core/src/main/java/org/pac4j/jax/rs/filters/JaxRsHttpActionAdapter.java b/core/src/main/java/org/pac4j/jax/rs/filters/JaxRsHttpActionAdapter.java index 828f4a2..da38d64 100644 --- a/core/src/main/java/org/pac4j/jax/rs/filters/JaxRsHttpActionAdapter.java +++ b/core/src/main/java/org/pac4j/jax/rs/filters/JaxRsHttpActionAdapter.java @@ -3,6 +3,7 @@ import javax.ws.rs.core.Response; import org.pac4j.core.context.HttpConstants; +import org.pac4j.core.context.WebContext; import org.pac4j.core.exception.TechnicalException; import org.pac4j.core.exception.http.HttpAction; import org.pac4j.core.exception.http.WithContentAction; @@ -16,26 +17,27 @@ * @since 1.1.1 * */ -public class JaxRsHttpActionAdapter implements HttpActionAdapter { +public class JaxRsHttpActionAdapter implements HttpActionAdapter { public static final JaxRsHttpActionAdapter INSTANCE = new JaxRsHttpActionAdapter(); @Override - public Object adapt(final HttpAction action, final JaxRsContext context) { - if (action != null) { + public Object adapt(final HttpAction action, final WebContext context) { + if (action != null && context instanceof JaxRsContext) { + JaxRsContext jaxRsContext = (JaxRsContext) context; final int code = action.getCode(); - context.getAbortBuilder().status(code); - context.getResponseHolder().setResponseStatus(code); + jaxRsContext.getAbortBuilder().status(code); + jaxRsContext.getResponseHolder().setResponseStatus(code); if (action instanceof WithLocationAction) { final WithLocationAction withLocationAction = (WithLocationAction) action; context.setResponseHeader(HttpConstants.LOCATION_HEADER, withLocationAction.getLocation()); } else if (action instanceof WithContentAction) { final String content = ((WithContentAction) action).getContent(); - context.getAbortBuilder().entity(content); - context.getResponseHolder().writeResponseContent(content); + jaxRsContext.getAbortBuilder().entity(content); + jaxRsContext.getResponseHolder().writeResponseContent(content); } - Response response = context.getAbortBuilder().build(); - context.getRequestContext().abortWith(response); + Response response = jaxRsContext.getAbortBuilder().build(); + jaxRsContext.getRequestContext().abortWith(response); return null; } diff --git a/core/src/main/java/org/pac4j/jax/rs/filters/LogoutFilter.java b/core/src/main/java/org/pac4j/jax/rs/filters/LogoutFilter.java index 98d9d85..42639d6 100644 --- a/core/src/main/java/org/pac4j/jax/rs/filters/LogoutFilter.java +++ b/core/src/main/java/org/pac4j/jax/rs/filters/LogoutFilter.java @@ -7,6 +7,7 @@ import javax.ws.rs.ext.Providers; import org.pac4j.core.config.Config; +import org.pac4j.core.context.session.SessionStore; import org.pac4j.core.engine.DefaultLogoutLogic; import org.pac4j.core.engine.LogoutLogic; import org.pac4j.jax.rs.pac4j.JaxRsContext; @@ -21,7 +22,7 @@ @Priority(Priorities.AUTHORIZATION) public class LogoutFilter extends AbstractFilter { - private LogoutLogic logoutLogic; + private LogoutLogic logoutLogic; private String defaultUrl; @@ -40,19 +41,21 @@ public LogoutFilter(Providers providers) { @Override protected void filter(JaxRsContext context) throws IOException { Config config = getConfig(); + SessionStore sessionStore = getSessionStore(); - buildLogic(config).perform(context, config, adapter(config), context.getAbsolutePath(defaultUrl, false), - context.getAbsolutePath(logoutUrlPattern, false), localLogout, destroySession, centralLogout); + buildLogic(config).perform(context, sessionStore, config, adapter(config), + context.getAbsolutePath(defaultUrl, false), context.getAbsolutePath(logoutUrlPattern, false), + localLogout, destroySession, centralLogout); } - protected LogoutLogic buildLogic(Config config) { + protected LogoutLogic buildLogic(Config config) { if (logoutLogic != null) { return logoutLogic; } else if (config.getLogoutLogic() != null) { return config.getLogoutLogic(); } else { - DefaultLogoutLogic logic = new DefaultLogoutLogic<>(); - logic.setProfileManagerFactory(ctx -> new JaxRsProfileManager((JaxRsContext) ctx)); + DefaultLogoutLogic logic = new DefaultLogoutLogic(); + logic.setProfileManagerFactory((ctx, sessionStore) -> new JaxRsProfileManager(ctx, sessionStore)); return logic; } @@ -98,11 +101,11 @@ public void setCentralLogout(Boolean centralLogout) { this.centralLogout = centralLogout; } - public LogoutLogic getLogoutLogic() { + public LogoutLogic getLogoutLogic() { return logoutLogic; } - public void setLogoutLogic(LogoutLogic applicationLogoutLogic) { + public void setLogoutLogic(LogoutLogic applicationLogoutLogic) { this.logoutLogic = applicationLogoutLogic; } } diff --git a/core/src/main/java/org/pac4j/jax/rs/filters/SecurityFilter.java b/core/src/main/java/org/pac4j/jax/rs/filters/SecurityFilter.java index 94e800f..6e14be6 100644 --- a/core/src/main/java/org/pac4j/jax/rs/filters/SecurityFilter.java +++ b/core/src/main/java/org/pac4j/jax/rs/filters/SecurityFilter.java @@ -9,6 +9,8 @@ import javax.ws.rs.ext.Providers; import org.pac4j.core.config.Config; +import org.pac4j.core.context.WebContext; +import org.pac4j.core.context.session.SessionStore; import org.pac4j.core.engine.DefaultSecurityLogic; import org.pac4j.core.engine.SecurityGrantedAccessAdapter; import org.pac4j.core.engine.SecurityLogic; @@ -19,8 +21,8 @@ /** * - * TODO this is missing a way to influence URL's prefix for the used clients and authorizers (this is a pac4j - * limitation) + * TODO this is missing a way to influence URL's prefix for the used clients and + * authorizers (this is a pac4j limitation) * * @author Victor Noel - Linagora * @since 1.0.0 @@ -29,7 +31,7 @@ @Priority(Priorities.AUTHENTICATION) public class SecurityFilter extends AbstractFilter { - private SecurityLogic securityLogic; + private SecurityLogic securityLogic; private String clients; @@ -45,25 +47,26 @@ public SecurityFilter(Providers providers) { @Override protected void filter(JaxRsContext context) throws IOException { - Config config = getConfig(); + SessionStore sessionStore = getSessionStore(); // Note: basically, there is two possible outcomes: // either the access is granted or there was an error or a redirect! // For the former, we do nothing (see SecurityGrantedAccessOutcome comments) - // For the later, we interpret the error and abort the request using jax-rs abstractions - buildLogic(config).perform(context, config, new SecurityGrantedAccessOutcome(), adapter(config), clients, - authorizers, matchers, multiProfile); + // For the later, we interpret the error and abort the request using jax-rs + // abstractions + buildLogic(config).perform(context, sessionStore, config, new SecurityGrantedAccessOutcome(), adapter(config), + clients, authorizers, matchers, multiProfile); } - protected SecurityLogic buildLogic(Config config) { + protected SecurityLogic buildLogic(Config config) { if (securityLogic != null) { return securityLogic; } else if (config.getSecurityLogic() != null) { return config.getSecurityLogic(); } else { - DefaultSecurityLogic logic = new DefaultSecurityLogic<>(); - logic.setProfileManagerFactory(ctx -> new JaxRsProfileManager((JaxRsContext) ctx)); + DefaultSecurityLogic logic = new DefaultSecurityLogic(); + logic.setProfileManagerFactory((ctx, sessionStore) -> new JaxRsProfileManager(ctx, sessionStore)); return logic; } } @@ -100,19 +103,24 @@ public void setMultiProfile(Boolean multiProfile) { this.multiProfile = multiProfile; } - public SecurityLogic getSecurityLogic() { + public SecurityLogic getSecurityLogic() { return securityLogic; } - public void setSecurityLogic(SecurityLogic securityLogic) { + public void setSecurityLogic(SecurityLogic securityLogic) { this.securityLogic = securityLogic; } - private static class SecurityGrantedAccessOutcome implements SecurityGrantedAccessAdapter { + private static class SecurityGrantedAccessOutcome implements SecurityGrantedAccessAdapter { @Override - public Object adapt(JaxRsContext context, Collection profiles, Object... parameters) { - SecurityContext original = context.getRequestContext().getSecurityContext(); - context.getRequestContext().setSecurityContext(new Pac4JSecurityContext(original, context, profiles)); + public Object adapt(WebContext context, SessionStore sessionStore, Collection profiles, + Object... parameters) { + if (context instanceof JaxRsContext) { + JaxRsContext jaxRsContext = (JaxRsContext) context; + SecurityContext original = jaxRsContext.getRequestContext().getSecurityContext(); + jaxRsContext.getRequestContext() + .setSecurityContext(new Pac4JSecurityContext(original, jaxRsContext, profiles)); + } return null; } } diff --git a/core/src/main/java/org/pac4j/jax/rs/helpers/RequestJaxRsContext.java b/core/src/main/java/org/pac4j/jax/rs/helpers/RequestJaxRsContext.java index 0d24186..68881d5 100644 --- a/core/src/main/java/org/pac4j/jax/rs/helpers/RequestJaxRsContext.java +++ b/core/src/main/java/org/pac4j/jax/rs/helpers/RequestJaxRsContext.java @@ -15,16 +15,31 @@ */ public class RequestJaxRsContext { - private final ProvidersContext providers; - private final ContainerRequestContext context; + private ProvidersContext providers; + private ContainerRequestContext context; + + private JaxRsContext jaxContext; public RequestJaxRsContext(Providers providers, ContainerRequestContext context) { this.providers = new ProvidersContext(providers); this.context = context; } + public RequestJaxRsContext(JaxRsContext context) { + this.jaxContext = context; + } + + public ProvidersContext getProviders() { + return providers; + } + + public ContainerRequestContext getContainerRequestContext() { + return context; + } + public Optional context() { - return new RequestPac4JSecurityContext(context).context().map(Pac4JSecurityContext::getContext); + return jaxContext != null ? Optional.of(jaxContext) + : new RequestPac4JSecurityContext(context).context().map(Pac4JSecurityContext::getContext); } public JaxRsContext contextOrNew() { diff --git a/core/src/main/java/org/pac4j/jax/rs/helpers/RequestProfileManager.java b/core/src/main/java/org/pac4j/jax/rs/helpers/RequestProfileManager.java index 75d8972..0fa21a0 100644 --- a/core/src/main/java/org/pac4j/jax/rs/helpers/RequestProfileManager.java +++ b/core/src/main/java/org/pac4j/jax/rs/helpers/RequestProfileManager.java @@ -1,5 +1,7 @@ package org.pac4j.jax.rs.helpers; +import org.pac4j.core.context.session.SessionStore; +import org.pac4j.jax.rs.pac4j.JaxRsContext; import org.pac4j.jax.rs.pac4j.JaxRsProfileManager; /** @@ -8,13 +10,15 @@ */ public class RequestProfileManager { - private final RequestJaxRsContext context; + private final JaxRsContext context; + private final SessionStore sessionStore; - public RequestProfileManager(RequestJaxRsContext context) { + public RequestProfileManager(JaxRsContext context, SessionStore sessionStore) { this.context = context; + this.sessionStore = sessionStore; } public JaxRsProfileManager profileManager() { - return new JaxRsProfileManager(context.contextOrNew()); + return new JaxRsProfileManager(context, sessionStore); } } diff --git a/core/src/main/java/org/pac4j/jax/rs/pac4j/JaxRsAjaxRequestResolver.java b/core/src/main/java/org/pac4j/jax/rs/pac4j/JaxRsAjaxRequestResolver.java index 778be76..374ca6b 100644 --- a/core/src/main/java/org/pac4j/jax/rs/pac4j/JaxRsAjaxRequestResolver.java +++ b/core/src/main/java/org/pac4j/jax/rs/pac4j/JaxRsAjaxRequestResolver.java @@ -1,11 +1,13 @@ package org.pac4j.jax.rs.pac4j; import org.pac4j.core.context.WebContext; +import org.pac4j.core.context.session.SessionStore; import org.pac4j.core.http.ajax.DefaultAjaxRequestResolver; /** * - * This can be used by applications to ensure that pac4j always answers with 401 instead of redirect. + * This can be used by applications to ensure that pac4j always answers with 401 + * instead of redirect. * * @author Victor Noel * @since 3.0.0 @@ -13,7 +15,7 @@ */ public class JaxRsAjaxRequestResolver extends DefaultAjaxRequestResolver { @Override - public boolean isAjax(WebContext context) { + public boolean isAjax(WebContext context, SessionStore sessionStore) { return true; } } diff --git a/core/src/main/java/org/pac4j/jax/rs/pac4j/JaxRsContext.java b/core/src/main/java/org/pac4j/jax/rs/pac4j/JaxRsContext.java index 2cfcf77..de02918 100644 --- a/core/src/main/java/org/pac4j/jax/rs/pac4j/JaxRsContext.java +++ b/core/src/main/java/org/pac4j/jax/rs/pac4j/JaxRsContext.java @@ -9,8 +9,13 @@ import java.lang.annotation.Annotation; import java.net.URI; import java.nio.charset.Charset; -import java.util.*; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; import java.util.Map.Entry; +import java.util.Optional; +import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; @@ -28,7 +33,6 @@ import org.pac4j.core.context.Cookie; import org.pac4j.core.context.WebContext; -import org.pac4j.core.context.session.SessionStore; import org.pac4j.core.exception.TechnicalException; import org.pac4j.core.util.CommonHelper; @@ -44,18 +48,15 @@ public class JaxRsContext implements WebContext { private final ContainerRequestContext requestContext; - private final SessionStore sessionStore; - private final Providers providers; private ResponseBuilder abortResponse = null; private MultivaluedMap parameters = null; - public JaxRsContext(Providers providers, ContainerRequestContext requestContext, SessionStore sessionStore) { + public JaxRsContext(Providers providers, ContainerRequestContext requestContext) { this.providers = providers; this.requestContext = requestContext; - this.sessionStore = sessionStore; } public Providers getProviders() { @@ -66,11 +67,6 @@ public ContainerRequestContext getRequestContext() { return requestContext; } - @Override - public SessionStore getSessionStore() { - return sessionStore; - } - public ResponseBuilder getAbortBuilder() { if (abortResponse == null) { abortResponse = Response.ok(); @@ -87,6 +83,11 @@ public ResponseHolder getResponseHolder() { return prop; } + @Override + public Optional getResponseHeader(String name) { + return Optional.ofNullable(getResponseHolder().getResponseHeader(name)); + } + public static class ResponseHolder { private boolean hasResponseContent = false; @@ -128,6 +129,10 @@ public void setResponseContentType(MediaType type) { hasResponseContentType = true; } + public String getResponseHeader(String name) { + return responseHeaders.get(name); + } + public void populateResponse(ContainerResponseContext responseContext) { if (hasResponseContent) { responseContext.setEntity(responseContent); @@ -166,9 +171,8 @@ public void setResponseContentType(String content) { @Override public void addResponseCookie(Cookie cookie) { CommonHelper.assertNotNull("cookie", cookie); - NewCookie c = new NewCookie(cookie.getName(), cookie.getValue(), cookie.getPath(), - cookie.getDomain(), cookie.getVersion(), cookie.getComment(), cookie.getMaxAge(), cookie.getExpiry(), - cookie.isSecure(), cookie.isHttpOnly()); + NewCookie c = new NewCookie(cookie.getName(), cookie.getValue(), cookie.getPath(), cookie.getDomain(), "", + cookie.getMaxAge(), cookie.isSecure()); getAbortBuilder().cookie(c); getResponseHolder().addResponseCookie(c); } @@ -301,7 +305,6 @@ public Collection getRequestCookies() { Cookie nc = new Cookie(c.getName(), c.getValue()); nc.setDomain(c.getDomain()); nc.setPath(c.getPath()); - nc.setVersion(c.getVersion()); return nc; }).collect(Collectors.toList()); } @@ -318,7 +321,6 @@ public String getRequestContent() { } // TODO newlines?! this is copied from J2EContext - @SuppressWarnings("OS_OPEN_STREAM") String content = new BufferedReader(new InputStreamReader(stream, charset)).lines().reduce("", (accumulator, actual) -> accumulator.concat(actual)); return content; diff --git a/core/src/main/java/org/pac4j/jax/rs/pac4j/JaxRsProfileManager.java b/core/src/main/java/org/pac4j/jax/rs/pac4j/JaxRsProfileManager.java index 6b09f3c..711bcbc 100644 --- a/core/src/main/java/org/pac4j/jax/rs/pac4j/JaxRsProfileManager.java +++ b/core/src/main/java/org/pac4j/jax/rs/pac4j/JaxRsProfileManager.java @@ -7,8 +7,12 @@ import javax.ws.rs.core.SecurityContext; -import org.pac4j.core.profile.*; -import org.pac4j.jax.rs.helpers.RequestPac4JSecurityContext; +import org.pac4j.core.context.WebContext; +import org.pac4j.core.context.session.SessionStore; +import org.pac4j.core.profile.Pac4JPrincipal; +import org.pac4j.core.profile.ProfileHelper; +import org.pac4j.core.profile.ProfileManager; +import org.pac4j.core.profile.UserProfile; /** * @@ -16,17 +20,10 @@ * @since 1.0.0 * */ -public class JaxRsProfileManager extends ProfileManager { +public class JaxRsProfileManager extends ProfileManager { - public JaxRsProfileManager(JaxRsContext context) { - super(context); - } - - @Override - public void logout() { - super.logout(); - - new RequestPac4JSecurityContext((JaxRsContext) this.context).context().ifPresent(c -> c.principal = null); + public JaxRsProfileManager(WebContext context, SessionStore sessionStore) { + super(context, sessionStore); } public static class Pac4JSecurityContext implements SecurityContext { @@ -42,8 +39,7 @@ public static class Pac4JSecurityContext implements SecurityContext { private final JaxRsContext context; - public Pac4JSecurityContext(SecurityContext original, JaxRsContext context, - Collection profiles) { + public Pac4JSecurityContext(SecurityContext original, JaxRsContext context, Collection profiles) { this.original = original; this.context = context; this.profiles = profiles; diff --git a/core/src/main/java/org/pac4j/jax/rs/servlet/features/Pac4JServletFeature.java b/core/src/main/java/org/pac4j/jax/rs/servlet/features/Pac4JServletFeature.java new file mode 100644 index 0000000..cf5ab2e --- /dev/null +++ b/core/src/main/java/org/pac4j/jax/rs/servlet/features/Pac4JServletFeature.java @@ -0,0 +1,34 @@ +package org.pac4j.jax.rs.servlet.features; + +import javax.ws.rs.core.FeatureContext; + +import org.pac4j.core.config.Config; +import org.pac4j.jax.rs.features.Pac4JFeature; + +/** + * + * Extends {@link Pac4JFeature} to register the default providers for + * servlet-based containers + * + * @see Pac4JFeature + * @author Michael Kohlsche + * @since 5.0.0 + * + */ +public class Pac4JServletFeature extends Pac4JFeature { + + public Pac4JServletFeature(Config config) { + super(config); + } + + protected boolean registerContextFactoryProvider(FeatureContext context) { + context.register(ServletJaxRsContextFactoryProvider.class); + return true; + } + + protected boolean registerSessionStoreProvider(FeatureContext context) { + context.register(new ServletSessionStoreProvider(config)); + return true; + } + +} diff --git a/core/src/main/java/org/pac4j/jax/rs/servlet/features/ServletJaxRsContextFactoryProvider.java b/core/src/main/java/org/pac4j/jax/rs/servlet/features/ServletJaxRsContextFactoryProvider.java index bcbb883..7845ac9 100644 --- a/core/src/main/java/org/pac4j/jax/rs/servlet/features/ServletJaxRsContextFactoryProvider.java +++ b/core/src/main/java/org/pac4j/jax/rs/servlet/features/ServletJaxRsContextFactoryProvider.java @@ -8,8 +8,8 @@ import org.pac4j.jax.rs.servlet.pac4j.ServletJaxRsContext; /** - * Extends {@link JaxRsContextFactoryProvider} to support any servlet-based container and its session manager (i.e., - * pac4j indirect clients will work, contrary than with {@link JaxRsContextFactoryProvider}). + * Extends {@link JaxRsContextFactoryProvider} to support any servlet-based + * container * * @see JaxRsContextFactoryProvider * @author Victor Noel - Linagora @@ -23,6 +23,6 @@ public class ServletJaxRsContextFactoryProvider extends JaxRsContextFactoryProvi @Override public JaxRsContextFactory getContext(Class type) { - return context -> new ServletJaxRsContext(getProviders(), context, getConfig().getSessionStore(), requestProvider.get()); + return context -> new ServletJaxRsContext(getProviders(), context, requestProvider.get()); } } diff --git a/core/src/main/java/org/pac4j/jax/rs/servlet/features/ServletSessionStoreProvider.java b/core/src/main/java/org/pac4j/jax/rs/servlet/features/ServletSessionStoreProvider.java new file mode 100644 index 0000000..5aaec88 --- /dev/null +++ b/core/src/main/java/org/pac4j/jax/rs/servlet/features/ServletSessionStoreProvider.java @@ -0,0 +1,29 @@ +package org.pac4j.jax.rs.servlet.features; + +import org.pac4j.core.config.Config; +import org.pac4j.core.context.session.SessionStore; +import org.pac4j.jax.rs.features.JaxRsSessionStoreProvider; +import org.pac4j.jax.rs.servlet.pac4j.ServletSessionStore; + +/** + * Extends {@link JaxRsSessionStoreProvider} to provide the configured + * {@link SessionStore} or the default implementation for servlet-based + * containers + * + * @see JaxRsSessionStoreProvider + * @author Michael Kohlsche + * @since 5.0.0 + * + */ +public class ServletSessionStoreProvider extends JaxRsSessionStoreProvider { + + public ServletSessionStoreProvider(Config config) { + super(config); + } + + @Override + public SessionStore getContext(Class type) { + return (config.getSessionStore() != null) ? config.getSessionStore() : ServletSessionStore.INSTANCE; + } + +} diff --git a/core/src/main/java/org/pac4j/jax/rs/servlet/pac4j/ServletJaxRsContext.java b/core/src/main/java/org/pac4j/jax/rs/servlet/pac4j/ServletJaxRsContext.java index 77025ec..7a0f2d8 100644 --- a/core/src/main/java/org/pac4j/jax/rs/servlet/pac4j/ServletJaxRsContext.java +++ b/core/src/main/java/org/pac4j/jax/rs/servlet/pac4j/ServletJaxRsContext.java @@ -4,16 +4,18 @@ import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.ext.Providers; -import org.pac4j.core.context.session.SessionStore; import org.pac4j.core.util.CommonHelper; import org.pac4j.jax.rs.pac4j.JaxRsContext; /** * - * Notice: depending on the servlet implementations, there is often chances that the JAX-RS implementation will read the - * input stream of the request when it arrives, and after that, it becomes impossible for the Servlet implementation to - * read it. In particular this means that {@link HttpServletRequest#getParameter(String)} won't be able to return FORM - * parameters. This is why we don't override {@link JaxRsContext#getRequestParameter(String)} to use the Servlet + * Notice: depending on the servlet implementations, there is often chances that + * the JAX-RS implementation will read the input stream of the request when it + * arrives, and after that, it becomes impossible for the Servlet implementation + * to read it. In particular this means that + * {@link HttpServletRequest#getParameter(String)} won't be able to return FORM + * parameters. This is why we don't override + * {@link JaxRsContext#getRequestParameter(String)} to use the Servlet * implementation. * * @author Victor Noel - Linagora @@ -25,12 +27,12 @@ public class ServletJaxRsContext extends JaxRsContext { private final HttpServletRequest request; public ServletJaxRsContext(Providers providers, ContainerRequestContext requestContext, - SessionStore sessionStore, HttpServletRequest request) { - super(providers, requestContext, sessionStore != null ? sessionStore : new ServletSessionStore()); + HttpServletRequest request) { + super(providers, requestContext); CommonHelper.assertNotNull("request", request); this.request = request; } - + public HttpServletRequest getRequest() { return request; } diff --git a/core/src/main/java/org/pac4j/jax/rs/servlet/pac4j/ServletSessionStore.java b/core/src/main/java/org/pac4j/jax/rs/servlet/pac4j/ServletSessionStore.java index 4d9dfec..e026105 100644 --- a/core/src/main/java/org/pac4j/jax/rs/servlet/pac4j/ServletSessionStore.java +++ b/core/src/main/java/org/pac4j/jax/rs/servlet/pac4j/ServletSessionStore.java @@ -7,8 +7,8 @@ import javax.servlet.http.HttpSession; +import org.pac4j.core.context.WebContext; import org.pac4j.core.context.session.SessionStore; -import org.pac4j.jax.rs.pac4j.JaxRsContext; /** * @@ -16,25 +16,31 @@ * @since 1.0.0 * */ -public class ServletSessionStore implements SessionStore { +public class ServletSessionStore implements SessionStore { - public HttpSession getHttpSession(JaxRsContext context) { - assert context instanceof ServletJaxRsContext; - return ((ServletJaxRsContext) context).getRequest().getSession(); + public static final ServletSessionStore INSTANCE = new ServletSessionStore(); + + protected HttpSession httpSession; + + protected ServletSessionStore() { } - @Override - public String getOrCreateSessionId(JaxRsContext context) { - return getHttpSession(context).getId(); + protected ServletSessionStore(final HttpSession httpSession) { + this.httpSession = httpSession; + } + + public HttpSession getHttpSession(WebContext context) { + assert context instanceof ServletJaxRsContext; + return ((ServletJaxRsContext) context).getRequest().getSession(); } @Override - public Optional get(JaxRsContext context, String key) { + public Optional get(WebContext context, String key) { return Optional.ofNullable(getHttpSession(context).getAttribute(key)); } @Override - public void set(JaxRsContext context, String key, Object value) { + public void set(WebContext context, String key, Object value) { if (value == null) { getHttpSession(context).removeAttribute(key); } else { @@ -43,7 +49,7 @@ public void set(JaxRsContext context, String key, Object value) { } @Override - public boolean destroySession(JaxRsContext context) { + public boolean destroySession(WebContext context) { final HttpSession session = getHttpSession(context); session.invalidate(); @@ -52,12 +58,12 @@ public boolean destroySession(JaxRsContext context) { } @Override - public Optional getTrackableSession(JaxRsContext context) { + public Optional getTrackableSession(WebContext context) { return Optional.ofNullable(getHttpSession(context)); } @Override - public boolean renewSession(JaxRsContext context) { + public boolean renewSession(WebContext context) { final HttpSession session = getHttpSession(context); final Map attributes = new HashMap<>(); Collections.list(session.getAttributeNames()).forEach(k -> attributes.put(k, session.getAttribute(k))); @@ -73,12 +79,18 @@ public boolean renewSession(JaxRsContext context) { } @Override - public Optional> buildFromTrackableSession(JaxRsContext context, Object trackableSession) { + public Optional buildFromTrackableSession(WebContext context, Object trackableSession) { return Optional.ofNullable(new ServletSessionStore() { @Override - public HttpSession getHttpSession(JaxRsContext context) { + public HttpSession getHttpSession(WebContext context) { return (HttpSession) trackableSession; } }); } + + @Override + public Optional getSessionId(WebContext context, boolean createSession) { + HttpSession session = getHttpSession(context); + return (session != null) ? Optional.of(session.getId()) : Optional.empty(); + } } diff --git a/jersey/pom.xml b/jersey/pom.xml index f155812..4b6b511 100644 --- a/jersey/pom.xml +++ b/jersey/pom.xml @@ -10,7 +10,15 @@ jersey-pac4j - 2.31 + 2.35 + + 2.3.3 + 1.2.2 + + + 2.4.4 + + 3.25.0-GA @@ -22,6 +30,23 @@ import pom + + + + jakarta.xml.bind + jakarta.xml.bind-api + ${xml.bind-api.version} + + + jakarta.activation + jakarta.activation-api + ${activation-api.version} + + + org.javassist + javassist + ${javassist.version} + @@ -39,41 +64,29 @@ org.glassfish.jersey.inject jersey-hk2 - ${jersey.version} provided + org.glassfish.grizzly grizzly-http-server - - 2.4.4 + ${grizzly-http-server.version} provided true + ${project.parent.groupId} testing ${project.version} test - - - org.javassist - javassist - - org.glassfish.jersey.test-framework.providers jersey-test-framework-provider-inmemory test - - - javax.servlet - javax.servlet-api - - org.glassfish.jersey.test-framework.providers @@ -83,6 +96,7 @@ org.mockito mockito-core + test \ No newline at end of file diff --git a/jersey/src/main/java/org/pac4j/jax/rs/grizzly/features/GrizzlyJaxRsContextFactoryProvider.java b/jersey/src/main/java/org/pac4j/jax/rs/grizzly/features/GrizzlyJaxRsContextFactoryProvider.java index 69190a6..92e208d 100644 --- a/jersey/src/main/java/org/pac4j/jax/rs/grizzly/features/GrizzlyJaxRsContextFactoryProvider.java +++ b/jersey/src/main/java/org/pac4j/jax/rs/grizzly/features/GrizzlyJaxRsContextFactoryProvider.java @@ -1,7 +1,7 @@ package org.pac4j.jax.rs.grizzly.features; -import javax.inject.Inject; import javax.inject.Provider; +import javax.ws.rs.core.Context; import org.glassfish.grizzly.http.server.Request; import org.pac4j.jax.rs.features.JaxRsContextFactoryProvider; @@ -9,9 +9,8 @@ /** * - * Extends {@link JaxRsContextFactoryProvider} to support the Grizzly container (without the need for servlet support) - * and its session manager (i.e., pac4j indirect clients will work, contrary than with - * {@link JaxRsContextFactoryProvider}). + * Extends {@link JaxRsContextFactoryProvider} to support the Grizzly container + * (without the need for servlet support) * * @see JaxRsContextFactoryProvider * @author Victor Noel - Linagora @@ -20,13 +19,13 @@ */ public class GrizzlyJaxRsContextFactoryProvider extends JaxRsContextFactoryProvider { - @Inject + @Context protected Provider requestProvider; @Override public JaxRsContextFactory getContext(Class type) { Request request = requestProvider.get(); assert request != null; - return context -> new GrizzlyJaxRsContext(getProviders(), context, getConfig().getSessionStore(), request); + return context -> new GrizzlyJaxRsContext(getProviders(), context, request); } -} +} \ No newline at end of file diff --git a/jersey/src/main/java/org/pac4j/jax/rs/grizzly/features/GrizzlySessionStoreProvider.java b/jersey/src/main/java/org/pac4j/jax/rs/grizzly/features/GrizzlySessionStoreProvider.java new file mode 100644 index 0000000..a58a56c --- /dev/null +++ b/jersey/src/main/java/org/pac4j/jax/rs/grizzly/features/GrizzlySessionStoreProvider.java @@ -0,0 +1,30 @@ +package org.pac4j.jax.rs.grizzly.features; + +import org.pac4j.core.config.Config; +import org.pac4j.core.context.session.SessionStore; +import org.pac4j.jax.rs.features.JaxRsSessionStoreProvider; +import org.pac4j.jax.rs.grizzly.pac4j.GrizzlySessionStore; + +/** + * + * Extends {@link JaxRsSessionStoreProvider} to provide the configured + * {@link SessionStore} or the default implementation for the Grizzly container + * (without the need for servlet support) + * + * @see JaxRsSessionStoreProvider + * @author Michael Kohlsche + * @since 5.0.0 + * + */ +public class GrizzlySessionStoreProvider extends JaxRsSessionStoreProvider { + + public GrizzlySessionStoreProvider(Config config) { + super(config); + } + + @Override + public SessionStore getContext(Class type) { + return (config.getSessionStore() != null) ? config.getSessionStore() : GrizzlySessionStore.INSTANCE; + } + +} diff --git a/jersey/src/main/java/org/pac4j/jax/rs/grizzly/features/Pac4JGrizzlyFeature.java b/jersey/src/main/java/org/pac4j/jax/rs/grizzly/features/Pac4JGrizzlyFeature.java new file mode 100644 index 0000000..89570d3 --- /dev/null +++ b/jersey/src/main/java/org/pac4j/jax/rs/grizzly/features/Pac4JGrizzlyFeature.java @@ -0,0 +1,34 @@ +package org.pac4j.jax.rs.grizzly.features; + +import javax.ws.rs.core.FeatureContext; + +import org.pac4j.core.config.Config; +import org.pac4j.jax.rs.features.Pac4JFeature; + +/** + * + * Extends {@link Pac4JFeature} to register the default providers for the + * Grizzly container (without the need for servlet support) + * + * @see Pac4JFeature + * @author Michael Kohlsche + * @since 5.0.0 + * + */ +public class Pac4JGrizzlyFeature extends Pac4JFeature { + + public Pac4JGrizzlyFeature(Config config) { + super(config); + } + + protected boolean registerContextFactoryProvider(FeatureContext context) { + context.register(GrizzlyJaxRsContextFactoryProvider.class); + return true; + } + + protected boolean registerSessionStoreProvider(FeatureContext context) { + context.register(new GrizzlySessionStoreProvider(config)); + return true; + } + +} diff --git a/jersey/src/main/java/org/pac4j/jax/rs/grizzly/pac4j/GrizzlyJaxRsContext.java b/jersey/src/main/java/org/pac4j/jax/rs/grizzly/pac4j/GrizzlyJaxRsContext.java index 95993d1..1a6f8b6 100644 --- a/jersey/src/main/java/org/pac4j/jax/rs/grizzly/pac4j/GrizzlyJaxRsContext.java +++ b/jersey/src/main/java/org/pac4j/jax/rs/grizzly/pac4j/GrizzlyJaxRsContext.java @@ -4,15 +4,17 @@ import javax.ws.rs.ext.Providers; import org.glassfish.grizzly.http.server.Request; -import org.pac4j.core.context.session.SessionStore; import org.pac4j.jax.rs.pac4j.JaxRsContext; /** * - * Notice: there is often chances that the JAX-RS implementation will read the input stream of the request when it - * arrives, and after that, it becomes impossible for Grizzly to read it. In particular this means that - * {@link Request#getParameter(String)} won't be able to return FORM parameters. This is why we don't override - * {@link JaxRsContext#getRequestParameter(String)} to use the Grizzly implementation. + * Notice: there is often chances that the JAX-RS implementation will read the + * input stream of the request when it arrives, and after that, it becomes + * impossible for Grizzly to read it. In particular this means that + * {@link Request#getParameter(String)} won't be able to return FORM parameters. + * This is why we don't override + * {@link JaxRsContext#getRequestParameter(String)} to use the Grizzly + * implementation. * * @author Victor Noel - Linagora * @since 1.0.0 @@ -22,9 +24,8 @@ public class GrizzlyJaxRsContext extends JaxRsContext { private final Request request; - public GrizzlyJaxRsContext(Providers providers, ContainerRequestContext requestContext, - SessionStore sessionStore, Request request) { - super(providers, requestContext, sessionStore != null ? sessionStore : new GrizzlySessionStore()); + public GrizzlyJaxRsContext(Providers providers, ContainerRequestContext requestContext, Request request) { + super(providers, requestContext); this.request = request; } diff --git a/jersey/src/main/java/org/pac4j/jax/rs/grizzly/pac4j/GrizzlySessionStore.java b/jersey/src/main/java/org/pac4j/jax/rs/grizzly/pac4j/GrizzlySessionStore.java index 848db6e..42a1b82 100644 --- a/jersey/src/main/java/org/pac4j/jax/rs/grizzly/pac4j/GrizzlySessionStore.java +++ b/jersey/src/main/java/org/pac4j/jax/rs/grizzly/pac4j/GrizzlySessionStore.java @@ -5,8 +5,8 @@ import java.util.Optional; import org.glassfish.grizzly.http.server.Session; +import org.pac4j.core.context.WebContext; import org.pac4j.core.context.session.SessionStore; -import org.pac4j.jax.rs.pac4j.JaxRsContext; /** * @@ -14,25 +14,37 @@ * @since 1.0.0 * */ -public class GrizzlySessionStore implements SessionStore { +public class GrizzlySessionStore implements SessionStore { - public Session getSession(final JaxRsContext context) { + public static final GrizzlySessionStore INSTANCE = new GrizzlySessionStore(); + + protected Session session; + + protected GrizzlySessionStore() { + } + + protected GrizzlySessionStore(final Session httpSession) { + this.session = httpSession; + } + + public Session getSession(final WebContext context) { assert context instanceof GrizzlyJaxRsContext; return ((GrizzlyJaxRsContext) context).getRequest().getSession(); } @Override - public String getOrCreateSessionId(JaxRsContext context) { - return getSession(context).getIdInternal(); + public Optional getSessionId(WebContext context, boolean createSession) { + Session session = getSession(context); + return (session != null) ? Optional.of(session.getIdInternal()) : Optional.empty(); } @Override - public Optional get(JaxRsContext context, String key) { + public Optional get(WebContext context, String key) { return Optional.ofNullable(getSession(context).getAttribute(key)); } @Override - public void set(JaxRsContext context, String key, Object value) { + public void set(WebContext context, String key, Object value) { if (value == null) { getSession(context).removeAttribute(key); } else { @@ -41,7 +53,7 @@ public void set(JaxRsContext context, String key, Object value) { } @Override - public boolean destroySession(JaxRsContext context) { + public boolean destroySession(WebContext context) { final Session session = getSession(context); session.setValid(false); @@ -50,12 +62,12 @@ public boolean destroySession(JaxRsContext context) { } @Override - public Optional getTrackableSession(JaxRsContext context) { + public Optional getTrackableSession(WebContext context) { return Optional.ofNullable(getSession(context)); } @Override - public boolean renewSession(JaxRsContext context) { + public boolean renewSession(WebContext context) { final Session session = getSession(context); final Map attributes = new HashMap<>(); attributes.putAll(session.attributes()); @@ -70,13 +82,11 @@ public boolean renewSession(JaxRsContext context) { return true; } - - @Override - public Optional> buildFromTrackableSession(JaxRsContext context, Object trackableSession) { + public Optional buildFromTrackableSession(WebContext context, Object trackableSession) { return Optional.of(new GrizzlySessionStore() { @Override - public Session getSession(JaxRsContext context) { + public Session getSession(WebContext context) { return (Session) trackableSession; } }); diff --git a/jersey/src/main/java/org/pac4j/jax/rs/jersey/features/Pac4JValueFactoryProvider.java b/jersey/src/main/java/org/pac4j/jax/rs/jersey/features/Pac4JValueFactoryProvider.java index ee23d94..65b1732 100644 --- a/jersey/src/main/java/org/pac4j/jax/rs/jersey/features/Pac4JValueFactoryProvider.java +++ b/jersey/src/main/java/org/pac4j/jax/rs/jersey/features/Pac4JValueFactoryProvider.java @@ -1,5 +1,18 @@ package org.pac4j.jax.rs.jersey.features; +import java.util.List; +import java.util.Optional; +import java.util.function.Function; +import java.util.function.Supplier; + +import javax.inject.Inject; +import javax.inject.Provider; +import javax.inject.Singleton; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.GenericType; +import javax.ws.rs.ext.Providers; + import org.glassfish.jersey.internal.inject.AbstractBinder; import org.glassfish.jersey.internal.inject.InjectionResolver; import org.glassfish.jersey.internal.util.ReflectionHelper; @@ -10,30 +23,21 @@ import org.glassfish.jersey.server.internal.inject.ParamInjectionResolver; import org.glassfish.jersey.server.model.Parameter; import org.glassfish.jersey.server.spi.internal.ValueParamProvider; +import org.pac4j.core.context.session.SessionStore; import org.pac4j.core.profile.CommonProfile; import org.pac4j.core.profile.ProfileManager; import org.pac4j.core.profile.UserProfile; import org.pac4j.jax.rs.annotations.Pac4JProfile; import org.pac4j.jax.rs.annotations.Pac4JProfileManager; -import org.pac4j.jax.rs.helpers.RequestUserProfile; +import org.pac4j.jax.rs.helpers.ProvidersContext; import org.pac4j.jax.rs.helpers.RequestJaxRsContext; import org.pac4j.jax.rs.helpers.RequestPac4JSecurityContext; import org.pac4j.jax.rs.helpers.RequestProfileManager; +import org.pac4j.jax.rs.helpers.RequestUserProfile; +import org.pac4j.jax.rs.pac4j.JaxRsContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.inject.Inject; -import javax.inject.Provider; -import javax.inject.Singleton; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.GenericType; -import javax.ws.rs.ext.Providers; -import java.util.List; -import java.util.Optional; -import java.util.function.Function; -import java.util.function.Supplier; - /** * {@link Pac4JProfile @Pac4JProfile} injection value factory provider. * @@ -54,12 +58,9 @@ static class Pac4JProfileValueFactoryProvider extends AbstractValueParamProvider private final ProfileFactoryBuilder profile; @Inject - protected Pac4JProfileValueFactoryProvider( - ProfileManagerFactoryBuilder manager, - OptionalProfileFactoryBuilder opt, - ProfileFactoryBuilder profile, - Provider mpep - ) { + protected Pac4JProfileValueFactoryProvider(ProfileManagerFactoryBuilder manager, + OptionalProfileFactoryBuilder opt, ProfileFactoryBuilder profile, + Provider mpep) { super(mpep, org.glassfish.jersey.model.Parameter.Source.UNKNOWN); this.manager = manager; this.optProfile = opt; @@ -74,7 +75,7 @@ protected Pac4JProfileValueFactoryProvider( } throw new IllegalStateException("Cannot inject a Pac4J profile manager into a parameter of type " - + parameter.getRawType().getName()); + + parameter.getRawType().getName()); } if (parameter.isAnnotationPresent(Pac4JProfile.class)) { @@ -91,7 +92,7 @@ protected Pac4JProfileValueFactoryProvider( } throw new IllegalStateException( - "Cannot inject a Pac4J profile into a parameter of type " + parameter.getRawType().getName()); + "Cannot inject a Pac4J profile into a parameter of type " + parameter.getRawType().getName()); } return null; @@ -100,40 +101,37 @@ protected Pac4JProfileValueFactoryProvider( static class ProfileManagerInjectionResolver extends ParamInjectionResolver { @Inject - ProfileManagerInjectionResolver( - Pac4JProfileValueFactoryProvider valueFactoryProvider, - Provider containerRequestProvider - ) { - super( - valueFactoryProvider, - Pac4JProfileManager.class, - containerRequestProvider - ); + ProfileManagerInjectionResolver(Pac4JProfileValueFactoryProvider valueFactoryProvider, + Provider containerRequestProvider) { + super(valueFactoryProvider, Pac4JProfileManager.class, containerRequestProvider); } } static class ProfileInjectionResolver extends ParamInjectionResolver { @Inject - ProfileInjectionResolver( - Pac4JProfileValueFactoryProvider valueFactoryProvider, - Provider containerRequestProvider - ) { - super( - valueFactoryProvider, - Pac4JProfile.class, - containerRequestProvider - ); + ProfileInjectionResolver(Pac4JProfileValueFactoryProvider valueFactoryProvider, + Provider containerRequestProvider) { + super(valueFactoryProvider, Pac4JProfile.class, containerRequestProvider); } } - public interface OptionalProfileFactory extends Function> {} - public interface OptionalProfileFactoryBuilder extends Supplier {} + public interface OptionalProfileFactory extends Function> { + } - public interface ProfileFactory extends Function {} - public interface ProfileFactoryBuilder extends Supplier {} + public interface OptionalProfileFactoryBuilder extends Supplier { + } - public interface ProfileManagerFactory extends Function> {} - public interface ProfileManagerFactoryBuilder extends Supplier {} + public interface ProfileFactory extends Function { + } + + public interface ProfileFactoryBuilder extends Supplier { + } + + public interface ProfileManagerFactory extends Function { + } + + public interface ProfileManagerFactoryBuilder extends Supplier { + } public static class Binder extends AbstractBinder { @@ -149,42 +147,42 @@ public Binder() { } /** - * Use this if you want to mock the {@link CommonProfile} or the {@link ProfileManager}. + * Use this if you want to mock the {@link CommonProfile} or the + * {@link ProfileManager}. * - * @param profile - * a builder for a {@link CommonProfile}, can be null and default will be used. - * @param optProfile - * a builder for an {@link Optional} of {@link CommonProfile}, can be null and default - * will be used. - * @param manager - * a builder for a {@link ProfileManager}, can be null and default will be used. + * @param profile a builder for a {@link CommonProfile}, can be + * null and default will be used. + * @param optProfile a builder for an {@link Optional} of {@link CommonProfile}, + * can be null and default will be used. + * @param manager a builder for a {@link ProfileManager}, can be + * null and default will be used. */ public Binder(ProfileFactoryBuilder profile, OptionalProfileFactoryBuilder optProfile, - ProfileManagerFactoryBuilder manager) { + ProfileManagerFactoryBuilder manager) { this.profile = profile == null ? ProfileValueFactory::new : profile; this.optProfile = optProfile == null ? OptionalProfileValueFactory::new : optProfile; this.manager = manager; } /** - * Use this if you want to always return the same {@link CommonProfile} (or none with null). + * Use this if you want to always return the same {@link CommonProfile} (or none + * with null). * * Note that it won't mock the profile coming out of {@link ProfileManager}! * - * @param profile - * a profile, can be null. + * @param profile a profile, can be null. */ public Binder(CommonProfile profile) { this(() -> (ignored) -> profile, () -> (ignored) -> Optional.ofNullable(profile), null); } /** - * Use this if you want to return a dynamically supplied {@link CommonProfile} (or none with null). + * Use this if you want to return a dynamically supplied {@link CommonProfile} + * (or none with null). * * Note that it won't mock the profile coming out of {@link ProfileManager}! * - * @param profile - * a profile supplier, can return null. + * @param profile a profile supplier, can return null. */ public Binder(Supplier profile) { this(() -> (ignored) -> profile.get(), () -> (ignored) -> Optional.ofNullable(profile.get()), null); @@ -195,26 +193,25 @@ protected void configure() { bind(profile).to(ProfileFactoryBuilder.class); bind(optProfile).to(OptionalProfileFactoryBuilder.class); - if(manager == null){ - bind(DefaultProfileManagerFactoryBuilder.class) - .to(ProfileManagerFactoryBuilder.class).in(Singleton.class); + if (manager == null) { + bind(DefaultProfileManagerFactoryBuilder.class).to(ProfileManagerFactoryBuilder.class) + .in(Singleton.class); } else { bind(manager).to(ProfileManagerFactoryBuilder.class); } bindAsContract(Pac4JProfileValueFactoryProvider.class).to(ValueParamProvider.class).in(Singleton.class); - bindAsContract(ProfileInjectionResolver.class) - .to(new GenericType>(){}) - .in(Singleton.class); + bindAsContract(ProfileInjectionResolver.class).to(new GenericType>() { + }).in(Singleton.class); bindAsContract(ProfileManagerInjectionResolver.class) - .to(new GenericType>(){}) - .in(Singleton.class); + .to(new GenericType>() { + }).in(Singleton.class); } } - static class ProfileManagerValueFactory implements ProfileManagerFactory{ + static class ProfileManagerValueFactory implements ProfileManagerFactory { @Context private final Providers providers; @@ -223,20 +220,20 @@ static class ProfileManagerValueFactory implements ProfileManagerFactory{ } @Override - public ProfileManager apply(ContainerRequest containerRequest) { - return new RequestProfileManager(new RequestJaxRsContext(providers, containerRequest)) - .profileManager(); + public ProfileManager apply(ContainerRequest containerRequest) { + JaxRsContext context = new RequestJaxRsContext(providers, containerRequest).contextOrNew(); + SessionStore sessionStore = new ProvidersContext(providers).resolveNotNull(SessionStore.class); + return new RequestProfileManager(context, sessionStore).profileManager(); } } static class ProfileValueFactory implements ProfileFactory { @Override public UserProfile apply(ContainerRequest containerRequest) { - return optionalProfile(containerRequest) - .orElseThrow(() -> { - LOG.debug("Cannot inject a Pac4j profile into an unauthenticated request, responding with 401"); - return new WebApplicationException(401); - }); + return optionalProfile(containerRequest).orElseThrow(() -> { + LOG.debug("Cannot inject a Pac4j profile into an unauthenticated request, responding with 401"); + return new WebApplicationException(401); + }); } } diff --git a/jersey/src/test/java/org/pac4j/jax/rs/rules/JerseyGrizzlyRule.java b/jersey/src/test/java/org/pac4j/jax/rs/rules/JerseyGrizzlyRule.java index f7f0a34..da15114 100644 --- a/jersey/src/test/java/org/pac4j/jax/rs/rules/JerseyGrizzlyRule.java +++ b/jersey/src/test/java/org/pac4j/jax/rs/rules/JerseyGrizzlyRule.java @@ -6,7 +6,7 @@ import org.glassfish.jersey.test.DeploymentContext; import org.glassfish.jersey.test.grizzly.GrizzlyTestContainerFactory; import org.glassfish.jersey.test.spi.TestContainerFactory; -import org.pac4j.jax.rs.grizzly.features.GrizzlyJaxRsContextFactoryProvider; +import org.pac4j.jax.rs.grizzly.features.Pac4JGrizzlyFeature; import org.pac4j.jax.rs.resources.JerseyResource; public class JerseyGrizzlyRule extends JerseyRule implements SessionContainerRule { @@ -32,7 +32,7 @@ protected DeploymentContext configureDeployment(ResourceConfig config) { protected ResourceConfig configureResourceConfig(ResourceConfig config) { return super .configureResourceConfig(config) - .register(new GrizzlyJaxRsContextFactoryProvider()); + .register(new Pac4JGrizzlyFeature(getConfig())); } } diff --git a/jersey/src/test/java/org/pac4j/jax/rs/rules/JerseyGrizzlyServletRule.java b/jersey/src/test/java/org/pac4j/jax/rs/rules/JerseyGrizzlyServletRule.java index 4ecfb20..39dba99 100644 --- a/jersey/src/test/java/org/pac4j/jax/rs/rules/JerseyGrizzlyServletRule.java +++ b/jersey/src/test/java/org/pac4j/jax/rs/rules/JerseyGrizzlyServletRule.java @@ -9,7 +9,7 @@ import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory; import org.glassfish.jersey.test.spi.TestContainerFactory; import org.pac4j.jax.rs.resources.JerseyResource; -import org.pac4j.jax.rs.servlet.features.ServletJaxRsContextFactoryProvider; +import org.pac4j.jax.rs.servlet.features.Pac4JServletFeature; public class JerseyGrizzlyServletRule extends JerseyRule implements SessionContainerRule { @@ -34,7 +34,7 @@ protected DeploymentContext configureDeployment(ResourceConfig config) { protected ResourceConfig configureResourceConfig(ResourceConfig config) { return super .configureResourceConfig(config) - .register(ServletJaxRsContextFactoryProvider.class); + .register(new Pac4JServletFeature(getConfig())); } } diff --git a/jersey/src/test/java/org/pac4j/jax/rs/rules/JerseyInMemoryRule.java b/jersey/src/test/java/org/pac4j/jax/rs/rules/JerseyInMemoryRule.java index c3c3199..795d582 100644 --- a/jersey/src/test/java/org/pac4j/jax/rs/rules/JerseyInMemoryRule.java +++ b/jersey/src/test/java/org/pac4j/jax/rs/rules/JerseyInMemoryRule.java @@ -9,8 +9,7 @@ import org.mockito.Mockito; import org.pac4j.core.config.Config; import org.pac4j.core.context.session.SessionStore; -import org.pac4j.jax.rs.features.JaxRsConfigProvider; -import org.pac4j.jax.rs.features.JaxRsContextFactoryProvider; +import org.pac4j.jax.rs.features.Pac4JFeature; import org.pac4j.jax.rs.features.Pac4JSecurityFeature; import org.pac4j.jax.rs.jersey.features.Pac4JValueFactoryProvider; import org.pac4j.jax.rs.resources.JerseyResource; @@ -40,9 +39,8 @@ protected ResourceConfig configureResourceConfig(ResourceConfig config) { // or pac4j should be able to handle no session store. pac4jConfig.setSessionStore(Mockito.mock(SessionStore.class)); return config - .register(new JaxRsConfigProvider(pac4jConfig)) + .register(new Pac4JFeature(pac4jConfig)) .register(new Pac4JSecurityFeature()) - .register(new Pac4JValueFactoryProvider.Binder()) - .register(JaxRsContextFactoryProvider.class); + .register(new Pac4JValueFactoryProvider.Binder()); } } diff --git a/jersey/src/test/java/org/pac4j/jax/rs/rules/JerseyRule.java b/jersey/src/test/java/org/pac4j/jax/rs/rules/JerseyRule.java index 81538f3..e0ee52d 100644 --- a/jersey/src/test/java/org/pac4j/jax/rs/rules/JerseyRule.java +++ b/jersey/src/test/java/org/pac4j/jax/rs/rules/JerseyRule.java @@ -13,7 +13,6 @@ import org.glassfish.jersey.test.spi.TestContainerException; import org.glassfish.jersey.test.spi.TestContainerFactory; import org.junit.rules.ExternalResource; -import org.pac4j.jax.rs.features.JaxRsConfigProvider; import org.pac4j.jax.rs.features.Pac4JSecurityFeature; import org.pac4j.jax.rs.jersey.features.Pac4JValueFactoryProvider; @@ -38,7 +37,6 @@ protected DeploymentContext configureDeployment() { protected ResourceConfig configureResourceConfig(ResourceConfig config) { return config - .register(new JaxRsConfigProvider(getConfig())) .register(new Pac4JSecurityFeature()) .register(new Pac4JValueFactoryProvider.Binder()); } diff --git a/jersey225/pom.xml b/jersey225/pom.xml index f012c94..6205b1f 100644 --- a/jersey225/pom.xml +++ b/jersey225/pom.xml @@ -9,15 +9,50 @@ org.pac4j jersey225-pac4j + + 2.25.1 + + 2.3.3 + 3.0.1 + 1.2.2 + + + 2.3.28 + + 3.20.0-GA + + org.glassfish.jersey jersey-bom - 2.25.1 + ${jersey.version} import pom + + + + jakarta.xml.bind + jakarta.xml.bind-api + ${xml.bind-api.version} + + + jakarta.activation + jakarta.activation-api + ${activation-api.version} + + + javax.servlet + javax.servlet-api + ${servlet-api.version} + + + org.javassist + javassist + ${javassist.version} + @@ -32,15 +67,21 @@ jersey-server provided + + jakarta.xml.bind + jakarta.xml.bind-api + provided + + org.glassfish.grizzly grizzly-http-server - - 2.3.28 + ${grizzly-http-server.version} provided true + ${project.parent.groupId} @@ -61,6 +102,7 @@ org.mockito mockito-core + test \ No newline at end of file diff --git a/jersey225/src/main/java/org/pac4j/jax/rs/grizzly/features/GrizzlyJaxRsContextFactoryProvider.java b/jersey225/src/main/java/org/pac4j/jax/rs/grizzly/features/GrizzlyJaxRsContextFactoryProvider.java index 69190a6..bddcb9c 100644 --- a/jersey225/src/main/java/org/pac4j/jax/rs/grizzly/features/GrizzlyJaxRsContextFactoryProvider.java +++ b/jersey225/src/main/java/org/pac4j/jax/rs/grizzly/features/GrizzlyJaxRsContextFactoryProvider.java @@ -9,9 +9,8 @@ /** * - * Extends {@link JaxRsContextFactoryProvider} to support the Grizzly container (without the need for servlet support) - * and its session manager (i.e., pac4j indirect clients will work, contrary than with - * {@link JaxRsContextFactoryProvider}). + * Extends {@link JaxRsContextFactoryProvider} to support the Grizzly container + * (without the need for servlet support) * * @see JaxRsContextFactoryProvider * @author Victor Noel - Linagora @@ -27,6 +26,6 @@ public class GrizzlyJaxRsContextFactoryProvider extends JaxRsContextFactoryProvi public JaxRsContextFactory getContext(Class type) { Request request = requestProvider.get(); assert request != null; - return context -> new GrizzlyJaxRsContext(getProviders(), context, getConfig().getSessionStore(), request); + return context -> new GrizzlyJaxRsContext(getProviders(), context, request); } } diff --git a/jersey225/src/main/java/org/pac4j/jax/rs/grizzly/features/GrizzlySessionStoreProvider.java b/jersey225/src/main/java/org/pac4j/jax/rs/grizzly/features/GrizzlySessionStoreProvider.java new file mode 100644 index 0000000..a58a56c --- /dev/null +++ b/jersey225/src/main/java/org/pac4j/jax/rs/grizzly/features/GrizzlySessionStoreProvider.java @@ -0,0 +1,30 @@ +package org.pac4j.jax.rs.grizzly.features; + +import org.pac4j.core.config.Config; +import org.pac4j.core.context.session.SessionStore; +import org.pac4j.jax.rs.features.JaxRsSessionStoreProvider; +import org.pac4j.jax.rs.grizzly.pac4j.GrizzlySessionStore; + +/** + * + * Extends {@link JaxRsSessionStoreProvider} to provide the configured + * {@link SessionStore} or the default implementation for the Grizzly container + * (without the need for servlet support) + * + * @see JaxRsSessionStoreProvider + * @author Michael Kohlsche + * @since 5.0.0 + * + */ +public class GrizzlySessionStoreProvider extends JaxRsSessionStoreProvider { + + public GrizzlySessionStoreProvider(Config config) { + super(config); + } + + @Override + public SessionStore getContext(Class type) { + return (config.getSessionStore() != null) ? config.getSessionStore() : GrizzlySessionStore.INSTANCE; + } + +} diff --git a/jersey225/src/main/java/org/pac4j/jax/rs/grizzly/features/Pac4JGrizzlyFeature.java b/jersey225/src/main/java/org/pac4j/jax/rs/grizzly/features/Pac4JGrizzlyFeature.java new file mode 100644 index 0000000..89570d3 --- /dev/null +++ b/jersey225/src/main/java/org/pac4j/jax/rs/grizzly/features/Pac4JGrizzlyFeature.java @@ -0,0 +1,34 @@ +package org.pac4j.jax.rs.grizzly.features; + +import javax.ws.rs.core.FeatureContext; + +import org.pac4j.core.config.Config; +import org.pac4j.jax.rs.features.Pac4JFeature; + +/** + * + * Extends {@link Pac4JFeature} to register the default providers for the + * Grizzly container (without the need for servlet support) + * + * @see Pac4JFeature + * @author Michael Kohlsche + * @since 5.0.0 + * + */ +public class Pac4JGrizzlyFeature extends Pac4JFeature { + + public Pac4JGrizzlyFeature(Config config) { + super(config); + } + + protected boolean registerContextFactoryProvider(FeatureContext context) { + context.register(GrizzlyJaxRsContextFactoryProvider.class); + return true; + } + + protected boolean registerSessionStoreProvider(FeatureContext context) { + context.register(new GrizzlySessionStoreProvider(config)); + return true; + } + +} diff --git a/jersey225/src/main/java/org/pac4j/jax/rs/grizzly/pac4j/GrizzlyJaxRsContext.java b/jersey225/src/main/java/org/pac4j/jax/rs/grizzly/pac4j/GrizzlyJaxRsContext.java index 95993d1..1a6f8b6 100644 --- a/jersey225/src/main/java/org/pac4j/jax/rs/grizzly/pac4j/GrizzlyJaxRsContext.java +++ b/jersey225/src/main/java/org/pac4j/jax/rs/grizzly/pac4j/GrizzlyJaxRsContext.java @@ -4,15 +4,17 @@ import javax.ws.rs.ext.Providers; import org.glassfish.grizzly.http.server.Request; -import org.pac4j.core.context.session.SessionStore; import org.pac4j.jax.rs.pac4j.JaxRsContext; /** * - * Notice: there is often chances that the JAX-RS implementation will read the input stream of the request when it - * arrives, and after that, it becomes impossible for Grizzly to read it. In particular this means that - * {@link Request#getParameter(String)} won't be able to return FORM parameters. This is why we don't override - * {@link JaxRsContext#getRequestParameter(String)} to use the Grizzly implementation. + * Notice: there is often chances that the JAX-RS implementation will read the + * input stream of the request when it arrives, and after that, it becomes + * impossible for Grizzly to read it. In particular this means that + * {@link Request#getParameter(String)} won't be able to return FORM parameters. + * This is why we don't override + * {@link JaxRsContext#getRequestParameter(String)} to use the Grizzly + * implementation. * * @author Victor Noel - Linagora * @since 1.0.0 @@ -22,9 +24,8 @@ public class GrizzlyJaxRsContext extends JaxRsContext { private final Request request; - public GrizzlyJaxRsContext(Providers providers, ContainerRequestContext requestContext, - SessionStore sessionStore, Request request) { - super(providers, requestContext, sessionStore != null ? sessionStore : new GrizzlySessionStore()); + public GrizzlyJaxRsContext(Providers providers, ContainerRequestContext requestContext, Request request) { + super(providers, requestContext); this.request = request; } diff --git a/jersey225/src/main/java/org/pac4j/jax/rs/grizzly/pac4j/GrizzlySessionStore.java b/jersey225/src/main/java/org/pac4j/jax/rs/grizzly/pac4j/GrizzlySessionStore.java index 848db6e..20a0601 100644 --- a/jersey225/src/main/java/org/pac4j/jax/rs/grizzly/pac4j/GrizzlySessionStore.java +++ b/jersey225/src/main/java/org/pac4j/jax/rs/grizzly/pac4j/GrizzlySessionStore.java @@ -5,8 +5,8 @@ import java.util.Optional; import org.glassfish.grizzly.http.server.Session; +import org.pac4j.core.context.WebContext; import org.pac4j.core.context.session.SessionStore; -import org.pac4j.jax.rs.pac4j.JaxRsContext; /** * @@ -14,25 +14,31 @@ * @since 1.0.0 * */ -public class GrizzlySessionStore implements SessionStore { +public class GrizzlySessionStore implements SessionStore { - public Session getSession(final JaxRsContext context) { - assert context instanceof GrizzlyJaxRsContext; - return ((GrizzlyJaxRsContext) context).getRequest().getSession(); + public static final GrizzlySessionStore INSTANCE = new GrizzlySessionStore(); + + protected Session session; + + protected GrizzlySessionStore() { } - @Override - public String getOrCreateSessionId(JaxRsContext context) { - return getSession(context).getIdInternal(); + protected GrizzlySessionStore(final Session httpSession) { + this.session = httpSession; + } + + public Session getSession(final WebContext context) { + assert context instanceof GrizzlyJaxRsContext; + return ((GrizzlyJaxRsContext) context).getRequest().getSession(); } @Override - public Optional get(JaxRsContext context, String key) { + public Optional get(WebContext context, String key) { return Optional.ofNullable(getSession(context).getAttribute(key)); } @Override - public void set(JaxRsContext context, String key, Object value) { + public void set(WebContext context, String key, Object value) { if (value == null) { getSession(context).removeAttribute(key); } else { @@ -41,7 +47,7 @@ public void set(JaxRsContext context, String key, Object value) { } @Override - public boolean destroySession(JaxRsContext context) { + public boolean destroySession(WebContext context) { final Session session = getSession(context); session.setValid(false); @@ -50,12 +56,12 @@ public boolean destroySession(JaxRsContext context) { } @Override - public Optional getTrackableSession(JaxRsContext context) { + public Optional getTrackableSession(WebContext context) { return Optional.ofNullable(getSession(context)); } @Override - public boolean renewSession(JaxRsContext context) { + public boolean renewSession(WebContext context) { final Session session = getSession(context); final Map attributes = new HashMap<>(); attributes.putAll(session.attributes()); @@ -70,13 +76,17 @@ public boolean renewSession(JaxRsContext context) { return true; } - + @Override + public Optional getSessionId(WebContext context, boolean createSession) { + Session session = getSession(context); + return (session != null) ? Optional.of(session.getIdInternal()) : Optional.empty(); + } @Override - public Optional> buildFromTrackableSession(JaxRsContext context, Object trackableSession) { + public Optional buildFromTrackableSession(WebContext context, Object trackableSession) { return Optional.of(new GrizzlySessionStore() { @Override - public Session getSession(JaxRsContext context) { + public Session getSession(WebContext context) { return (Session) trackableSession; } }); diff --git a/jersey225/src/main/java/org/pac4j/jax/rs/jersey/features/Pac4JValueFactoryProvider.java b/jersey225/src/main/java/org/pac4j/jax/rs/jersey/features/Pac4JValueFactoryProvider.java index 6d98b45..6291b59 100644 --- a/jersey225/src/main/java/org/pac4j/jax/rs/jersey/features/Pac4JValueFactoryProvider.java +++ b/jersey225/src/main/java/org/pac4j/jax/rs/jersey/features/Pac4JValueFactoryProvider.java @@ -23,15 +23,18 @@ import org.glassfish.jersey.server.internal.inject.ParamInjectionResolver; import org.glassfish.jersey.server.model.Parameter; import org.glassfish.jersey.server.spi.internal.ValueFactoryProvider; +import org.pac4j.core.context.session.SessionStore; import org.pac4j.core.profile.CommonProfile; import org.pac4j.core.profile.ProfileManager; import org.pac4j.core.profile.UserProfile; import org.pac4j.jax.rs.annotations.Pac4JProfile; import org.pac4j.jax.rs.annotations.Pac4JProfileManager; +import org.pac4j.jax.rs.helpers.ProvidersContext; import org.pac4j.jax.rs.helpers.RequestJaxRsContext; -import org.pac4j.jax.rs.helpers.RequestUserProfile; -import org.pac4j.jax.rs.helpers.RequestProfileManager; import org.pac4j.jax.rs.helpers.RequestPac4JSecurityContext; +import org.pac4j.jax.rs.helpers.RequestProfileManager; +import org.pac4j.jax.rs.helpers.RequestUserProfile; +import org.pac4j.jax.rs.pac4j.JaxRsContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -122,9 +125,9 @@ default void dispose(UserProfile instance) { } } - public interface ProfileManagerFactory extends Factory> { + public interface ProfileManagerFactory extends Factory { @Override - default void dispose(ProfileManager instance) { + default void dispose(ProfileManager instance) { // do nothing } } @@ -155,15 +158,15 @@ public Binder() { } /** - * Use this if you want to mock the {@link CommonProfile} or the {@link ProfileManager}. + * Use this if you want to mock the {@link CommonProfile} or the + * {@link ProfileManager}. * - * @param profile - * a builder for a {@link CommonProfile}, can be null and default will be used. - * @param optProfile - * a builder for an {@link Optional} of {@link CommonProfile}, can be null and default - * will be used. - * @param manager - * a builder for a {@link ProfileManager}, can be null and default will be used. + * @param profile a builder for a {@link CommonProfile}, can be + * null and default will be used. + * @param optProfile a builder for an {@link Optional} of {@link CommonProfile}, + * can be null and default will be used. + * @param manager a builder for a {@link ProfileManager}, can be + * null and default will be used. */ public Binder(ProfileFactoryBuilder profile, OptionalProfileFactoryBuilder optProfile, ProfileManagerFactoryBuilder manager) { @@ -173,24 +176,24 @@ public Binder(ProfileFactoryBuilder profile, OptionalProfileFactoryBuilder optPr } /** - * Use this if you want to always return the same {@link CommonProfile} (or none with null). + * Use this if you want to always return the same {@link CommonProfile} (or none + * with null). * * Note that it won't mock the profile coming out of {@link ProfileManager}! * - * @param profile - * a profile, can be null. + * @param profile a profile, can be null. */ public Binder(CommonProfile profile) { this(() -> () -> profile, () -> () -> Optional.ofNullable(profile), null); } /** - * Use this if you want to return a dynamically supplied {@link CommonProfile} (or none with null). + * Use this if you want to return a dynamically supplied {@link CommonProfile} + * (or none with null). * * Note that it won't mock the profile coming out of {@link ProfileManager}! * - * @param profile - * a profile supplier, can return null. + * @param profile a profile supplier, can return null. */ public Binder(Supplier profile) { this(() -> () -> profile.get(), () -> () -> Optional.ofNullable(profile.get()), null); @@ -211,16 +214,17 @@ protected void configure() { } } - static class ProfileManagerValueFactory extends AbstractContainerRequestValueFactory> + static class ProfileManagerValueFactory extends AbstractContainerRequestValueFactory implements ProfileManagerFactory { @Context Providers providers; @Override - public ProfileManager provide() { - return new RequestProfileManager(new RequestJaxRsContext(providers, getContainerRequest())) - .profileManager(); + public ProfileManager provide() { + JaxRsContext context = new RequestJaxRsContext(providers, getContainerRequest()).contextOrNew(); + SessionStore sessionStore = new ProvidersContext(providers).resolveNotNull(SessionStore.class); + return new RequestProfileManager(context, sessionStore).profileManager(); } } diff --git a/jersey225/src/test/java/org/pac4j/jax/rs/rules/JerseyGrizzlyRule.java b/jersey225/src/test/java/org/pac4j/jax/rs/rules/JerseyGrizzlyRule.java index f7f0a34..da15114 100644 --- a/jersey225/src/test/java/org/pac4j/jax/rs/rules/JerseyGrizzlyRule.java +++ b/jersey225/src/test/java/org/pac4j/jax/rs/rules/JerseyGrizzlyRule.java @@ -6,7 +6,7 @@ import org.glassfish.jersey.test.DeploymentContext; import org.glassfish.jersey.test.grizzly.GrizzlyTestContainerFactory; import org.glassfish.jersey.test.spi.TestContainerFactory; -import org.pac4j.jax.rs.grizzly.features.GrizzlyJaxRsContextFactoryProvider; +import org.pac4j.jax.rs.grizzly.features.Pac4JGrizzlyFeature; import org.pac4j.jax.rs.resources.JerseyResource; public class JerseyGrizzlyRule extends JerseyRule implements SessionContainerRule { @@ -32,7 +32,7 @@ protected DeploymentContext configureDeployment(ResourceConfig config) { protected ResourceConfig configureResourceConfig(ResourceConfig config) { return super .configureResourceConfig(config) - .register(new GrizzlyJaxRsContextFactoryProvider()); + .register(new Pac4JGrizzlyFeature(getConfig())); } } diff --git a/jersey225/src/test/java/org/pac4j/jax/rs/rules/JerseyGrizzlyServletRule.java b/jersey225/src/test/java/org/pac4j/jax/rs/rules/JerseyGrizzlyServletRule.java index 4ecfb20..39dba99 100644 --- a/jersey225/src/test/java/org/pac4j/jax/rs/rules/JerseyGrizzlyServletRule.java +++ b/jersey225/src/test/java/org/pac4j/jax/rs/rules/JerseyGrizzlyServletRule.java @@ -9,7 +9,7 @@ import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory; import org.glassfish.jersey.test.spi.TestContainerFactory; import org.pac4j.jax.rs.resources.JerseyResource; -import org.pac4j.jax.rs.servlet.features.ServletJaxRsContextFactoryProvider; +import org.pac4j.jax.rs.servlet.features.Pac4JServletFeature; public class JerseyGrizzlyServletRule extends JerseyRule implements SessionContainerRule { @@ -34,7 +34,7 @@ protected DeploymentContext configureDeployment(ResourceConfig config) { protected ResourceConfig configureResourceConfig(ResourceConfig config) { return super .configureResourceConfig(config) - .register(ServletJaxRsContextFactoryProvider.class); + .register(new Pac4JServletFeature(getConfig())); } } diff --git a/jersey225/src/test/java/org/pac4j/jax/rs/rules/JerseyInMemoryRule.java b/jersey225/src/test/java/org/pac4j/jax/rs/rules/JerseyInMemoryRule.java index c3c3199..795d582 100644 --- a/jersey225/src/test/java/org/pac4j/jax/rs/rules/JerseyInMemoryRule.java +++ b/jersey225/src/test/java/org/pac4j/jax/rs/rules/JerseyInMemoryRule.java @@ -9,8 +9,7 @@ import org.mockito.Mockito; import org.pac4j.core.config.Config; import org.pac4j.core.context.session.SessionStore; -import org.pac4j.jax.rs.features.JaxRsConfigProvider; -import org.pac4j.jax.rs.features.JaxRsContextFactoryProvider; +import org.pac4j.jax.rs.features.Pac4JFeature; import org.pac4j.jax.rs.features.Pac4JSecurityFeature; import org.pac4j.jax.rs.jersey.features.Pac4JValueFactoryProvider; import org.pac4j.jax.rs.resources.JerseyResource; @@ -40,9 +39,8 @@ protected ResourceConfig configureResourceConfig(ResourceConfig config) { // or pac4j should be able to handle no session store. pac4jConfig.setSessionStore(Mockito.mock(SessionStore.class)); return config - .register(new JaxRsConfigProvider(pac4jConfig)) + .register(new Pac4JFeature(pac4jConfig)) .register(new Pac4JSecurityFeature()) - .register(new Pac4JValueFactoryProvider.Binder()) - .register(JaxRsContextFactoryProvider.class); + .register(new Pac4JValueFactoryProvider.Binder()); } } diff --git a/jersey225/src/test/java/org/pac4j/jax/rs/rules/JerseyRule.java b/jersey225/src/test/java/org/pac4j/jax/rs/rules/JerseyRule.java index 81538f3..e0ee52d 100644 --- a/jersey225/src/test/java/org/pac4j/jax/rs/rules/JerseyRule.java +++ b/jersey225/src/test/java/org/pac4j/jax/rs/rules/JerseyRule.java @@ -13,7 +13,6 @@ import org.glassfish.jersey.test.spi.TestContainerException; import org.glassfish.jersey.test.spi.TestContainerFactory; import org.junit.rules.ExternalResource; -import org.pac4j.jax.rs.features.JaxRsConfigProvider; import org.pac4j.jax.rs.features.Pac4JSecurityFeature; import org.pac4j.jax.rs.jersey.features.Pac4JValueFactoryProvider; @@ -38,7 +37,6 @@ protected DeploymentContext configureDeployment() { protected ResourceConfig configureResourceConfig(ResourceConfig config) { return config - .register(new JaxRsConfigProvider(getConfig())) .register(new Pac4JSecurityFeature()) .register(new Pac4JValueFactoryProvider.Binder()); } diff --git a/jersey228/pom.xml b/jersey228/pom.xml index 5eaae57..e251879 100644 --- a/jersey228/pom.xml +++ b/jersey228/pom.xml @@ -11,7 +11,17 @@ jersey228-pac4j - 2.31 + 2.28 + + 2.1.5 + 2.3.3 + 1.2.2 + 1.3.4 + + + 2.4.4 + + 3.22.0-CR2 @@ -23,6 +33,33 @@ import pom + + + + jakarta.ws.rs + jakarta.ws.rs-api + ${ws.rs-api.version} + + + jakarta.xml.bind + jakarta.xml.bind-api + ${xml.bind-api.version} + + + jakarta.activation + jakarta.activation-api + ${activation-api.version} + + + jakarta.annotation + jakarta.annotation-api + ${annotation-api.version} + + + org.javassist + javassist + ${javassist.version} + @@ -40,46 +77,44 @@ org.glassfish.jersey.inject jersey-hk2 - ${jersey.version} provided + + jakarta.xml.bind + jakarta.xml.bind-api + provided + + org.glassfish.grizzly grizzly-http-server - - 2.4.4 + ${grizzly-http-server.version} provided true + ${project.parent.groupId} testing ${project.version} test - - - org.javassist - javassist - - org.glassfish.jersey.test-framework.providers jersey-test-framework-provider-inmemory test - - - javax.servlet - javax.servlet-api - - org.glassfish.jersey.test-framework.providers jersey-test-framework-provider-grizzly2 test + + org.mockito + mockito-core + test + \ No newline at end of file diff --git a/jersey228/src/main/java/org/pac4j/jax/rs/grizzly/features/GrizzlyJaxRsContextFactoryProvider.java b/jersey228/src/main/java/org/pac4j/jax/rs/grizzly/features/GrizzlyJaxRsContextFactoryProvider.java index b1802f6..bddcb9c 100644 --- a/jersey228/src/main/java/org/pac4j/jax/rs/grizzly/features/GrizzlyJaxRsContextFactoryProvider.java +++ b/jersey228/src/main/java/org/pac4j/jax/rs/grizzly/features/GrizzlyJaxRsContextFactoryProvider.java @@ -1,17 +1,16 @@ package org.pac4j.jax.rs.grizzly.features; +import javax.inject.Inject; +import javax.inject.Provider; + import org.glassfish.grizzly.http.server.Request; import org.pac4j.jax.rs.features.JaxRsContextFactoryProvider; import org.pac4j.jax.rs.grizzly.pac4j.GrizzlyJaxRsContext; -import javax.inject.Inject; -import javax.inject.Provider; - /** * - * Extends {@link JaxRsContextFactoryProvider} to support the Grizzly container (without the need for servlet support) - * and its session manager (i.e., pac4j indirect clients will work, contrary than with - * {@link JaxRsContextFactoryProvider}). + * Extends {@link JaxRsContextFactoryProvider} to support the Grizzly container + * (without the need for servlet support) * * @see JaxRsContextFactoryProvider * @author Victor Noel - Linagora @@ -27,6 +26,6 @@ public class GrizzlyJaxRsContextFactoryProvider extends JaxRsContextFactoryProvi public JaxRsContextFactory getContext(Class type) { Request request = requestProvider.get(); assert request != null; - return context -> new GrizzlyJaxRsContext(getProviders(), context, getConfig().getSessionStore(), request); + return context -> new GrizzlyJaxRsContext(getProviders(), context, request); } } diff --git a/jersey228/src/main/java/org/pac4j/jax/rs/grizzly/features/GrizzlySessionStoreProvider.java b/jersey228/src/main/java/org/pac4j/jax/rs/grizzly/features/GrizzlySessionStoreProvider.java new file mode 100644 index 0000000..a58a56c --- /dev/null +++ b/jersey228/src/main/java/org/pac4j/jax/rs/grizzly/features/GrizzlySessionStoreProvider.java @@ -0,0 +1,30 @@ +package org.pac4j.jax.rs.grizzly.features; + +import org.pac4j.core.config.Config; +import org.pac4j.core.context.session.SessionStore; +import org.pac4j.jax.rs.features.JaxRsSessionStoreProvider; +import org.pac4j.jax.rs.grizzly.pac4j.GrizzlySessionStore; + +/** + * + * Extends {@link JaxRsSessionStoreProvider} to provide the configured + * {@link SessionStore} or the default implementation for the Grizzly container + * (without the need for servlet support) + * + * @see JaxRsSessionStoreProvider + * @author Michael Kohlsche + * @since 5.0.0 + * + */ +public class GrizzlySessionStoreProvider extends JaxRsSessionStoreProvider { + + public GrizzlySessionStoreProvider(Config config) { + super(config); + } + + @Override + public SessionStore getContext(Class type) { + return (config.getSessionStore() != null) ? config.getSessionStore() : GrizzlySessionStore.INSTANCE; + } + +} diff --git a/jersey228/src/main/java/org/pac4j/jax/rs/grizzly/features/Pac4JGrizzlyFeature.java b/jersey228/src/main/java/org/pac4j/jax/rs/grizzly/features/Pac4JGrizzlyFeature.java new file mode 100644 index 0000000..89570d3 --- /dev/null +++ b/jersey228/src/main/java/org/pac4j/jax/rs/grizzly/features/Pac4JGrizzlyFeature.java @@ -0,0 +1,34 @@ +package org.pac4j.jax.rs.grizzly.features; + +import javax.ws.rs.core.FeatureContext; + +import org.pac4j.core.config.Config; +import org.pac4j.jax.rs.features.Pac4JFeature; + +/** + * + * Extends {@link Pac4JFeature} to register the default providers for the + * Grizzly container (without the need for servlet support) + * + * @see Pac4JFeature + * @author Michael Kohlsche + * @since 5.0.0 + * + */ +public class Pac4JGrizzlyFeature extends Pac4JFeature { + + public Pac4JGrizzlyFeature(Config config) { + super(config); + } + + protected boolean registerContextFactoryProvider(FeatureContext context) { + context.register(GrizzlyJaxRsContextFactoryProvider.class); + return true; + } + + protected boolean registerSessionStoreProvider(FeatureContext context) { + context.register(new GrizzlySessionStoreProvider(config)); + return true; + } + +} diff --git a/jersey228/src/main/java/org/pac4j/jax/rs/grizzly/pac4j/GrizzlyJaxRsContext.java b/jersey228/src/main/java/org/pac4j/jax/rs/grizzly/pac4j/GrizzlyJaxRsContext.java index d233bc2..1a6f8b6 100644 --- a/jersey228/src/main/java/org/pac4j/jax/rs/grizzly/pac4j/GrizzlyJaxRsContext.java +++ b/jersey228/src/main/java/org/pac4j/jax/rs/grizzly/pac4j/GrizzlyJaxRsContext.java @@ -1,18 +1,20 @@ package org.pac4j.jax.rs.grizzly.pac4j; -import org.glassfish.grizzly.http.server.Request; -import org.pac4j.core.context.session.SessionStore; -import org.pac4j.jax.rs.pac4j.JaxRsContext; - import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.ext.Providers; +import org.glassfish.grizzly.http.server.Request; +import org.pac4j.jax.rs.pac4j.JaxRsContext; + /** * - * Notice: there is often chances that the JAX-RS implementation will read the input stream of the request when it - * arrives, and after that, it becomes impossible for Grizzly to read it. In particular this means that - * {@link Request#getParameter(String)} won't be able to return FORM parameters. This is why we don't override - * {@link JaxRsContext#getRequestParameter(String)} to use the Grizzly implementation. + * Notice: there is often chances that the JAX-RS implementation will read the + * input stream of the request when it arrives, and after that, it becomes + * impossible for Grizzly to read it. In particular this means that + * {@link Request#getParameter(String)} won't be able to return FORM parameters. + * This is why we don't override + * {@link JaxRsContext#getRequestParameter(String)} to use the Grizzly + * implementation. * * @author Victor Noel - Linagora * @since 1.0.0 @@ -22,9 +24,8 @@ public class GrizzlyJaxRsContext extends JaxRsContext { private final Request request; - public GrizzlyJaxRsContext(Providers providers, ContainerRequestContext requestContext, - SessionStore sessionStore, Request request) { - super(providers, requestContext, sessionStore != null ? sessionStore : new GrizzlySessionStore()); + public GrizzlyJaxRsContext(Providers providers, ContainerRequestContext requestContext, Request request) { + super(providers, requestContext); this.request = request; } diff --git a/jersey228/src/main/java/org/pac4j/jax/rs/grizzly/pac4j/GrizzlySessionStore.java b/jersey228/src/main/java/org/pac4j/jax/rs/grizzly/pac4j/GrizzlySessionStore.java index e88df78..42a1b82 100644 --- a/jersey228/src/main/java/org/pac4j/jax/rs/grizzly/pac4j/GrizzlySessionStore.java +++ b/jersey228/src/main/java/org/pac4j/jax/rs/grizzly/pac4j/GrizzlySessionStore.java @@ -1,38 +1,50 @@ package org.pac4j.jax.rs.grizzly.pac4j; -import org.glassfish.grizzly.http.server.Session; -import org.pac4j.core.context.session.SessionStore; -import org.pac4j.jax.rs.pac4j.JaxRsContext; - import java.util.HashMap; import java.util.Map; import java.util.Optional; +import org.glassfish.grizzly.http.server.Session; +import org.pac4j.core.context.WebContext; +import org.pac4j.core.context.session.SessionStore; + /** * * @author Victor Noel - Linagora * @since 1.0.0 * */ -public class GrizzlySessionStore implements SessionStore { +public class GrizzlySessionStore implements SessionStore { + + public static final GrizzlySessionStore INSTANCE = new GrizzlySessionStore(); - public Session getSession(final JaxRsContext context) { + protected Session session; + + protected GrizzlySessionStore() { + } + + protected GrizzlySessionStore(final Session httpSession) { + this.session = httpSession; + } + + public Session getSession(final WebContext context) { assert context instanceof GrizzlyJaxRsContext; return ((GrizzlyJaxRsContext) context).getRequest().getSession(); } @Override - public String getOrCreateSessionId(JaxRsContext context) { - return getSession(context).getIdInternal(); + public Optional getSessionId(WebContext context, boolean createSession) { + Session session = getSession(context); + return (session != null) ? Optional.of(session.getIdInternal()) : Optional.empty(); } @Override - public Optional get(JaxRsContext context, String key) { + public Optional get(WebContext context, String key) { return Optional.ofNullable(getSession(context).getAttribute(key)); } @Override - public void set(JaxRsContext context, String key, Object value) { + public void set(WebContext context, String key, Object value) { if (value == null) { getSession(context).removeAttribute(key); } else { @@ -41,7 +53,7 @@ public void set(JaxRsContext context, String key, Object value) { } @Override - public boolean destroySession(JaxRsContext context) { + public boolean destroySession(WebContext context) { final Session session = getSession(context); session.setValid(false); @@ -50,12 +62,12 @@ public boolean destroySession(JaxRsContext context) { } @Override - public Optional getTrackableSession(JaxRsContext context) { + public Optional getTrackableSession(WebContext context) { return Optional.ofNullable(getSession(context)); } @Override - public boolean renewSession(JaxRsContext context) { + public boolean renewSession(WebContext context) { final Session session = getSession(context); final Map attributes = new HashMap<>(); attributes.putAll(session.attributes()); @@ -70,13 +82,11 @@ public boolean renewSession(JaxRsContext context) { return true; } - - @Override - public Optional> buildFromTrackableSession(JaxRsContext context, Object trackableSession) { + public Optional buildFromTrackableSession(WebContext context, Object trackableSession) { return Optional.of(new GrizzlySessionStore() { @Override - public Session getSession(JaxRsContext context) { + public Session getSession(WebContext context) { return (Session) trackableSession; } }); diff --git a/jersey228/src/main/java/org/pac4j/jax/rs/jersey/features/Pac4JValueFactoryProvider.java b/jersey228/src/main/java/org/pac4j/jax/rs/jersey/features/Pac4JValueFactoryProvider.java index dd6bbb3..c1d8bbc 100644 --- a/jersey228/src/main/java/org/pac4j/jax/rs/jersey/features/Pac4JValueFactoryProvider.java +++ b/jersey228/src/main/java/org/pac4j/jax/rs/jersey/features/Pac4JValueFactoryProvider.java @@ -1,5 +1,18 @@ package org.pac4j.jax.rs.jersey.features; +import java.util.List; +import java.util.Optional; +import java.util.function.Function; +import java.util.function.Supplier; + +import javax.inject.Inject; +import javax.inject.Provider; +import javax.inject.Singleton; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.GenericType; +import javax.ws.rs.ext.Providers; + import org.glassfish.jersey.internal.inject.AbstractBinder; import org.glassfish.jersey.internal.inject.InjectionResolver; import org.glassfish.jersey.internal.util.ReflectionHelper; @@ -10,30 +23,21 @@ import org.glassfish.jersey.server.internal.inject.ParamInjectionResolver; import org.glassfish.jersey.server.model.Parameter; import org.glassfish.jersey.server.spi.internal.ValueParamProvider; +import org.pac4j.core.context.session.SessionStore; import org.pac4j.core.profile.CommonProfile; import org.pac4j.core.profile.ProfileManager; import org.pac4j.core.profile.UserProfile; import org.pac4j.jax.rs.annotations.Pac4JProfile; import org.pac4j.jax.rs.annotations.Pac4JProfileManager; -import org.pac4j.jax.rs.helpers.RequestUserProfile; +import org.pac4j.jax.rs.helpers.ProvidersContext; import org.pac4j.jax.rs.helpers.RequestJaxRsContext; import org.pac4j.jax.rs.helpers.RequestPac4JSecurityContext; import org.pac4j.jax.rs.helpers.RequestProfileManager; +import org.pac4j.jax.rs.helpers.RequestUserProfile; +import org.pac4j.jax.rs.pac4j.JaxRsContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.inject.Inject; -import javax.inject.Provider; -import javax.inject.Singleton; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.GenericType; -import javax.ws.rs.ext.Providers; -import java.util.List; -import java.util.Optional; -import java.util.function.Function; -import java.util.function.Supplier; - /** * {@link Pac4JProfile @Pac4JProfile} injection value factory provider. * @@ -54,12 +58,9 @@ static class Pac4JProfileValueFactoryProvider extends AbstractValueParamProvider private final ProfileFactoryBuilder profile; @Inject - protected Pac4JProfileValueFactoryProvider( - ProfileManagerFactoryBuilder manager, - OptionalProfileFactoryBuilder opt, - ProfileFactoryBuilder profile, - Provider mpep - ) { + protected Pac4JProfileValueFactoryProvider(ProfileManagerFactoryBuilder manager, + OptionalProfileFactoryBuilder opt, ProfileFactoryBuilder profile, + Provider mpep) { super(mpep, Parameter.Source.UNKNOWN); this.manager = manager; this.optProfile = opt; @@ -74,7 +75,7 @@ protected Pac4JProfileValueFactoryProvider( } throw new IllegalStateException("Cannot inject a Pac4J profile manager into a parameter of type " - + parameter.getRawType().getName()); + + parameter.getRawType().getName()); } if (parameter.isAnnotationPresent(Pac4JProfile.class)) { @@ -91,7 +92,7 @@ protected Pac4JProfileValueFactoryProvider( } throw new IllegalStateException( - "Cannot inject a Pac4J profile into a parameter of type " + parameter.getRawType().getName()); + "Cannot inject a Pac4J profile into a parameter of type " + parameter.getRawType().getName()); } return null; @@ -100,40 +101,37 @@ protected Pac4JProfileValueFactoryProvider( static class ProfileManagerInjectionResolver extends ParamInjectionResolver { @Inject - ProfileManagerInjectionResolver( - Pac4JProfileValueFactoryProvider valueFactoryProvider, - Provider containerRequestProvider - ) { - super( - valueFactoryProvider, - Pac4JProfileManager.class, - containerRequestProvider - ); + ProfileManagerInjectionResolver(Pac4JProfileValueFactoryProvider valueFactoryProvider, + Provider containerRequestProvider) { + super(valueFactoryProvider, Pac4JProfileManager.class, containerRequestProvider); } } static class ProfileInjectionResolver extends ParamInjectionResolver { @Inject - ProfileInjectionResolver( - Pac4JProfileValueFactoryProvider valueFactoryProvider, - Provider containerRequestProvider - ) { - super( - valueFactoryProvider, - Pac4JProfile.class, - containerRequestProvider - ); + ProfileInjectionResolver(Pac4JProfileValueFactoryProvider valueFactoryProvider, + Provider containerRequestProvider) { + super(valueFactoryProvider, Pac4JProfile.class, containerRequestProvider); } } - public interface OptionalProfileFactory extends Function> {} - public interface OptionalProfileFactoryBuilder extends Supplier {} + public interface OptionalProfileFactory extends Function> { + } - public interface ProfileFactory extends Function {} - public interface ProfileFactoryBuilder extends Supplier {} + public interface OptionalProfileFactoryBuilder extends Supplier { + } - public interface ProfileManagerFactory extends Function> {} - public interface ProfileManagerFactoryBuilder extends Supplier {} + public interface ProfileFactory extends Function { + } + + public interface ProfileFactoryBuilder extends Supplier { + } + + public interface ProfileManagerFactory extends Function { + } + + public interface ProfileManagerFactoryBuilder extends Supplier { + } public static class Binder extends AbstractBinder { @@ -149,42 +147,42 @@ public Binder() { } /** - * Use this if you want to mock the {@link CommonProfile} or the {@link ProfileManager}. + * Use this if you want to mock the {@link CommonProfile} or the + * {@link ProfileManager}. * - * @param profile - * a builder for a {@link CommonProfile}, can be null and default will be used. - * @param optProfile - * a builder for an {@link Optional} of {@link CommonProfile}, can be null and default - * will be used. - * @param manager - * a builder for a {@link ProfileManager}, can be null and default will be used. + * @param profile a builder for a {@link CommonProfile}, can be + * null and default will be used. + * @param optProfile a builder for an {@link Optional} of {@link CommonProfile}, + * can be null and default will be used. + * @param manager a builder for a {@link ProfileManager}, can be + * null and default will be used. */ public Binder(ProfileFactoryBuilder profile, OptionalProfileFactoryBuilder optProfile, - ProfileManagerFactoryBuilder manager) { + ProfileManagerFactoryBuilder manager) { this.profile = profile == null ? ProfileValueFactory::new : profile; this.optProfile = optProfile == null ? OptionalProfileValueFactory::new : optProfile; this.manager = manager; } /** - * Use this if you want to always return the same {@link CommonProfile} (or none with null). + * Use this if you want to always return the same {@link CommonProfile} (or none + * with null). * * Note that it won't mock the profile coming out of {@link ProfileManager}! * - * @param profile - * a profile, can be null. + * @param profile a profile, can be null. */ public Binder(CommonProfile profile) { this(() -> (ignored) -> profile, () -> (ignored) -> Optional.ofNullable(profile), null); } /** - * Use this if you want to return a dynamically supplied {@link CommonProfile} (or none with null). + * Use this if you want to return a dynamically supplied {@link CommonProfile} + * (or none with null). * * Note that it won't mock the profile coming out of {@link ProfileManager}! * - * @param profile - * a profile supplier, can return null. + * @param profile a profile supplier, can return null. */ public Binder(Supplier profile) { this(() -> (ignored) -> profile.get(), () -> (ignored) -> Optional.ofNullable(profile.get()), null); @@ -195,27 +193,23 @@ protected void configure() { bind(profile).to(ProfileFactoryBuilder.class); bind(optProfile).to(OptionalProfileFactoryBuilder.class); - if(manager == null){ - bind(DefaultProfileManagerFactoryBuilder.class) - .to(ProfileManagerFactoryBuilder.class) - ; + if (manager == null) { + bind(DefaultProfileManagerFactoryBuilder.class).to(ProfileManagerFactoryBuilder.class); } else { bind(manager).to(ProfileManagerFactoryBuilder.class); } bind(Pac4JProfileValueFactoryProvider.class).to(ValueParamProvider.class).in(Singleton.class); - bind(ProfileInjectionResolver.class) - .to(new GenericType>(){}) - .in(Singleton.class); + bind(ProfileInjectionResolver.class).to(new GenericType>() { + }).in(Singleton.class); - bind(ProfileManagerInjectionResolver.class) - .to(new GenericType>(){}) - .in(Singleton.class); + bind(ProfileManagerInjectionResolver.class).to(new GenericType>() { + }).in(Singleton.class); } } - static class ProfileManagerValueFactory implements ProfileManagerFactory{ + static class ProfileManagerValueFactory implements ProfileManagerFactory { @Context private final Providers providers; @@ -224,20 +218,20 @@ static class ProfileManagerValueFactory implements ProfileManagerFactory{ } @Override - public ProfileManager apply(ContainerRequest containerRequest) { - return new RequestProfileManager(new RequestJaxRsContext(providers, containerRequest)) - .profileManager(); + public ProfileManager apply(ContainerRequest containerRequest) { + JaxRsContext context = new RequestJaxRsContext(providers, containerRequest).contextOrNew(); + SessionStore sessionStore = new ProvidersContext(providers).resolveNotNull(SessionStore.class); + return new RequestProfileManager(context, sessionStore).profileManager(); } } static class ProfileValueFactory implements ProfileFactory { @Override public UserProfile apply(ContainerRequest containerRequest) { - return optionalProfile(containerRequest) - .orElseThrow(() -> { - LOG.debug("Cannot inject a Pac4j profile into an unauthenticated request, responding with 401"); - return new WebApplicationException(401); - }); + return optionalProfile(containerRequest).orElseThrow(() -> { + LOG.debug("Cannot inject a Pac4j profile into an unauthenticated request, responding with 401"); + return new WebApplicationException(401); + }); } } diff --git a/jersey228/src/test/java/org/pac4j/jax/rs/JerseyGrizzlyServletTest.java b/jersey228/src/test/java/org/pac4j/jax/rs/JerseyGrizzlyServletTest.java new file mode 100644 index 0000000..10da86e --- /dev/null +++ b/jersey228/src/test/java/org/pac4j/jax/rs/JerseyGrizzlyServletTest.java @@ -0,0 +1,17 @@ +package org.pac4j.jax.rs; + +import org.pac4j.jax.rs.rules.JerseyGrizzlyServletRule; +import org.pac4j.jax.rs.rules.SessionContainerRule; + +/** + * + * @author Victor Noel - Linagora + * @since 1.0.0 + * + */ +public class JerseyGrizzlyServletTest extends AbstractSessionTest { + @Override + protected SessionContainerRule createContainer() { + return new JerseyGrizzlyServletRule(); + } +} diff --git a/jersey228/src/test/java/org/pac4j/jax/rs/JerseyGrizzlyTest.java b/jersey228/src/test/java/org/pac4j/jax/rs/JerseyGrizzlyTest.java new file mode 100644 index 0000000..bb0e688 --- /dev/null +++ b/jersey228/src/test/java/org/pac4j/jax/rs/JerseyGrizzlyTest.java @@ -0,0 +1,17 @@ +package org.pac4j.jax.rs; + +import org.pac4j.jax.rs.rules.JerseyGrizzlyRule; +import org.pac4j.jax.rs.rules.SessionContainerRule; + +/** + * + * @author Victor Noel - Linagora + * @since 1.0.0 + * + */ +public class JerseyGrizzlyTest extends AbstractSessionTest { + @Override + protected SessionContainerRule createContainer() { + return new JerseyGrizzlyRule(); + } +} diff --git a/jersey228/src/test/java/org/pac4j/jax/rs/JerseyInMemoryTest.java b/jersey228/src/test/java/org/pac4j/jax/rs/JerseyInMemoryTest.java new file mode 100644 index 0000000..6cb65e9 --- /dev/null +++ b/jersey228/src/test/java/org/pac4j/jax/rs/JerseyInMemoryTest.java @@ -0,0 +1,17 @@ +package org.pac4j.jax.rs; + +import org.pac4j.jax.rs.rules.ContainerRule; +import org.pac4j.jax.rs.rules.JerseyInMemoryRule; + +/** + * + * @author Victor Noel - Linagora + * @since 1.0.0 + * + */ +public class JerseyInMemoryTest extends AbstractTest { + @Override + protected ContainerRule createContainer() { + return new JerseyInMemoryRule(); + } +} diff --git a/jersey228/src/test/java/org/pac4j/jax/rs/resources/JerseyResource.java b/jersey228/src/test/java/org/pac4j/jax/rs/resources/JerseyResource.java new file mode 100644 index 0000000..bfc517e --- /dev/null +++ b/jersey228/src/test/java/org/pac4j/jax/rs/resources/JerseyResource.java @@ -0,0 +1,56 @@ +package org.pac4j.jax.rs.resources; + +import javax.inject.Inject; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.SecurityContext; +import javax.ws.rs.ext.Providers; + +import org.pac4j.core.authorization.authorizer.DefaultAuthorizers; +import org.pac4j.jax.rs.annotations.Pac4JSecurity; +import org.pac4j.jax.rs.features.JaxRsContextFactoryProvider.JaxRsContextFactory; +import org.pac4j.jax.rs.helpers.ProvidersContext; +import org.pac4j.jax.rs.pac4j.JaxRsContext; +import org.pac4j.jax.rs.pac4j.JaxRsProfileManager.Pac4JSecurityContext; + +@Path("/containerSpecific") +public class JerseyResource { + + @Context + private Providers providers; + + @Inject + private ContainerRequestContext requestContext; + + @POST + @Path("/securitycontext") + @Pac4JSecurity(clients = "DirectFormClient", authorizers = DefaultAuthorizers.IS_AUTHENTICATED) + public String directSecurityContext() { + // Note: SecurityContext injected via @Context can't be cast + SecurityContext context = requestContext.getSecurityContext(); + if (context != null) { + if (context instanceof Pac4JSecurityContext) { + return "ok"; + } else { + return "fail"; + } + } else { + return "error"; + } + } + + @POST + @Path("/context") + @Pac4JSecurity(clients = "DirectFormClient", authorizers = DefaultAuthorizers.IS_AUTHENTICATED) + public String directContext() { + JaxRsContext context = new ProvidersContext(providers).resolveNotNull(JaxRsContextFactory.class) + .provides(requestContext); + if (context != null) { + return "ok"; + } else { + return "fail"; + } + } +} diff --git a/jersey228/src/test/java/org/pac4j/jax/rs/rules/JerseyGrizzlyRule.java b/jersey228/src/test/java/org/pac4j/jax/rs/rules/JerseyGrizzlyRule.java new file mode 100644 index 0000000..da15114 --- /dev/null +++ b/jersey228/src/test/java/org/pac4j/jax/rs/rules/JerseyGrizzlyRule.java @@ -0,0 +1,38 @@ +package org.pac4j.jax.rs.rules; + +import java.util.Set; + +import org.glassfish.jersey.server.ResourceConfig; +import org.glassfish.jersey.test.DeploymentContext; +import org.glassfish.jersey.test.grizzly.GrizzlyTestContainerFactory; +import org.glassfish.jersey.test.spi.TestContainerFactory; +import org.pac4j.jax.rs.grizzly.features.Pac4JGrizzlyFeature; +import org.pac4j.jax.rs.resources.JerseyResource; + +public class JerseyGrizzlyRule extends JerseyRule implements SessionContainerRule { + + @Override + public Set> getResources() { + Set> resources = SessionContainerRule.super.getResources(); + resources.add(JerseyResource.class); + return resources; + } + + @Override + protected TestContainerFactory getTestContainerFactory() { + return new GrizzlyTestContainerFactory(); + } + + @Override + protected DeploymentContext configureDeployment(ResourceConfig config) { + return DeploymentContext.builder(config).build(); + } + + @Override + protected ResourceConfig configureResourceConfig(ResourceConfig config) { + return super + .configureResourceConfig(config) + .register(new Pac4JGrizzlyFeature(getConfig())); + } + +} diff --git a/jersey228/src/test/java/org/pac4j/jax/rs/rules/JerseyGrizzlyServletRule.java b/jersey228/src/test/java/org/pac4j/jax/rs/rules/JerseyGrizzlyServletRule.java new file mode 100644 index 0000000..39dba99 --- /dev/null +++ b/jersey228/src/test/java/org/pac4j/jax/rs/rules/JerseyGrizzlyServletRule.java @@ -0,0 +1,40 @@ +package org.pac4j.jax.rs.rules; + +import java.util.Set; + +import org.glassfish.jersey.server.ResourceConfig; +import org.glassfish.jersey.servlet.ServletContainer; +import org.glassfish.jersey.test.DeploymentContext; +import org.glassfish.jersey.test.ServletDeploymentContext; +import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory; +import org.glassfish.jersey.test.spi.TestContainerFactory; +import org.pac4j.jax.rs.resources.JerseyResource; +import org.pac4j.jax.rs.servlet.features.Pac4JServletFeature; + +public class JerseyGrizzlyServletRule extends JerseyRule implements SessionContainerRule { + + @Override + public Set> getResources() { + Set> resources = SessionContainerRule.super.getResources(); + resources.add(JerseyResource.class); + return resources; + } + + @Override + protected TestContainerFactory getTestContainerFactory() { + return new GrizzlyWebTestContainerFactory(); + } + + @Override + protected DeploymentContext configureDeployment(ResourceConfig config) { + return ServletDeploymentContext.forServlet(new ServletContainer(config)).build(); + } + + @Override + protected ResourceConfig configureResourceConfig(ResourceConfig config) { + return super + .configureResourceConfig(config) + .register(new Pac4JServletFeature(getConfig())); + } + +} diff --git a/jersey228/src/test/java/org/pac4j/jax/rs/rules/JerseyInMemoryRule.java b/jersey228/src/test/java/org/pac4j/jax/rs/rules/JerseyInMemoryRule.java new file mode 100644 index 0000000..795d582 --- /dev/null +++ b/jersey228/src/test/java/org/pac4j/jax/rs/rules/JerseyInMemoryRule.java @@ -0,0 +1,46 @@ +package org.pac4j.jax.rs.rules; + +import java.util.Set; + +import org.glassfish.jersey.server.ResourceConfig; +import org.glassfish.jersey.test.DeploymentContext; +import org.glassfish.jersey.test.inmemory.InMemoryTestContainerFactory; +import org.glassfish.jersey.test.spi.TestContainerFactory; +import org.mockito.Mockito; +import org.pac4j.core.config.Config; +import org.pac4j.core.context.session.SessionStore; +import org.pac4j.jax.rs.features.Pac4JFeature; +import org.pac4j.jax.rs.features.Pac4JSecurityFeature; +import org.pac4j.jax.rs.jersey.features.Pac4JValueFactoryProvider; +import org.pac4j.jax.rs.resources.JerseyResource; + +public class JerseyInMemoryRule extends JerseyRule { + + @Override + public Set> getResources() { + Set> resources = super.getResources(); + resources.add(JerseyResource.class); + return resources; + } + + @Override + protected TestContainerFactory getTestContainerFactory() { + return new InMemoryTestContainerFactory(); + } + + @Override + protected DeploymentContext configureDeployment(ResourceConfig config) { + return DeploymentContext.builder(config).build(); + } + + protected ResourceConfig configureResourceConfig(ResourceConfig config) { + final Config pac4jConfig = getConfig(); + // we create a fake session to make tests pass. Otherwise we would need: matchers="none" + // or pac4j should be able to handle no session store. + pac4jConfig.setSessionStore(Mockito.mock(SessionStore.class)); + return config + .register(new Pac4JFeature(pac4jConfig)) + .register(new Pac4JSecurityFeature()) + .register(new Pac4JValueFactoryProvider.Binder()); + } +} diff --git a/jersey228/src/test/java/org/pac4j/jax/rs/rules/JerseyRule.java b/jersey228/src/test/java/org/pac4j/jax/rs/rules/JerseyRule.java new file mode 100644 index 0000000..e0ee52d --- /dev/null +++ b/jersey228/src/test/java/org/pac4j/jax/rs/rules/JerseyRule.java @@ -0,0 +1,76 @@ +package org.pac4j.jax.rs.rules; + +import java.net.CookieHandler; +import java.net.CookieManager; + +import javax.ws.rs.client.WebTarget; + +import org.glassfish.grizzly.http.server.util.Globals; +import org.glassfish.jersey.server.ResourceConfig; +import org.glassfish.jersey.test.DeploymentContext; +import org.glassfish.jersey.test.JerseyTest; +import org.glassfish.jersey.test.TestProperties; +import org.glassfish.jersey.test.spi.TestContainerException; +import org.glassfish.jersey.test.spi.TestContainerFactory; +import org.junit.rules.ExternalResource; +import org.pac4j.jax.rs.features.Pac4JSecurityFeature; +import org.pac4j.jax.rs.jersey.features.Pac4JValueFactoryProvider; + +public abstract class JerseyRule extends ExternalResource implements ContainerRule { + + private MyJerseyTest jersey; + + public class MyJerseyTest extends JerseyTest { + + @Override + protected TestContainerFactory getTestContainerFactory() throws TestContainerException { + return JerseyRule.this.getTestContainerFactory(); + } + + @Override + protected DeploymentContext configureDeployment() { + forceSet(TestProperties.CONTAINER_PORT, "0"); + + return JerseyRule.this.configureDeployment(configureResourceConfig(new ResourceConfig(getResources()))); + } + } + + protected ResourceConfig configureResourceConfig(ResourceConfig config) { + return config + .register(new Pac4JSecurityFeature()) + .register(new Pac4JValueFactoryProvider.Binder()); + } + + protected abstract TestContainerFactory getTestContainerFactory(); + + protected abstract DeploymentContext configureDeployment(ResourceConfig config); + + @Override + protected void before() throws Throwable { + // Used by Jersey Client to store cookies + CookieHandler.setDefault(new CookieManager()); + + jersey = new MyJerseyTest(); + jersey.setUp(); + } + + @Override + protected void after() { + try { + jersey.tearDown(); + CookieHandler.setDefault(null); + } catch (Exception e) { + throw new RuntimeException("can't stop jersey", e); + } + } + + @Override + public WebTarget getTarget(String url) { + return jersey.target(url); + } + + @Override + public String cookieName() { + return Globals.SESSION_COOKIE_NAME; + } +} diff --git a/pom.xml b/pom.xml index ebcac02..98ecd0b 100644 --- a/pom.xml +++ b/pom.xml @@ -79,8 +79,15 @@ - 4.0.3 - 1.8 + 5.3.1 + 11 + + 1.7.35 + 1.2.17 + + 4.3.1 + 4.13.2 + 3.0.1 @@ -90,11 +97,31 @@ pac4j-core ${pac4j.version} + + org.slf4j + slf4j-api + ${slf4j.version} + + + log4j + log4j + ${log4j.version} + + + junit + junit + ${junit.version} + org.mockito mockito-core - 3.5.10 - test + ${mockito.version} + + + com.google.code.findbugs + findbugs-annotations + ${findbugs-annotations.version} + provided @@ -104,7 +131,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.8.1 + 3.10.0 ${java.version} ${java.version} @@ -127,7 +154,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.2.0 + 3.3.2 UTF-8 UTF-8 @@ -145,7 +172,7 @@ com.github.spotbugs spotbugs-maven-plugin - 4.0.4 + 4.5.3.0 Low Max @@ -166,7 +193,7 @@ org.apache.maven.plugins maven-pmd-plugin - 3.13.0 + 3.16.0 true true @@ -184,7 +211,7 @@ org.apache.maven.plugins maven-enforcer-plugin - 3.0.0-M3 + 3.0.0 dependency-convergence @@ -216,7 +243,7 @@ org.apache.maven.plugins maven-gpg-plugin - 1.6 + 3.0.1 sign-artifacts diff --git a/resteasy/pom.xml b/resteasy/pom.xml index 49962fc..8a74adb 100644 --- a/resteasy/pom.xml +++ b/resteasy/pom.xml @@ -10,7 +10,21 @@ resteasy-pac4j - 3.13.0.Final + 3.15.3.Final + + 2.0.SP1 + 4.0.3 + 1.0.5 + + 6.0.0 + 2.35 + 3.1.9.Final + 2.2.16.Final + 3.4.1.Final + 2.2.1.Final + 2.2.1.Final + 1.11 + 1.5.4.Final @@ -22,6 +36,70 @@ import pom + + + + org.jboss.weld.servlet + weld-servlet-parent + ${weld.version} + import + pom + + + org.osgi + org.osgi.core + ${osgi.version} + + + commons-codec + commons-codec + ${commons-codec.version} + + + jakarta.servlet + jakarta.servlet-api + ${servlet-api.version} + + + javax.enterprise + cdi-api + ${cdi-api.version} + + + jakarta.inject + jakarta.inject-api + ${inject-api.version} + + + org.jboss.logging + jboss-logging + ${jboss-logging.version} + + + org.jboss.logging + jboss-logging-annotations + ${jboss-logging-annotations.version} + + + org.jboss.logging + jboss-logging-processor + ${jboss-logging-processor.version} + + + org.wildfly.common + wildfly-common + ${wildfly-common.version} + + + io.undertow + undertow-servlet + ${undertow.version} + + + io.undertow + undertow-core + ${undertow.version} + @@ -36,6 +114,7 @@ resteasy-jaxrs provided + ${project.parent.groupId} @@ -43,49 +122,31 @@ ${project.version} test - - org.jboss.resteasy - resteasy-undertow - test - - - commons-codec - commons-codec - - - org.jboss.logging - jboss-logging - - - org.jboss.resteasy resteasy-cdi test - ${resteasy.version} - - - javax - javaee-api - 8.0 - test - io.undertow - undertow-servlet - 2.0.23.Final + org.jboss.resteasy + resteasy-undertow test org.jboss.weld.servlet - weld-servlet - 2.4.8.Final + weld-servlet-core test org.glassfish.jersey.core jersey-client - 2.25.1 + ${jersey.version} + test + + + org.glassfish.jersey.inject + jersey-cdi2-se + ${jersey.version} test diff --git a/resteasy/src/main/java/org/pac4j/jax/rs/resteasy/features/Pac4JProfileInjectorFactory.java b/resteasy/src/main/java/org/pac4j/jax/rs/resteasy/features/Pac4JProfileInjectorFactory.java index 69a35cb..94bfa43 100644 --- a/resteasy/src/main/java/org/pac4j/jax/rs/resteasy/features/Pac4JProfileInjectorFactory.java +++ b/resteasy/src/main/java/org/pac4j/jax/rs/resteasy/features/Pac4JProfileInjectorFactory.java @@ -16,12 +16,13 @@ import org.jboss.resteasy.spi.ResteasyProviderFactory; import org.jboss.resteasy.spi.metadata.Parameter; import org.jboss.resteasy.util.FindAnnotation; +import org.pac4j.core.context.session.SessionStore; import org.pac4j.jax.rs.annotations.Pac4JProfile; import org.pac4j.jax.rs.annotations.Pac4JProfileManager; -import org.pac4j.jax.rs.helpers.RequestUserProfile; import org.pac4j.jax.rs.helpers.RequestJaxRsContext; import org.pac4j.jax.rs.helpers.RequestPac4JSecurityContext; import org.pac4j.jax.rs.helpers.RequestProfileManager; +import org.pac4j.jax.rs.helpers.RequestUserProfile; import org.pac4j.jax.rs.resteasy.helpers.RestEasyRequestContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,12 +36,25 @@ public class Pac4JProfileInjectorFactory extends InjectorFactoryImpl { private static Logger LOG = LoggerFactory.getLogger(Pac4JProfileInjectorFactory.class); @Override - public ValueInjector createParameterExtractor(Class injectTargetClass, AccessibleObject injectTarget, Class type, - Type genericType, Annotation[] annotations, ResteasyProviderFactory factory) { - final ValueInjector injector = getValueInjector(type, annotations, factory); + public ValueInjector createParameterExtractor(Class injectTargetClass, AccessibleObject injectTarget, + String defaultName, Class type, Type genericType, Annotation[] annotations, boolean useDefault, + ResteasyProviderFactory providerFactory) { + final ValueInjector injector = getValueInjector(type, annotations, providerFactory); + if (injector != null) + return injector; + return super.createParameterExtractor(injectTargetClass, injectTarget, defaultName, type, genericType, + annotations, useDefault, providerFactory); + } + + @Override + public ValueInjector createParameterExtractor(Class injectTargetClass, AccessibleObject injectTarget, + String defaultName, Class type, Type genericType, Annotation[] annotations, + ResteasyProviderFactory providerFactory) { + final ValueInjector injector = getValueInjector(type, annotations, providerFactory); if (injector != null) return injector; - return super.createParameterExtractor(injectTargetClass, injectTarget, type, genericType, annotations, factory); + return super.createParameterExtractor(injectTargetClass, injectTarget, defaultName, type, genericType, + annotations, providerFactory); } @Override @@ -69,7 +83,8 @@ private ValueInjector getValueInjector(Class type, Annotation[] annotations, })); } } else if (FindAnnotation.findAnnotation(annotations, Pac4JProfileManager.class) != null) { - return new Pac4JValueInjector(providerFactory, c -> new RequestProfileManager(c).profileManager()); + return new Pac4JValueInjector(providerFactory, c -> new RequestProfileManager(c.contextOrNew(), + c.getProviders().resolveNotNull(SessionStore.class)).profileManager()); } else { return null; } diff --git a/resteasy/src/main/java/org/pac4j/jax/rs/resteasy/helpers/RestEasyRequestContext.java b/resteasy/src/main/java/org/pac4j/jax/rs/resteasy/helpers/RestEasyRequestContext.java index e6179f7..2ef4164 100644 --- a/resteasy/src/main/java/org/pac4j/jax/rs/resteasy/helpers/RestEasyRequestContext.java +++ b/resteasy/src/main/java/org/pac4j/jax/rs/resteasy/helpers/RestEasyRequestContext.java @@ -1,5 +1,6 @@ package org.pac4j.jax.rs.resteasy.helpers; +import javax.ws.rs.container.ContainerRequestFilter; import javax.ws.rs.core.SecurityContext; import javax.ws.rs.ext.Providers; @@ -25,6 +26,6 @@ public RestEasyRequestContext(Providers providers, HttpRequest request) { // if we went through a pac4j security filter .map(sc -> sc.getContext().getRequestContext()) // if not, we create a new ContainerRequestContext - .orElse(new PreMatchContainerRequestContext(request))); + .orElse(new PreMatchContainerRequestContext(request, new ContainerRequestFilter[] {}, null))); } } diff --git a/resteasy/src/test/java/org/pac4j/jax/rs/rules/RestEasyUndertowServletRule.java b/resteasy/src/test/java/org/pac4j/jax/rs/rules/RestEasyUndertowServletRule.java index d3062b6..db98987 100644 --- a/resteasy/src/test/java/org/pac4j/jax/rs/rules/RestEasyUndertowServletRule.java +++ b/resteasy/src/test/java/org/pac4j/jax/rs/rules/RestEasyUndertowServletRule.java @@ -19,11 +19,10 @@ import org.jboss.resteasy.test.TestPortProvider; import org.jboss.weld.environment.servlet.Listener; import org.junit.rules.ExternalResource; -import org.pac4j.jax.rs.features.JaxRsConfigProvider; import org.pac4j.jax.rs.features.Pac4JSecurityFeature; import org.pac4j.jax.rs.resources.RestEasyResource; import org.pac4j.jax.rs.resteasy.features.Pac4JProfileInjectorFactory; -import org.pac4j.jax.rs.servlet.features.ServletJaxRsContextFactoryProvider; +import org.pac4j.jax.rs.servlet.features.Pac4JServletFeature; import io.undertow.server.session.SessionCookieConfig; import io.undertow.servlet.Servlets; @@ -40,7 +39,6 @@ public class MyApp extends Application { @Override public Set> getClasses() { Set> classes = getResources(); - classes.add(ServletJaxRsContextFactoryProvider.class); classes.add(Pac4JProfileInjectorFactory.class); return classes; } @@ -48,7 +46,7 @@ public Set> getClasses() { @Override public Set getSingletons() { return Sets.newLinkedHashSet( - new JaxRsConfigProvider(getConfig()), + new Pac4JServletFeature(getConfig()), new Pac4JSecurityFeature()); } } diff --git a/spotbugs-exclude.xml b/spotbugs-exclude.xml index 710cf08..53d8e77 100644 --- a/spotbugs-exclude.xml +++ b/spotbugs-exclude.xml @@ -2,5 +2,4 @@ - diff --git a/testing/pom.xml b/testing/pom.xml index bd87c33..89a68c1 100644 --- a/testing/pom.xml +++ b/testing/pom.xml @@ -8,6 +8,15 @@ testing + + 2.1.6 + + 3.22.0 + 3.28.0-GA + 4.1.1 + 3.2 + + @@ -17,11 +26,12 @@ provided - javax.ws.rs - javax.ws.rs-api + jakarta.ws.rs + jakarta.ws.rs-api + ${ws.rs-api.version} provided - 2.0.1 + org.pac4j @@ -31,43 +41,36 @@ junit junit - 4.12 org.assertj assertj-core - 3.17.2 + ${assertj.version} org.javassist javassist - 3.20.0-GA + ${javassist.version} org.awaitility awaitility - 4.0.3 - - - org.objenesis - objenesis - - + ${awaitility.version} org.objenesis objenesis - 3.1 + ${objenesis.version} org.slf4j slf4j-simple - 1.7.30 + ${slf4j.version} org.slf4j jul-to-slf4j - 1.7.30 + ${slf4j.version} \ No newline at end of file diff --git a/testing/src/main/java/org/pac4j/jax/rs/TestConfig.java b/testing/src/main/java/org/pac4j/jax/rs/TestConfig.java index 69100c2..6f7f060 100644 --- a/testing/src/main/java/org/pac4j/jax/rs/TestConfig.java +++ b/testing/src/main/java/org/pac4j/jax/rs/TestConfig.java @@ -2,7 +2,6 @@ import org.pac4j.core.client.Clients; import org.pac4j.core.config.Config; -import org.pac4j.core.credentials.UsernamePasswordCredentials; import org.pac4j.core.credentials.authenticator.Authenticator; import org.pac4j.http.client.direct.DirectFormClient; import org.pac4j.http.client.indirect.FormClient; @@ -11,24 +10,25 @@ import org.pac4j.jax.rs.pac4j.JaxRsUrlResolver; public interface TestConfig { - + String DEFAULT_CLIENT = "default-form"; - + default Config getConfig() { // login not used because the ajax resolver always answer true - Authenticator auth = new SimpleTestUsernamePasswordAuthenticator(); + Authenticator auth = new SimpleTestUsernamePasswordAuthenticator(); FormClient client = new FormClient("notUsedLoginUrl", auth); DirectFormClient client2 = new DirectFormClient(auth); DirectFormClient client3 = new DirectFormClient(auth); client3.setName(DEFAULT_CLIENT); Clients clients = new Clients("notUsedCallbackUrl", client, client2, client3); - // in case of invalid credentials, we simply want the error, not a redirect to the login url + // in case of invalid credentials, we simply want the error, not a redirect to + // the login url clients.setAjaxRequestResolver(new JaxRsAjaxRequestResolver()); - + // so that callback url have the correct prefix w.r.t. the container's context clients.setUrlResolver(new JaxRsUrlResolver()); - + clients.setDefaultSecurityClients(DEFAULT_CLIENT); return new Config(clients); diff --git a/testing/src/main/java/org/pac4j/jax/rs/resources/TestProxyResource.java b/testing/src/main/java/org/pac4j/jax/rs/resources/TestProxyResource.java index d21cd64..4167d6b 100644 --- a/testing/src/main/java/org/pac4j/jax/rs/resources/TestProxyResource.java +++ b/testing/src/main/java/org/pac4j/jax/rs/resources/TestProxyResource.java @@ -1,5 +1,7 @@ package org.pac4j.jax.rs.resources; +import java.lang.reflect.InvocationTargetException; + import javax.ws.rs.Path; import javassist.util.proxy.Proxy; @@ -20,13 +22,14 @@ public TestClassLevelResource proxiedResource() { try { final ProxyFactory factory = new ProxyFactory(); factory.setSuperclass(TestClassLevelResource.class); - final Proxy proxy = (Proxy) factory.createClass().newInstance(); + final Proxy proxy = (Proxy) factory.createClass().getConstructor().newInstance(); proxy.setHandler((self, overridden, proceed, args) -> { return proceed.invoke(self, args); }); return (TestClassLevelResource) proxy; - } catch (InstantiationException | IllegalAccessException e) { + } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException + | NoSuchMethodException | SecurityException e) { throw new AssertionError(e); } } diff --git a/testing/src/main/java/org/pac4j/jax/rs/resources/TestResource.java b/testing/src/main/java/org/pac4j/jax/rs/resources/TestResource.java index 8b27c91..2270b7e 100644 --- a/testing/src/main/java/org/pac4j/jax/rs/resources/TestResource.java +++ b/testing/src/main/java/org/pac4j/jax/rs/resources/TestResource.java @@ -19,6 +19,7 @@ import org.pac4j.jax.rs.annotations.Pac4JProfile; import org.pac4j.jax.rs.annotations.Pac4JProfileManager; import org.pac4j.jax.rs.annotations.Pac4JSecurity; +import org.pac4j.jax.rs.servlet.pac4j.ServletSessionStore; /** * This contains only session-less interactions @@ -30,7 +31,7 @@ @Path("/") public class TestResource { - private final Authorizer IS_AUTHENTICATED_AUTHORIZER = new IsAuthenticatedAuthorizer<>(); + private final Authorizer IS_AUTHENTICATED_AUTHORIZER = new IsAuthenticatedAuthorizer(); @GET @Path("no") @@ -91,10 +92,10 @@ public String directInjectNoAuth(@Pac4JProfile CommonProfile profile) { @POST @Path("directInjectManager") @Pac4JSecurity(clients = "DirectFormClient", authorizers = DefaultAuthorizers.IS_AUTHENTICATED, skipResponse = true) - public String directInjectManager(@Pac4JProfileManager ProfileManager pm) throws HttpAction { + public String directInjectManager(@Pac4JProfileManager ProfileManager pm) throws HttpAction { if (pm != null) { // pm.isAuthorized is relying on the session... - if (IS_AUTHENTICATED_AUTHORIZER.isAuthorized(null, pm.getAll(false))) { + if (IS_AUTHENTICATED_AUTHORIZER.isAuthorized(null, ServletSessionStore.INSTANCE, pm.getProfiles())) { return "ok"; } else { return "fail";