SpnegoEngineTest.java
/*
* Copyright (c) 2023 AsyncHttpClient Project. All rights reserved.
*
* Licensed 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.asynchttpclient.spnego;
import io.github.artsok.RepeatedIfExceptionsTest;
import org.apache.commons.io.FileUtils;
import org.apache.kerby.kerberos.kerb.server.SimpleKdcServer;
import org.asynchttpclient.AbstractBasicTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class SpnegoEngineTest extends AbstractBasicTest {
private SimpleKdcServer kerbyServer;
private String basedir;
private String alice;
private String bob;
private File aliceKeytab;
private File bobKeytab;
private File loginConfig;
@BeforeEach
public void startServers() throws Exception {
basedir = System.getProperty("basedir");
if (basedir == null) {
basedir = new File(".").getCanonicalPath();
}
// System.setProperty("sun.security.krb5.debug", "true");
System.setProperty("java.security.krb5.conf",
new File(basedir + File.separator + "target" + File.separator + "krb5.conf").getCanonicalPath());
loginConfig = new File(basedir + File.separator + "target" + File.separator + "kerberos.jaas");
System.setProperty("java.security.auth.login.config", loginConfig.getCanonicalPath());
kerbyServer = new SimpleKdcServer();
kerbyServer.setKdcRealm("service.ws.apache.org");
kerbyServer.setAllowUdp(false);
kerbyServer.setWorkDir(new File(basedir, "target"));
//kerbyServer.setInnerKdcImpl(new NettyKdcServerImpl(kerbyServer.getKdcSetting()));
kerbyServer.init();
// Create principals
alice = "alice@service.ws.apache.org";
bob = "bob/service.ws.apache.org@service.ws.apache.org";
kerbyServer.createPrincipal(alice, "alice");
kerbyServer.createPrincipal(bob, "bob");
aliceKeytab = new File(basedir + File.separator + "target" + File.separator + "alice.keytab");
bobKeytab = new File(basedir + File.separator + "target" + File.separator + "bob.keytab");
kerbyServer.exportPrincipal(alice, aliceKeytab);
kerbyServer.exportPrincipal(bob, bobKeytab);
kerbyServer.start();
FileUtils.copyInputStreamToFile(SpnegoEngine.class.getResourceAsStream("/kerberos.jaas"), loginConfig);
}
@RepeatedIfExceptionsTest(repeats = 5)
public void testSpnegoGenerateTokenWithUsernamePassword() throws Exception {
SpnegoEngine spnegoEngine = new SpnegoEngine("alice",
"alice",
"bob",
"service.ws.apache.org",
false,
null,
"alice",
null);
String token = spnegoEngine.generateToken("localhost");
assertNotNull(token);
assertTrue(token.startsWith("YII"));
}
@Test
public void testSpnegoGenerateTokenWithNullPasswordFail() {
SpnegoEngine spnegoEngine = new SpnegoEngine("alice",
null,
"bob",
"service.ws.apache.org",
false,
null,
"alice",
null);
assertThrows(SpnegoEngineException.class, () -> spnegoEngine.generateToken("localhost"), "No password provided");
}
@RepeatedIfExceptionsTest(repeats = 5)
public void testSpnegoGenerateTokenWithUsernamePasswordFail() throws Exception {
SpnegoEngine spnegoEngine = new SpnegoEngine("alice",
"wrong password",
"bob",
"service.ws.apache.org",
false,
null,
"alice",
null);
assertThrows(SpnegoEngineException.class, () -> spnegoEngine.generateToken("localhost"));
}
@RepeatedIfExceptionsTest(repeats = 5)
public void testSpnegoGenerateTokenWithCustomLoginConfig() throws Exception {
Map<String, String> loginConfig = new HashMap<>();
loginConfig.put("useKeyTab", "true");
loginConfig.put("storeKey", "true");
loginConfig.put("refreshKrb5Config", "true");
loginConfig.put("keyTab", aliceKeytab.getCanonicalPath());
loginConfig.put("principal", alice);
loginConfig.put("debug", String.valueOf(true));
SpnegoEngine spnegoEngine = new SpnegoEngine(null,
null,
"bob",
"service.ws.apache.org",
false,
loginConfig,
null,
null);
String token = spnegoEngine.generateToken("localhost");
assertNotNull(token);
assertTrue(token.startsWith("YII"));
}
@RepeatedIfExceptionsTest(repeats = 5)
public void testGetCompleteServicePrincipalName() throws Exception {
{
SpnegoEngine spnegoEngine = new SpnegoEngine(null,
null,
"bob",
"service.ws.apache.org",
false,
null,
null,
null);
assertEquals("bob@service.ws.apache.org", spnegoEngine.getCompleteServicePrincipalName("localhost"));
}
{
SpnegoEngine spnegoEngine = new SpnegoEngine(null,
null,
null,
"service.ws.apache.org",
true,
null,
null,
null);
assertTrue(spnegoEngine.getCompleteServicePrincipalName("localhost").startsWith("HTTP@"));
}
{
SpnegoEngine spnegoEngine = new SpnegoEngine(null,
null,
null,
"service.ws.apache.org",
false,
null,
null,
null);
assertEquals("HTTP@localhost", spnegoEngine.getCompleteServicePrincipalName("localhost"));
}
}
@AfterEach
public void cleanup() throws Exception {
if (kerbyServer != null) {
kerbyServer.stop();
}
FileUtils.deleteQuietly(aliceKeytab);
FileUtils.deleteQuietly(bobKeytab);
FileUtils.deleteQuietly(loginConfig);
}
}