ARTEMIS-4195 Auth callback to get Client ID

introduce ClientIDCallback to allow JAAS login module to retrieve Client
ID
This commit is contained in:
Alexey Markevich 2023-03-02 23:35:21 +01:00 committed by Justin Bertram
parent 6851e7d677
commit 61c687ec9c
3 changed files with 161 additions and 17 deletions

View File

@ -0,0 +1,43 @@
/*
* 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.artemis.spi.core.security.jaas;
import javax.security.auth.callback.Callback;
/**
* A Callback for getting the Client ID.
*/
public class ClientIDCallback implements Callback {
private String clientID;
/**
* Setter for Client ID.
* @param cid The Client ID to be returned.
*/
public void setClientID(String cid) {
clientID = cid;
}
/**
* Getter for peer Client ID.
* @return The Client ID being carried.
*/
public String getClientID() {
return clientID;
}
}

View File

@ -34,7 +34,7 @@ import javax.security.auth.kerberos.KerberosPrincipal;
import org.apache.activemq.artemis.spi.core.protocol.RemotingConnection;
/**
* A JAAS username password CallbackHandler.
* A JAAS CallbackHandler.
*/
public class JaasCallbackHandler implements CallbackHandler {
@ -52,23 +52,11 @@ public class JaasCallbackHandler implements CallbackHandler {
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
for (Callback callback : callbacks) {
if (callback instanceof PasswordCallback) {
PasswordCallback passwordCallback = (PasswordCallback) callback;
if (password == null) {
passwordCallback.setPassword(null);
} else {
passwordCallback.setPassword(password.toCharArray());
}
((PasswordCallback) callback).setPassword(password != null ? password.toCharArray() : null);
} else if (callback instanceof NameCallback) {
NameCallback nameCallback = (NameCallback) callback;
if (username == null) {
nameCallback.setName(null);
} else {
nameCallback.setName(username);
}
((NameCallback) callback).setName(username);
} else if (callback instanceof CertificateCallback) {
CertificateCallback certCallback = (CertificateCallback) callback;
certCallback.setCertificates(getCertsFromConnection(remotingConnection));
((CertificateCallback) callback).setCertificates(getCertsFromConnection(remotingConnection));
} else if (callback instanceof PrincipalsCallback) {
PrincipalsCallback principalsCallback = (PrincipalsCallback) callback;
@ -79,7 +67,7 @@ public class JaasCallbackHandler implements CallbackHandler {
return;
}
Set<Principal> principals = peerSubject.getPrincipals();
if (principals.size() > 0) {
if (!principals.isEmpty()) {
principalsCallback.setPeerPrincipals(principals.toArray(new Principal[0]));
return;
}
@ -89,6 +77,8 @@ public class JaasCallbackHandler implements CallbackHandler {
if (peerPrincipalFromConnection != null) {
principalsCallback.setPeerPrincipals(new Principal[] {peerPrincipalFromConnection});
}
} else if (callback instanceof ClientIDCallback) {
((ClientIDCallback) callback).setClientID(remotingConnection.getClientID());
} else {
throw new UnsupportedCallbackException(callback);
}

View File

@ -0,0 +1,111 @@
/*
* 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.artemis.spi.core.security.jaas;
import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.TextInputCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import java.security.Principal;
import java.util.Collections;
import org.apache.activemq.artemis.core.management.impl.ManagementRemotingConnection;
import org.junit.Test;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
public class JaasCallbackHandlerTest {
@Test
public void handlePasswordCallback() throws Exception {
final String password = "password";
PasswordCallback passwordCallback = new PasswordCallback("prompt", false);
new JaasCallbackHandler(null, password, null).handle(new Callback[]{passwordCallback});
assertEquals(password, new String(passwordCallback.getPassword()));
new JaasCallbackHandler(null, null, null).handle(new Callback[]{passwordCallback});
assertNull(passwordCallback.getPassword());
}
@Test
public void handleNameCallback() throws Exception {
final String username = "username";
NameCallback nameCallback = new NameCallback("prompt");
new JaasCallbackHandler(username, null, null).handle(new Callback[]{nameCallback});
assertEquals(username, nameCallback.getName());
new JaasCallbackHandler(null, null, null).handle(new Callback[]{nameCallback});
assertNull(nameCallback.getName());
}
@Test
public void handleCertificateCallback() throws Exception {
CertificateCallback certificateCallback = new CertificateCallback();
new JaasCallbackHandler(null, null, null).handle(new Callback[]{certificateCallback});
assertNull(certificateCallback.getCertificates());
}
@Test
public void handlePrincipalsCallback() throws Exception {
PrincipalsCallback principalsCallback = new PrincipalsCallback();
new JaasCallbackHandler(null, null, new ManagementRemotingConnection()).handle(new Callback[]{principalsCallback});
assertNull(principalsCallback.getPeerPrincipals());
final Principal principal = new UserPrincipal("");
ManagementRemotingConnection remotingConnection = new ManagementRemotingConnection() {
@Override
public Subject getSubject() {
return new Subject(false, Collections.singleton(principal), Collections.emptySet(), Collections.emptySet());
}
};
new JaasCallbackHandler(null, null, remotingConnection).handle(new Callback[]{principalsCallback});
assertArrayEquals(new Principal[]{principal}, principalsCallback.getPeerPrincipals());
}
@Test
public void handleClientIDCallback() throws Exception {
final String clientID = "clientID";
ClientIDCallback clientIDCallback = new ClientIDCallback();
ManagementRemotingConnection remotingConnection = new ManagementRemotingConnection() {
@Override
public String getClientID() {
return clientID;
}
};
new JaasCallbackHandler(null, null, remotingConnection).handle(new Callback[]{clientIDCallback});
assertEquals(clientID, clientIDCallback.getClientID());
new JaasCallbackHandler(null, null, new ManagementRemotingConnection()).handle(new Callback[]{clientIDCallback});
assertNull(clientIDCallback.getClientID());
}
@Test(expected = UnsupportedCallbackException.class)
public void handleUnsupported() throws Exception {
new JaasCallbackHandler(null, null, null).handle(new Callback[]{new TextInputCallback("prompt")});
}
}