[ 
https://issues.apache.org/jira/browse/AMQ-9244?focusedWorklogId=866832&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-866832
 ]

ASF GitHub Bot logged work on AMQ-9244:
---------------------------------------

                Author: ASF GitHub Bot
            Created on: 21/Jun/23 19:29
            Start Date: 21/Jun/23 19:29
    Worklog Time Spent: 10m 
      Work Description: jbertram commented on code in PR #1035:
URL: https://github.com/apache/activemq/pull/1035#discussion_r1237586536


##########
activemq-broker/src/main/java/org/apache/activemq/security/jwt/JwtAuthenticationBroker.java:
##########
@@ -0,0 +1,179 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.security.jwt;
+
+import org.apache.activemq.broker.Broker;
+import org.apache.activemq.broker.ConnectionContext;
+import org.apache.activemq.command.ConnectionInfo;
+import org.apache.activemq.jaas.GroupPrincipal;
+import org.apache.activemq.security.AbstractAuthenticationBroker;
+import org.apache.activemq.security.SecurityContext;
+import org.jose4j.jwa.AlgorithmConstraints;
+import org.jose4j.jws.AlgorithmIdentifiers;
+import org.jose4j.jwt.JwtClaims;
+import org.jose4j.jwt.MalformedClaimException;
+import org.jose4j.jwt.consumer.InvalidJwtException;
+import org.jose4j.jwt.consumer.JwtConsumer;
+import org.jose4j.jwt.consumer.JwtConsumerBuilder;
+import org.jose4j.jwt.consumer.JwtContext;
+
+import java.security.Key;
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.Principal;
+import java.security.cert.X509Certificate;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.Base64;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * Handle authentication an user based on a JWT token
+ */
+public class JwtAuthenticationBroker extends AbstractAuthenticationBroker {
+
+    private final String jwtIssuer;
+    private final Claims jwtGroupsClaim;
+    private final String jwtValidatingPublicKey;
+
+    public JwtAuthenticationBroker(
+            final Broker next,
+            final String jwtIssuer,
+            final Claims jwtGroupsClaim,
+            final String jwtValidatingPublicKey) {
+        super(next);
+        this.jwtIssuer = jwtIssuer;
+        this.jwtGroupsClaim = jwtGroupsClaim;
+        this.jwtValidatingPublicKey = jwtValidatingPublicKey;
+    }
+
+    @Override
+    public void addConnection(final ConnectionContext context, final 
ConnectionInfo info) throws Exception {
+        SecurityContext securityContext = context.getSecurityContext();
+        if (securityContext == null) {
+            securityContext = authenticate(info.getUserName(), 
info.getPassword(), null);
+            context.setSecurityContext(securityContext);
+            securityContexts.add(securityContext);
+        }
+
+        try {
+            super.addConnection(context, info);
+        } catch (Exception e) {
+            securityContexts.remove(securityContext);
+            context.setSecurityContext(null);
+            throw e;
+        }
+    }
+
+    @Override
+    public SecurityContext authenticate(final String username, final String 
password, final X509Certificate[] certificates) throws SecurityException {
+        SecurityContext securityContext = null;
+        if (!username.isEmpty()) {
+
+            // parse the JWT token and check signature, validity, nbf
+            try {
+                final JwtConsumerBuilder builder = new JwtConsumerBuilder()
+                        .setRelaxVerificationKeyValidation()
+                        .setRequireSubject()
+                        .setSkipDefaultAudienceValidation()
+                        .setRequireExpirationTime()
+                        .setExpectedIssuer(jwtIssuer)
+                        .setAllowedClockSkewInSeconds(5)
+                        .setVerificationKey(parsePCKS8(jwtValidatingPublicKey))
+                        .setJwsAlgorithmConstraints(
+                                new 
AlgorithmConstraints(AlgorithmConstraints.ConstraintType.WHITELIST,
+                                        AlgorithmIdentifiers.RSA_USING_SHA256,
+                                        AlgorithmIdentifiers.RSA_USING_SHA384,
+                                        AlgorithmIdentifiers.RSA_USING_SHA512)
+                        );
+
+                final JwtConsumer jwtConsumer = builder.build();
+                final JwtContext jwtContext = jwtConsumer.process(username);

Review Comment:
   On [the 
Jira](https://issues.apache.org/jira/browse/AMQ-9244?focusedCommentId=17723012&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-17723012)
 it was indicated that the _password_ field should contain the token. If 
`username` is used instead will this fit the reported use-case?





Issue Time Tracking
-------------------

    Worklog Id:     (was: 866832)
    Time Spent: 1h 10m  (was: 1h)

> Add JWT authentication plugin
> -----------------------------
>
>                 Key: AMQ-9244
>                 URL: https://issues.apache.org/jira/browse/AMQ-9244
>             Project: ActiveMQ
>          Issue Type: Task
>          Components: Security/JAAS
>            Reporter: Jean-Baptiste Onofré
>            Assignee: Jean-Baptiste Onofré
>            Priority: Major
>             Fix For: 5.19.0, 5.18.2
>
>          Time Spent: 1h 10m
>  Remaining Estimate: 0h
>




--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to