You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by jl...@apache.org on 2021/06/24 15:08:43 UTC

[tomee] branch master updated: TOMEE-3762 Support for realm for Basic challenge

This is an automated email from the ASF dual-hosted git repository.

jlmonteiro pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tomee.git


The following commit(s) were added to refs/heads/master by this push:
     new 50602dc  TOMEE-3762 Support for realm for Basic challenge
50602dc is described below

commit 50602dca968305f7012137ea3752dc80429b7aa5
Author: Jean-Louis Monteiro <jl...@tomitribe.com>
AuthorDate: Thu Jun 24 17:08:17 2021 +0200

    TOMEE-3762 Support for realm for Basic challenge
---
 .../security/cdi/BasicAuthenticationMechanism.java | 17 ++++++++++---
 .../tomee/security/cdi/RememberMeInterceptor.java  |  4 +--
 .../tomee/security/cdi/TomEESecurityExtension.java | 29 ++++++++++++++++++----
 .../security/servlet/BasicAuthServletTest.java     | 13 +++++++++-
 .../servlet/JaccPermissionServletTest.java         |  4 ++-
 5 files changed, 55 insertions(+), 12 deletions(-)

diff --git a/tomee/tomee-security/src/main/java/org/apache/tomee/security/cdi/BasicAuthenticationMechanism.java b/tomee/tomee-security/src/main/java/org/apache/tomee/security/cdi/BasicAuthenticationMechanism.java
index a9ec2da..14a28a5 100644
--- a/tomee/tomee-security/src/main/java/org/apache/tomee/security/cdi/BasicAuthenticationMechanism.java
+++ b/tomee/tomee-security/src/main/java/org/apache/tomee/security/cdi/BasicAuthenticationMechanism.java
@@ -20,14 +20,17 @@ import javax.enterprise.context.ApplicationScoped;
 import javax.inject.Inject;
 import javax.security.enterprise.AuthenticationException;
 import javax.security.enterprise.AuthenticationStatus;
+import javax.security.enterprise.authentication.mechanism.http.BasicAuthenticationMechanismDefinition;
 import javax.security.enterprise.authentication.mechanism.http.HttpAuthenticationMechanism;
 import javax.security.enterprise.authentication.mechanism.http.HttpMessageContext;
+import javax.security.enterprise.authentication.mechanism.http.LoginToContinue;
 import javax.security.enterprise.credential.BasicAuthenticationCredential;
 import javax.security.enterprise.identitystore.CredentialValidationResult;
 import javax.security.enterprise.identitystore.IdentityStoreHandler;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.util.Optional;
+import java.util.function.Supplier;
 
 import static javax.security.enterprise.identitystore.CredentialValidationResult.Status.VALID;
 import static javax.ws.rs.core.HttpHeaders.AUTHORIZATION;
@@ -38,6 +41,10 @@ public class BasicAuthenticationMechanism implements HttpAuthenticationMechanism
     @Inject
     private IdentityStoreHandler identityStoreHandler;
 
+    @Inject
+    private Supplier<BasicAuthenticationMechanismDefinition> basicAuthenticationMechanismDefinition;
+
+
     @Override
     public AuthenticationStatus validateRequest(final HttpServletRequest request,
                                                 final HttpServletResponse response,
@@ -57,10 +64,14 @@ public class BasicAuthenticationMechanism implements HttpAuthenticationMechanism
         }
 
         if (httpMessageContext.isProtected()) {
-            response.setHeader("WWW-Authenticate", "Basic");
 
-            // todo use the annotation to define the realm
-            // response.setHeader("WWW-Authenticate", format("Basic realm=\"%s\"", realm));
+            final String realmName = basicAuthenticationMechanismDefinition.get().realmName();
+            if (realmName.isEmpty()) {
+                response.setHeader("WWW-Authenticate", "Basic");
+            } else {
+                response.setHeader("WWW-Authenticate", String.format("Basic realm=\"%s\"", realmName));
+
+            }
 
             return httpMessageContext.responseUnauthorized();
         }
diff --git a/tomee/tomee-security/src/main/java/org/apache/tomee/security/cdi/RememberMeInterceptor.java b/tomee/tomee-security/src/main/java/org/apache/tomee/security/cdi/RememberMeInterceptor.java
index ee0b3c6..81039a4 100644
--- a/tomee/tomee-security/src/main/java/org/apache/tomee/security/cdi/RememberMeInterceptor.java
+++ b/tomee/tomee-security/src/main/java/org/apache/tomee/security/cdi/RememberMeInterceptor.java
@@ -73,12 +73,12 @@ public class RememberMeInterceptor {
             if (rememberMeIdentityStore.isUnsatisfied()) {
                 throw new IllegalStateException("RememberMe annotated AuthenticationMechanism  " +
                                                 httpMechanismBean.getBeanClass() +
-                                                " required an implementation of RememberMeIndentityStore");
+                                                " required an implementation of RememberMeIdentityStore");
             }
 
             if (rememberMeIdentityStore.isAmbiguous()) {
                 throw new IllegalStateException(
-                    "Multiple implementations of RememberMeIndentityStore found. Only one should be supplied.");
+                    "Multiple implementations of RememberMeIdentityStore found. Only one should be supplied.");
             }
 
             return validateRequest(invocationContext);
