You are viewing a plain text version of this content. The canonical link for it is here.
Posted to gitbox@activemq.apache.org by "jbonofre (via GitHub)" <gi...@apache.org> on 2026/03/08 08:04:30 UTC

[PR] feat(#1737): Add OAuth2 JWT authentication support via JAAS LoginModule [activemq]

jbonofre opened a new pull request, #1738:
URL: https://github.com/apache/activemq/pull/1738

   Add OAuth2LoginModule to activemq-jaas that validates JWT access tokens using JWKS endpoint for signature verification. 
   
   Clients pass the JWT as the password field, and claims are mapped to UserPrincipal/GroupPrincipal for seamless integration with the existing JaasAuthenticationPlugin.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org
For additional commands, e-mail: gitbox-help@activemq.apache.org
For further information, visit: https://activemq.apache.org/contact



Re: [PR] feat(#1737): Add OAuth2 JWT authentication support via JAAS LoginModule [activemq]

Posted by "jbonofre (via GitHub)" <gi...@apache.org>.
jbonofre commented on PR #1738:
URL: https://github.com/apache/activemq/pull/1738#issuecomment-6287961635

   @cshannon I added experimental in the code and docs.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org
For additional commands, e-mail: gitbox-help@activemq.apache.org
For further information, visit: https://activemq.apache.org/contact



Re: [PR] feat(#1737): Add OAuth2 JWT authentication support via JAAS LoginModule [activemq]

Posted by "jbonofre (via GitHub)" <gi...@apache.org>.
jbonofre commented on code in PR #1738:
URL: https://github.com/apache/activemq/pull/1738#discussion_r2916291484


##########
activemq-jaas/src/main/java/org/apache/activemq/jaas/OAuth2LoginModule.java:
##########
@@ -0,0 +1,343 @@
+/**
+ * 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.jaas;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.security.Principal;
+import java.text.ParseException;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.auth.login.FailedLoginException;
+import javax.security.auth.login.LoginException;
+import javax.security.auth.spi.LoginModule;
+
+import com.nimbusds.jose.JOSEException;
+import com.nimbusds.jose.JWSAlgorithm;
+import com.nimbusds.jose.jwk.source.JWKSource;
+import com.nimbusds.jose.jwk.source.JWKSourceBuilder;
+import com.nimbusds.jose.proc.BadJOSEException;
+import com.nimbusds.jose.proc.JWSKeySelector;
+import com.nimbusds.jose.proc.JWSVerificationKeySelector;
+import com.nimbusds.jose.proc.SecurityContext;
+import com.nimbusds.jwt.JWTClaimsSet;
+import com.nimbusds.jwt.proc.ConfigurableJWTProcessor;
+import com.nimbusds.jwt.proc.DefaultJWTClaimsVerifier;
+import com.nimbusds.jwt.proc.DefaultJWTProcessor;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A JAAS LoginModule that authenticates users via OAuth2 JWT access tokens.
+ * <p>
+ * The client passes the JWT access token as the password in the connection info.
+ * The module validates the token signature using the JWKS endpoint and verifies
+ * standard claims (issuer, audience, expiration).
+ * <p>
+ * Configuration options (in login.config):
+ * <ul>
+ *   <li>{@code oauth2.jwksUrl} (required) - URL to the JWKS endpoint for signature verification</li>
+ *   <li>{@code oauth2.issuer} (required) - Expected token issuer (iss claim)</li>
+ *   <li>{@code oauth2.audience} (optional) - Expected token audience (aud claim)</li>
+ *   <li>{@code oauth2.usernameClaim} (optional, default: "sub") - JWT claim to use as username</li>
+ *   <li>{@code oauth2.groupsClaim} (optional, default: "groups") - JWT claim containing group memberships</li>
+ *   <li>{@code debug} (optional) - Enable debug logging</li>
+ * </ul>
+ * <p>
+ * Example login.config:
+ * <pre>
+ * activemq-oauth2 {
+ *     org.apache.activemq.jaas.OAuth2LoginModule required
+ *         oauth2.jwksUrl="https://idp.example.com/.well-known/jwks.json"
+ *         oauth2.issuer="https://idp.example.com"
+ *         oauth2.audience="activemq"
+ *         oauth2.usernameClaim="preferred_username"
+ *         oauth2.groupsClaim="roles";
+ * };
+ * </pre>
+ */
+public class OAuth2LoginModule implements LoginModule {
+
+    private static final Logger LOG = LoggerFactory.getLogger(OAuth2LoginModule.class);
+
+    static final String JWKS_URL_OPTION = "oauth2.jwksUrl";
+    static final String ISSUER_OPTION = "oauth2.issuer";
+    static final String AUDIENCE_OPTION = "oauth2.audience";
+    static final String USERNAME_CLAIM_OPTION = "oauth2.usernameClaim";
+    static final String GROUPS_CLAIM_OPTION = "oauth2.groupsClaim";
+
+    private static final String DEFAULT_USERNAME_CLAIM = "sub";
+    private static final String DEFAULT_GROUPS_CLAIM = "groups";
+
+    private Subject subject;
+    private CallbackHandler callbackHandler;
+    private boolean debug;
+
+    private String jwksUrl;
+    private String issuer;
+    private String audience;
+    private String usernameClaim;
+    private String groupsClaim;
+
+    private String user;
+    private final Set<Principal> principals = new HashSet<>();

Review Comment:
   I'm fine to use LinkedHashSet but not sure it's strictly required.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org
For additional commands, e-mail: gitbox-help@activemq.apache.org
For further information, visit: https://activemq.apache.org/contact



Re: [PR] feat(#1737): Add OAuth2 JWT authentication support via JAAS LoginModule [activemq]

Posted by "jbonofre (via GitHub)" <gi...@apache.org>.
jbonofre commented on code in PR #1738:
URL: https://github.com/apache/activemq/pull/1738#discussion_r4310225355


##########
assembly/src/release/conf/login.config:
##########


Review Comment:
   Yes, agree. Let me clarify this and the documentation.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org
For additional commands, e-mail: gitbox-help@activemq.apache.org
For further information, visit: https://activemq.apache.org/contact



Re: [PR] feat(#1737): Add OAuth2 JWT authentication support via JAAS LoginModule [activemq]

Posted by "jeanouii (via GitHub)" <gi...@apache.org>.
jeanouii commented on code in PR #1738:
URL: https://github.com/apache/activemq/pull/1738#discussion_r2904059312


##########
activemq-jaas/src/main/java/org/apache/activemq/jaas/OAuth2LoginModule.java:
##########
@@ -0,0 +1,342 @@
+/**
+ * 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.jaas;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.security.Principal;
+import java.text.ParseException;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.auth.login.FailedLoginException;
+import javax.security.auth.login.LoginException;
+import javax.security.auth.spi.LoginModule;
+
+import com.nimbusds.jose.JOSEException;
+import com.nimbusds.jose.JWSAlgorithm;
+import com.nimbusds.jose.jwk.source.JWKSource;
+import com.nimbusds.jose.jwk.source.JWKSourceBuilder;
+import com.nimbusds.jose.proc.BadJOSEException;
+import com.nimbusds.jose.proc.JWSKeySelector;
+import com.nimbusds.jose.proc.JWSVerificationKeySelector;
+import com.nimbusds.jose.proc.SecurityContext;
+import com.nimbusds.jwt.JWTClaimsSet;
+import com.nimbusds.jwt.proc.ConfigurableJWTProcessor;
+import com.nimbusds.jwt.proc.DefaultJWTClaimsVerifier;
+import com.nimbusds.jwt.proc.DefaultJWTProcessor;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A JAAS LoginModule that authenticates users via OAuth2 JWT access tokens.
+ * <p>
+ * The client passes the JWT access token as the password in the connection info.
+ * The module validates the token signature using the JWKS endpoint and verifies
+ * standard claims (issuer, audience, expiration).
+ * <p>
+ * Configuration options (in login.config):
+ * <ul>
+ *   <li>{@code oauth2.jwksUrl} (required) - URL to the JWKS endpoint for signature verification</li>
+ *   <li>{@code oauth2.issuer} (required) - Expected token issuer (iss claim)</li>
+ *   <li>{@code oauth2.audience} (optional) - Expected token audience (aud claim)</li>
+ *   <li>{@code oauth2.usernameClaim} (optional, default: "sub") - JWT claim to use as username</li>
+ *   <li>{@code oauth2.groupsClaim} (optional, default: "groups") - JWT claim containing group memberships</li>
+ *   <li>{@code debug} (optional) - Enable debug logging</li>
+ * </ul>
+ * <p>
+ * Example login.config:
+ * <pre>
+ * activemq-oauth2 {
+ *     org.apache.activemq.jaas.OAuth2LoginModule required
+ *         oauth2.jwksUrl="https://idp.example.com/.well-known/jwks.json"
+ *         oauth2.issuer="https://idp.example.com"
+ *         oauth2.audience="activemq"
+ *         oauth2.usernameClaim="preferred_username"
+ *         oauth2.groupsClaim="roles";
+ * };
+ * </pre>
+ */
+public class OAuth2LoginModule implements LoginModule {
+
+    private static final Logger LOG = LoggerFactory.getLogger(OAuth2LoginModule.class);
+
+    static final String JWKS_URL_OPTION = "oauth2.jwksUrl";
+    static final String ISSUER_OPTION = "oauth2.issuer";
+    static final String AUDIENCE_OPTION = "oauth2.audience";
+    static final String USERNAME_CLAIM_OPTION = "oauth2.usernameClaim";
+    static final String GROUPS_CLAIM_OPTION = "oauth2.groupsClaim";
+
+    private static final String DEFAULT_USERNAME_CLAIM = "sub";
+    private static final String DEFAULT_GROUPS_CLAIM = "groups";
+
+    private Subject subject;
+    private CallbackHandler callbackHandler;
+    private boolean debug;
+
+    private String jwksUrl;
+    private String issuer;
+    private String audience;
+    private String usernameClaim;
+    private String groupsClaim;
+
+    private String user;
+    private final Set<Principal> principals = new HashSet<>();
+    private boolean succeeded;
+    private boolean commitSucceeded;
+
+    private ConfigurableJWTProcessor<SecurityContext> jwtProcessor;
+
+    @Override
+    public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, Map<String, ?> options) {
+        this.subject = subject;
+        this.callbackHandler = callbackHandler;
+        this.succeeded = false;
+        this.debug = Boolean.parseBoolean((String) options.get("debug"));
+
+        this.jwksUrl = (String) options.get(JWKS_URL_OPTION);
+        this.issuer = (String) options.get(ISSUER_OPTION);
+        this.audience = (String) options.get(AUDIENCE_OPTION);
+
+        String userClaim = (String) options.get(USERNAME_CLAIM_OPTION);
+        this.usernameClaim = (userClaim != null && !userClaim.isEmpty()) ? userClaim : DEFAULT_USERNAME_CLAIM;
+
+        String grpClaim = (String) options.get(GROUPS_CLAIM_OPTION);
+        this.groupsClaim = (grpClaim != null && !grpClaim.isEmpty()) ? grpClaim : DEFAULT_GROUPS_CLAIM;
+
+        if (debug) {
+            LOG.debug("OAuth2LoginModule initialized with jwksUrl={}, issuer={}, audience={}, usernameClaim={}, groupsClaim={}",
+                    jwksUrl, issuer, audience, usernameClaim, groupsClaim);
+        }
+    }
+
+    @Override
+    public boolean login() throws LoginException {
+        if (jwksUrl == null || jwksUrl.isEmpty()) {

Review Comment:
   I think if this is required, it could go in the init.
   No need to let the broker start and login module initialize if we know upfront it will fail at login, generating tons of similar exceptions. 



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org
For additional commands, e-mail: gitbox-help@activemq.apache.org
For further information, visit: https://activemq.apache.org/contact



Re: [PR] feat(#1737): Add OAuth2 JWT authentication support via JAAS LoginModule [activemq]

Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] commented on PR #1738:
URL: https://github.com/apache/activemq/pull/1738#issuecomment-5009406077

   This PR is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 5 days.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org
For additional commands, e-mail: gitbox-help@activemq.apache.org
For further information, visit: https://activemq.apache.org/contact



Re: [PR] feat(#1737): Add OAuth2 JWT authentication support via JAAS LoginModule [activemq]

Posted by "jbonofre (via GitHub)" <gi...@apache.org>.
jbonofre commented on PR #1738:
URL: https://github.com/apache/activemq/pull/1738#issuecomment-4018955719

   The test failure is related to https://github.com/apache/activemq/pull/1741


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org
For additional commands, e-mail: gitbox-help@activemq.apache.org
For further information, visit: https://activemq.apache.org/contact



Re: [PR] feat(#1737): Add OAuth2 JWT authentication support via JAAS LoginModule [activemq]

Posted by "mattrpav (via GitHub)" <gi...@apache.org>.
mattrpav commented on code in PR #1738:
URL: https://github.com/apache/activemq/pull/1738#discussion_r4297417700


##########
assembly/src/release/conf/login.config:
##########


Review Comment:
   nit: I think OAuth2 probably should have its own sample config and not modify the default login.config file. For example, we don't ship LDAP or shiro examples in the default login.config



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org
For additional commands, e-mail: gitbox-help@activemq.apache.org
For further information, visit: https://activemq.apache.org/contact



Re: [PR] feat(#1737): Add OAuth2 JWT authentication support via JAAS LoginModule [activemq]

Posted by "jbonofre (via GitHub)" <gi...@apache.org>.
jbonofre commented on PR #1738:
URL: https://github.com/apache/activemq/pull/1738#issuecomment-6270210525

   @cshannon agree to flag as experimental. Let me do it 😄 


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org
For additional commands, e-mail: gitbox-help@activemq.apache.org
For further information, visit: https://activemq.apache.org/contact



Re: [PR] feat(#1737): Add OAuth2 JWT authentication support via JAAS LoginModule [activemq]

Posted by "jeanouii (via GitHub)" <gi...@apache.org>.
jeanouii commented on PR #1738:
URL: https://github.com/apache/activemq/pull/1738#issuecomment-4037949728

   @mattrpav Using LinkedHashSet is a nice to have but not strictly required per spec. Actually Subject.getPrincipals() returns a Set, that's it. The rest is platform dependant. Our JaasAuthenticationBroker for instance gets all the principals and then iterates until it finds an instance of UserPrincipal. 
   The other login modules all rely on HashSet, so it is now inconsistent with other ActiveMQ LoginModule.
   
   On the dependency, it will be in the final zip anyways, so until it becomes a problem, I'd prefer to keep in in activemq-jaas instead of creating another module for one class only. It is both simpler for us and for our users that don't have to know they need another module to use oauth2 tokens. We could go like this and if it's a problem split later on. 


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org
For additional commands, e-mail: gitbox-help@activemq.apache.org
For further information, visit: https://activemq.apache.org/contact



Re: [PR] feat(#1737): Add OAuth2 JWT authentication support via JAAS LoginModule [activemq]

Posted by "mattrpav (via GitHub)" <gi...@apache.org>.
mattrpav commented on PR #1738:
URL: https://github.com/apache/activemq/pull/1738#issuecomment-4035544338

   -1 on merging this as part of the activemq-jaas module. This drags in 3rd party dependency to _all_ deployments -- I think this should go into a activemq-jaas-oath2 module.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org
For additional commands, e-mail: gitbox-help@activemq.apache.org
For further information, visit: https://activemq.apache.org/contact



Re: [PR] feat(#1737): Add OAuth2 JWT authentication support via JAAS LoginModule [activemq]

Posted by "jbonofre (via GitHub)" <gi...@apache.org>.
jbonofre merged PR #1738:
URL: https://github.com/apache/activemq/pull/1738


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org
For additional commands, e-mail: gitbox-help@activemq.apache.org
For further information, visit: https://activemq.apache.org/contact



Re: [PR] feat(#1737): Add OAuth2 JWT authentication support via JAAS LoginModule [activemq]

Posted by "jbonofre (via GitHub)" <gi...@apache.org>.
jbonofre commented on PR #1738:
URL: https://github.com/apache/activemq/pull/1738#issuecomment-4018616846

   NB: this is a better approach imho to what I did initially in https://github.com/apache/activemq/pull/1035 (with the same goal).


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org
For additional commands, e-mail: gitbox-help@activemq.apache.org
For further information, visit: https://activemq.apache.org/contact



Re: [PR] feat(#1737): Add OAuth2 JWT authentication support via JAAS LoginModule [activemq]

Posted by "jbonofre (via GitHub)" <gi...@apache.org>.
jbonofre commented on code in PR #1738:
URL: https://github.com/apache/activemq/pull/1738#discussion_r2904064434


##########
activemq-jaas/src/main/java/org/apache/activemq/jaas/OAuth2LoginModule.java:
##########
@@ -0,0 +1,342 @@
+/**
+ * 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.jaas;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.security.Principal;
+import java.text.ParseException;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.auth.login.FailedLoginException;
+import javax.security.auth.login.LoginException;
+import javax.security.auth.spi.LoginModule;
+
+import com.nimbusds.jose.JOSEException;
+import com.nimbusds.jose.JWSAlgorithm;
+import com.nimbusds.jose.jwk.source.JWKSource;
+import com.nimbusds.jose.jwk.source.JWKSourceBuilder;
+import com.nimbusds.jose.proc.BadJOSEException;
+import com.nimbusds.jose.proc.JWSKeySelector;
+import com.nimbusds.jose.proc.JWSVerificationKeySelector;
+import com.nimbusds.jose.proc.SecurityContext;
+import com.nimbusds.jwt.JWTClaimsSet;
+import com.nimbusds.jwt.proc.ConfigurableJWTProcessor;
+import com.nimbusds.jwt.proc.DefaultJWTClaimsVerifier;
+import com.nimbusds.jwt.proc.DefaultJWTProcessor;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A JAAS LoginModule that authenticates users via OAuth2 JWT access tokens.
+ * <p>
+ * The client passes the JWT access token as the password in the connection info.
+ * The module validates the token signature using the JWKS endpoint and verifies
+ * standard claims (issuer, audience, expiration).
+ * <p>
+ * Configuration options (in login.config):
+ * <ul>
+ *   <li>{@code oauth2.jwksUrl} (required) - URL to the JWKS endpoint for signature verification</li>
+ *   <li>{@code oauth2.issuer} (required) - Expected token issuer (iss claim)</li>
+ *   <li>{@code oauth2.audience} (optional) - Expected token audience (aud claim)</li>
+ *   <li>{@code oauth2.usernameClaim} (optional, default: "sub") - JWT claim to use as username</li>
+ *   <li>{@code oauth2.groupsClaim} (optional, default: "groups") - JWT claim containing group memberships</li>
+ *   <li>{@code debug} (optional) - Enable debug logging</li>
+ * </ul>
+ * <p>
+ * Example login.config:
+ * <pre>
+ * activemq-oauth2 {
+ *     org.apache.activemq.jaas.OAuth2LoginModule required
+ *         oauth2.jwksUrl="https://idp.example.com/.well-known/jwks.json"
+ *         oauth2.issuer="https://idp.example.com"
+ *         oauth2.audience="activemq"
+ *         oauth2.usernameClaim="preferred_username"
+ *         oauth2.groupsClaim="roles";
+ * };
+ * </pre>
+ */
+public class OAuth2LoginModule implements LoginModule {
+
+    private static final Logger LOG = LoggerFactory.getLogger(OAuth2LoginModule.class);
+
+    static final String JWKS_URL_OPTION = "oauth2.jwksUrl";
+    static final String ISSUER_OPTION = "oauth2.issuer";
+    static final String AUDIENCE_OPTION = "oauth2.audience";
+    static final String USERNAME_CLAIM_OPTION = "oauth2.usernameClaim";
+    static final String GROUPS_CLAIM_OPTION = "oauth2.groupsClaim";
+
+    private static final String DEFAULT_USERNAME_CLAIM = "sub";
+    private static final String DEFAULT_GROUPS_CLAIM = "groups";
+
+    private Subject subject;
+    private CallbackHandler callbackHandler;
+    private boolean debug;
+
+    private String jwksUrl;
+    private String issuer;
+    private String audience;
+    private String usernameClaim;
+    private String groupsClaim;
+
+    private String user;
+    private final Set<Principal> principals = new HashSet<>();
+    private boolean succeeded;
+    private boolean commitSucceeded;
+
+    private ConfigurableJWTProcessor<SecurityContext> jwtProcessor;
+
+    @Override
+    public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, Map<String, ?> options) {
+        this.subject = subject;
+        this.callbackHandler = callbackHandler;
+        this.succeeded = false;
+        this.debug = Boolean.parseBoolean((String) options.get("debug"));
+
+        this.jwksUrl = (String) options.get(JWKS_URL_OPTION);
+        this.issuer = (String) options.get(ISSUER_OPTION);
+        this.audience = (String) options.get(AUDIENCE_OPTION);
+
+        String userClaim = (String) options.get(USERNAME_CLAIM_OPTION);
+        this.usernameClaim = (userClaim != null && !userClaim.isEmpty()) ? userClaim : DEFAULT_USERNAME_CLAIM;
+
+        String grpClaim = (String) options.get(GROUPS_CLAIM_OPTION);
+        this.groupsClaim = (grpClaim != null && !grpClaim.isEmpty()) ? grpClaim : DEFAULT_GROUPS_CLAIM;
+
+        if (debug) {
+            LOG.debug("OAuth2LoginModule initialized with jwksUrl={}, issuer={}, audience={}, usernameClaim={}, groupsClaim={}",
+                    jwksUrl, issuer, audience, usernameClaim, groupsClaim);
+        }
+    }
+
+    @Override
+    public boolean login() throws LoginException {
+        if (jwksUrl == null || jwksUrl.isEmpty()) {

Review Comment:
   That's a good point. Let me move in the `init` section.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org
For additional commands, e-mail: gitbox-help@activemq.apache.org
For further information, visit: https://activemq.apache.org/contact



Re: [PR] feat(#1737): Add OAuth2 JWT authentication support via JAAS LoginModule [activemq]

Posted by "cshannon (via GitHub)" <gi...@apache.org>.
cshannon commented on PR #1738:
URL: https://github.com/apache/activemq/pull/1738#issuecomment-6270007919

   it's probably fine for 6.4.0, maybe we can mark it as experimental/beta in the docs and the code? We have the Experimental annotation we could use just to let people know it's new and needs some testing
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org
For additional commands, e-mail: gitbox-help@activemq.apache.org
For further information, visit: https://activemq.apache.org/contact



Re: [PR] feat(#1737): Add OAuth2 JWT authentication support via JAAS LoginModule [activemq]

Posted by "mattrpav (via GitHub)" <gi...@apache.org>.
mattrpav commented on PR #1738:
URL: https://github.com/apache/activemq/pull/1738#issuecomment-4060827995

   > but it's one class for now so splitting now just makes it harder for us.
   
   I think this line of thinking 'it's just one class' is what gets us into dependency trouble as a project. Yes, it is one class in the ActiveMQ tree, but this pulls in several transitive dependencies-- not just the one listed as optional.
   
   I think it would be most correct to have separate modules per security mechanism (the shiro appoarch). We could do an activemq-jaas-extras, but that doesn't seem to make sense b/c rarely are multiple external security providers (used outside of local accounts).
   
   
   
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org
For additional commands, e-mail: gitbox-help@activemq.apache.org
For further information, visit: https://activemq.apache.org/contact



Re: [PR] feat(#1737): Add OAuth2 JWT authentication support via JAAS LoginModule [activemq]

Posted by "jbonofre (via GitHub)" <gi...@apache.org>.
jbonofre commented on PR #1738:
URL: https://github.com/apache/activemq/pull/1738#issuecomment-4036942488

   > I think this should go into a separate module and get deployed into an extras folder (with the 3rd party) dependency instead of installed into the classpath by default for _every_ running broker.
   
   @mattrpav what is the concern about the Nimbus dependency in the JAAS module ?
   
   At the end, regarding the ActiveMQ distribution, it will be a dependency like another (like Jetty or Rome for instance).
   
   Your concern is about the "embedded" ActiveMQ service in application (`BrokerService`) ?


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org
For additional commands, e-mail: gitbox-help@activemq.apache.org
For further information, visit: https://activemq.apache.org/contact



Re: [PR] feat(#1737): Add OAuth2 JWT authentication support via JAAS LoginModule [activemq]

Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] commented on PR #1738:
URL: https://github.com/apache/activemq/pull/1738#issuecomment-5805941513

   This PR is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 5 days.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org
For additional commands, e-mail: gitbox-help@activemq.apache.org
For further information, visit: https://activemq.apache.org/contact



Re: [PR] feat(#1737): Add OAuth2 JWT authentication support via JAAS LoginModule [activemq]

Posted by "cshannon (via GitHub)" <gi...@apache.org>.
cshannon commented on PR #1738:
URL: https://github.com/apache/activemq/pull/1738#issuecomment-6219216209

   This is a very large change and I think it's better to target for 6.5.0 unless @mattrpav has time to review it in detail. We need to finish 6.4.0 and other bug fix releases ASAP and i won't have time to review something this large before then.
   
   Given that this is security related, rushing is a bad idea because we don't want to get a bunch of CVE reports if something is missed so it probably needs more time for review


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org
For additional commands, e-mail: gitbox-help@activemq.apache.org
For further information, visit: https://activemq.apache.org/contact



Re: [PR] feat(#1737): Add OAuth2 JWT authentication support via JAAS LoginModule [activemq]

Posted by "jeanouii (via GitHub)" <gi...@apache.org>.
jeanouii commented on code in PR #1738:
URL: https://github.com/apache/activemq/pull/1738#discussion_r2904060641


##########
activemq-jaas/src/main/java/org/apache/activemq/jaas/OAuth2LoginModule.java:
##########
@@ -0,0 +1,342 @@
+/**
+ * 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.jaas;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.security.Principal;
+import java.text.ParseException;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.auth.login.FailedLoginException;
+import javax.security.auth.login.LoginException;
+import javax.security.auth.spi.LoginModule;
+
+import com.nimbusds.jose.JOSEException;
+import com.nimbusds.jose.JWSAlgorithm;
+import com.nimbusds.jose.jwk.source.JWKSource;
+import com.nimbusds.jose.jwk.source.JWKSourceBuilder;
+import com.nimbusds.jose.proc.BadJOSEException;
+import com.nimbusds.jose.proc.JWSKeySelector;
+import com.nimbusds.jose.proc.JWSVerificationKeySelector;
+import com.nimbusds.jose.proc.SecurityContext;
+import com.nimbusds.jwt.JWTClaimsSet;
+import com.nimbusds.jwt.proc.ConfigurableJWTProcessor;
+import com.nimbusds.jwt.proc.DefaultJWTClaimsVerifier;
+import com.nimbusds.jwt.proc.DefaultJWTProcessor;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A JAAS LoginModule that authenticates users via OAuth2 JWT access tokens.
+ * <p>
+ * The client passes the JWT access token as the password in the connection info.
+ * The module validates the token signature using the JWKS endpoint and verifies
+ * standard claims (issuer, audience, expiration).
+ * <p>
+ * Configuration options (in login.config):
+ * <ul>
+ *   <li>{@code oauth2.jwksUrl} (required) - URL to the JWKS endpoint for signature verification</li>
+ *   <li>{@code oauth2.issuer} (required) - Expected token issuer (iss claim)</li>
+ *   <li>{@code oauth2.audience} (optional) - Expected token audience (aud claim)</li>
+ *   <li>{@code oauth2.usernameClaim} (optional, default: "sub") - JWT claim to use as username</li>
+ *   <li>{@code oauth2.groupsClaim} (optional, default: "groups") - JWT claim containing group memberships</li>
+ *   <li>{@code debug} (optional) - Enable debug logging</li>
+ * </ul>
+ * <p>
+ * Example login.config:
+ * <pre>
+ * activemq-oauth2 {
+ *     org.apache.activemq.jaas.OAuth2LoginModule required
+ *         oauth2.jwksUrl="https://idp.example.com/.well-known/jwks.json"
+ *         oauth2.issuer="https://idp.example.com"
+ *         oauth2.audience="activemq"
+ *         oauth2.usernameClaim="preferred_username"
+ *         oauth2.groupsClaim="roles";
+ * };
+ * </pre>
+ */
+public class OAuth2LoginModule implements LoginModule {
+
+    private static final Logger LOG = LoggerFactory.getLogger(OAuth2LoginModule.class);
+
+    static final String JWKS_URL_OPTION = "oauth2.jwksUrl";
+    static final String ISSUER_OPTION = "oauth2.issuer";
+    static final String AUDIENCE_OPTION = "oauth2.audience";
+    static final String USERNAME_CLAIM_OPTION = "oauth2.usernameClaim";
+    static final String GROUPS_CLAIM_OPTION = "oauth2.groupsClaim";
+
+    private static final String DEFAULT_USERNAME_CLAIM = "sub";
+    private static final String DEFAULT_GROUPS_CLAIM = "groups";
+
+    private Subject subject;
+    private CallbackHandler callbackHandler;
+    private boolean debug;
+
+    private String jwksUrl;
+    private String issuer;
+    private String audience;
+    private String usernameClaim;
+    private String groupsClaim;
+
+    private String user;
+    private final Set<Principal> principals = new HashSet<>();
+    private boolean succeeded;
+    private boolean commitSucceeded;
+
+    private ConfigurableJWTProcessor<SecurityContext> jwtProcessor;
+
+    @Override
+    public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, Map<String, ?> options) {
+        this.subject = subject;
+        this.callbackHandler = callbackHandler;
+        this.succeeded = false;
+        this.debug = Boolean.parseBoolean((String) options.get("debug"));
+
+        this.jwksUrl = (String) options.get(JWKS_URL_OPTION);
+        this.issuer = (String) options.get(ISSUER_OPTION);
+        this.audience = (String) options.get(AUDIENCE_OPTION);
+
+        String userClaim = (String) options.get(USERNAME_CLAIM_OPTION);
+        this.usernameClaim = (userClaim != null && !userClaim.isEmpty()) ? userClaim : DEFAULT_USERNAME_CLAIM;
+
+        String grpClaim = (String) options.get(GROUPS_CLAIM_OPTION);
+        this.groupsClaim = (grpClaim != null && !grpClaim.isEmpty()) ? grpClaim : DEFAULT_GROUPS_CLAIM;
+
+        if (debug) {
+            LOG.debug("OAuth2LoginModule initialized with jwksUrl={}, issuer={}, audience={}, usernameClaim={}, groupsClaim={}",
+                    jwksUrl, issuer, audience, usernameClaim, groupsClaim);
+        }
+    }
+
+    @Override
+    public boolean login() throws LoginException {
+        if (jwksUrl == null || jwksUrl.isEmpty()) {

Review Comment:
   Same for issuer I think



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org
For additional commands, e-mail: gitbox-help@activemq.apache.org
For further information, visit: https://activemq.apache.org/contact



Re: [PR] feat(#1737): Add OAuth2 JWT authentication support via JAAS LoginModule [activemq]

Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] closed pull request #1738: feat(#1737): Add OAuth2 JWT authentication support via JAAS LoginModule
URL: https://github.com/apache/activemq/pull/1738


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org
For additional commands, e-mail: gitbox-help@activemq.apache.org
For further information, visit: https://activemq.apache.org/contact



Re: [PR] feat(#1737): Add OAuth2 JWT authentication support via JAAS LoginModule [activemq]

Posted by "jbonofre (via GitHub)" <gi...@apache.org>.
jbonofre commented on PR #1738:
URL: https://github.com/apache/activemq/pull/1738#issuecomment-6269917228

   @cshannon @mattrpav are we good to include in 6.4.0 (as it's addition, I think it's fine, I will just check `LICENSE`/`NOTICE`) or do you prefer 6.5.0?


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org
For additional commands, e-mail: gitbox-help@activemq.apache.org
For further information, visit: https://activemq.apache.org/contact



Re: [PR] feat(#1737): Add OAuth2 JWT authentication support via JAAS LoginModule [activemq]

Posted by "jbonofre (via GitHub)" <gi...@apache.org>.
jbonofre commented on code in PR #1738:
URL: https://github.com/apache/activemq/pull/1738#discussion_r4310743414


##########
assembly/src/release/conf/login.config:
##########


Review Comment:
   Done



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org
For additional commands, e-mail: gitbox-help@activemq.apache.org
For further information, visit: https://activemq.apache.org/contact



Re: [PR] feat(#1737): Add OAuth2 JWT authentication support via JAAS LoginModule [activemq]

Posted by "mattrpav (via GitHub)" <gi...@apache.org>.
mattrpav commented on code in PR #1738:
URL: https://github.com/apache/activemq/pull/1738#discussion_r2915372705


##########
activemq-jaas/src/main/java/org/apache/activemq/jaas/OAuth2LoginModule.java:
##########
@@ -0,0 +1,343 @@
+/**
+ * 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.jaas;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.security.Principal;
+import java.text.ParseException;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.auth.login.FailedLoginException;
+import javax.security.auth.login.LoginException;
+import javax.security.auth.spi.LoginModule;
+
+import com.nimbusds.jose.JOSEException;
+import com.nimbusds.jose.JWSAlgorithm;
+import com.nimbusds.jose.jwk.source.JWKSource;
+import com.nimbusds.jose.jwk.source.JWKSourceBuilder;
+import com.nimbusds.jose.proc.BadJOSEException;
+import com.nimbusds.jose.proc.JWSKeySelector;
+import com.nimbusds.jose.proc.JWSVerificationKeySelector;
+import com.nimbusds.jose.proc.SecurityContext;
+import com.nimbusds.jwt.JWTClaimsSet;
+import com.nimbusds.jwt.proc.ConfigurableJWTProcessor;
+import com.nimbusds.jwt.proc.DefaultJWTClaimsVerifier;
+import com.nimbusds.jwt.proc.DefaultJWTProcessor;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A JAAS LoginModule that authenticates users via OAuth2 JWT access tokens.
+ * <p>
+ * The client passes the JWT access token as the password in the connection info.
+ * The module validates the token signature using the JWKS endpoint and verifies
+ * standard claims (issuer, audience, expiration).
+ * <p>
+ * Configuration options (in login.config):
+ * <ul>
+ *   <li>{@code oauth2.jwksUrl} (required) - URL to the JWKS endpoint for signature verification</li>
+ *   <li>{@code oauth2.issuer} (required) - Expected token issuer (iss claim)</li>
+ *   <li>{@code oauth2.audience} (optional) - Expected token audience (aud claim)</li>
+ *   <li>{@code oauth2.usernameClaim} (optional, default: "sub") - JWT claim to use as username</li>
+ *   <li>{@code oauth2.groupsClaim} (optional, default: "groups") - JWT claim containing group memberships</li>
+ *   <li>{@code debug} (optional) - Enable debug logging</li>
+ * </ul>
+ * <p>
+ * Example login.config:
+ * <pre>
+ * activemq-oauth2 {
+ *     org.apache.activemq.jaas.OAuth2LoginModule required
+ *         oauth2.jwksUrl="https://idp.example.com/.well-known/jwks.json"
+ *         oauth2.issuer="https://idp.example.com"
+ *         oauth2.audience="activemq"
+ *         oauth2.usernameClaim="preferred_username"
+ *         oauth2.groupsClaim="roles";
+ * };
+ * </pre>
+ */
+public class OAuth2LoginModule implements LoginModule {
+
+    private static final Logger LOG = LoggerFactory.getLogger(OAuth2LoginModule.class);
+
+    static final String JWKS_URL_OPTION = "oauth2.jwksUrl";
+    static final String ISSUER_OPTION = "oauth2.issuer";
+    static final String AUDIENCE_OPTION = "oauth2.audience";
+    static final String USERNAME_CLAIM_OPTION = "oauth2.usernameClaim";
+    static final String GROUPS_CLAIM_OPTION = "oauth2.groupsClaim";
+
+    private static final String DEFAULT_USERNAME_CLAIM = "sub";
+    private static final String DEFAULT_GROUPS_CLAIM = "groups";
+
+    private Subject subject;
+    private CallbackHandler callbackHandler;
+    private boolean debug;
+
+    private String jwksUrl;
+    private String issuer;
+    private String audience;
+    private String usernameClaim;
+    private String groupsClaim;
+
+    private String user;
+    private final Set<Principal> principals = new HashSet<>();

Review Comment:
   This should be a LinkedHashSet to ensure ordering (UserPrincipal first)



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org
For additional commands, e-mail: gitbox-help@activemq.apache.org
For further information, visit: https://activemq.apache.org/contact



Re: [PR] feat(#1737): Add OAuth2 JWT authentication support via JAAS LoginModule [activemq]

Posted by "jbonofre (via GitHub)" <gi...@apache.org>.
jbonofre commented on PR #1738:
URL: https://github.com/apache/activemq/pull/1738#issuecomment-4060831859

   @mattrpav that's fair. I'm not a big fan of `activemq-jaas-extras`, I would prefer to have `activemq-jaas-oauth2`.
   
   I will update the PR accordingly.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org
For additional commands, e-mail: gitbox-help@activemq.apache.org
For further information, visit: https://activemq.apache.org/contact



Re: [PR] feat(#1737): Add OAuth2 JWT authentication support via JAAS LoginModule [activemq]

Posted by "jbonofre (via GitHub)" <gi...@apache.org>.
jbonofre commented on PR #1738:
URL: https://github.com/apache/activemq/pull/1738#issuecomment-4060897829

   @jeanouii @mattrpav I moved the `OAuth2LoginModule` in a dedicated `activemq-oauth2` module.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org
For additional commands, e-mail: gitbox-help@activemq.apache.org
For further information, visit: https://activemq.apache.org/contact



Re: [PR] feat(#1737): Add OAuth2 JWT authentication support via JAAS LoginModule [activemq]

Posted by "jbonofre (via GitHub)" <gi...@apache.org>.
jbonofre commented on PR #1738:
URL: https://github.com/apache/activemq/pull/1738#issuecomment-4105654947

   NB: I will update the `LICENSE`/`NOTICE` to document nimbus.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org
For additional commands, e-mail: gitbox-help@activemq.apache.org
For further information, visit: https://activemq.apache.org/contact



Re: [PR] feat(#1737): Add OAuth2 JWT authentication support via JAAS LoginModule [activemq]

Posted by "jbonofre (via GitHub)" <gi...@apache.org>.
jbonofre commented on PR #1738:
URL: https://github.com/apache/activemq/pull/1738#issuecomment-6214799818

   @cshannon @mattrpav I updated this PR:
   - now it's a isolated in a dedicated module (I included in the distribution with LICENSE/NOTICE updated, but not enabled by default, user has to configure the `login.config`)
   - I added support for network security


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: gitbox-unsubscribe@activemq.apache.org
For additional commands, e-mail: gitbox-help@activemq.apache.org
For further information, visit: https://activemq.apache.org/contact