diff --git a/tomee/tomee-security/src/main/java/org/apache/tomee/security/cdi/TomEESecurityExtension.java b/tomee/tomee-security/src/main/java/org/apache/tomee/security/cdi/TomEESecurityExtension.java
index c4462c6..16fcfaf 100644
--- a/tomee/tomee-security/src/main/java/org/apache/tomee/security/cdi/TomEESecurityExtension.java
+++ b/tomee/tomee-security/src/main/java/org/apache/tomee/security/cdi/TomEESecurityExtension.java
@@ -220,6 +220,16 @@ public class TomEESecurityExtension implements Extension {
         if (basicMechanism.get() != null) {
             afterBeanDiscovery
                 .addBean()
+                .id(BasicAuthenticationMechanism.class.getName() + "#" + BasicAuthenticationMechanismDefinition.class.getName())
+                .beanClass(Supplier.class)
+                .addType(Object.class)
+                .addType(new TypeLiteral<Supplier<BasicAuthenticationMechanismDefinition>>() {})
+                .qualifiers(Default.Literal.INSTANCE, Any.Literal.INSTANCE)
+                .scope(ApplicationScoped.class)
+                .createWith(creationalContext -> createBasicAuthenticationMechanismDefinitionSupplier(beanManager));
+
+            afterBeanDiscovery
+                .addBean()
                 .id(BasicAuthenticationMechanism.class.getName())
                 .beanClass(BasicAuthenticationMechanism.class)
                 .types(Object.class, HttpAuthenticationMechanism.class, BasicAuthenticationMechanism.class)
@@ -314,14 +324,23 @@ public class TomEESecurityExtension implements Extension {
         };
     }
 
+    private Supplier<BasicAuthenticationMechanismDefinition> createBasicAuthenticationMechanismDefinitionSupplier(final BeanManager beanManager) {
+        return () -> {
+            final BasicAuthenticationMechanismDefinition annotation = basicMechanism.get()
+                                                                   .getAnnotation(BasicAuthenticationMechanismDefinition.class);
+
+            return TomEEELInvocationHandler.of(BasicAuthenticationMechanismDefinition.class, annotation, beanManager);
+        };
+    }
+
     private Supplier<LoginToContinue> createCustomFormLoginToContinueSupplier(final BeanManager beanManager) {
         return () -> {
-            final LoginToContinue loginToContinue = customMechanism.get()
-                                                                        .getAnnotation(
-                                                                            CustomFormAuthenticationMechanismDefinition.class)
-                                                                        .loginToContinue();
+            final LoginToContinue annotation = customMechanism.get()
+                                                                   .getAnnotation(
+                                                                       CustomFormAuthenticationMechanismDefinition.class)
+                                                                   .loginToContinue();
 
-            return TomEEELInvocationHandler.of(LoginToContinue.class, loginToContinue, beanManager);
+            return TomEEELInvocationHandler.of(LoginToContinue.class, annotation, beanManager);
         };
     }
 
diff --git a/tomee/tomee-security/src/test/java/org/apache/tomee/security/servlet/BasicAuthServletTest.java b/tomee/tomee-security/src/test/java/org/apache/tomee/security/servlet/BasicAuthServletTest.java
index 3ab8894..34520c4 100644
--- a/tomee/tomee-security/src/test/java/org/apache/tomee/security/servlet/BasicAuthServletTest.java
+++ b/tomee/tomee-security/src/test/java/org/apache/tomee/security/servlet/BasicAuthServletTest.java
@@ -63,6 +63,15 @@ public class BasicAuthServletTest extends AbstractTomEESecurityTest {
     }
 
     @Test
+    public void realmName() throws Exception {
+        final String servlet = getAppUrl() + "/basic";
+        assertEquals("Basic realm=\"fun EL realm\"", ClientBuilder.newBuilder().register(new BasicAuthFilter("unknown", "tomcat")).build()
+                                       .target(servlet)
+                                       .request()
+                                       .get().getHeaderString("WWW-Authenticate"));
+    }
+
+    @Test
     public void wrongPassword() throws Exception {
         final String servlet = getAppUrl() + "/basic";
         assertEquals(401, ClientBuilder.newBuilder().register(new BasicAuthFilter("tomcat", "wrong")).build()
@@ -83,7 +92,9 @@ public class BasicAuthServletTest extends AbstractTomEESecurityTest {
     @TomcatUserIdentityStoreDefinition
     @WebServlet(urlPatterns = "/basic")
     @ServletSecurity(@HttpConstraint(rolesAllowed = "tomcat"))
-    @BasicAuthenticationMechanismDefinition
+    @BasicAuthenticationMechanismDefinition(
+        realmName = "${'fun EL realm'}" // constant so we could avoid EL but it's just for the test
+    )
     public static class TestServlet extends HttpServlet {
         @Override
         protected void doGet(final HttpServletRequest req, final HttpServletResponse resp)
diff --git a/tomee/tomee-security/src/test/java/org/apache/tomee/security/servlet/JaccPermissionServletTest.java b/tomee/tomee-security/src/test/java/org/apache/tomee/security/servlet/JaccPermissionServletTest.java
index a051f64..4f2ec76 100644
--- a/tomee/tomee-security/src/test/java/org/apache/tomee/security/servlet/JaccPermissionServletTest.java
+++ b/tomee/tomee-security/src/test/java/org/apache/tomee/security/servlet/JaccPermissionServletTest.java
@@ -107,7 +107,9 @@ public class JaccPermissionServletTest extends AbstractTomEESecurityTest {
 
     @WebServlet("/servlet2")
     @TomcatUserIdentityStoreDefinition
-    @BasicAuthenticationMechanismDefinition
+    @BasicAuthenticationMechanismDefinition(
+        realmName = "${'fun EL realm'}" // constant so we could avoid EL but it's just for the test
+        )
     public static class Servlet2 extends HttpServlet {
 
         private static final long serialVersionUID = 1L;