public boolean handleSecurity(HttpServletRequest request, HttpServletResponse response) throws IOException {
if (log.isTraceEnabled())
HttpUtils.logRequestHeaders(log, request);
+ ClassLoader currentThreadContextClassLoader = Thread.currentThread().getContextClassLoader();
+ Thread.currentThread().setContextClassLoader(CmsServletContext.class.getClassLoader());
LoginContext lc;
try {
lc = CmsAuth.USER.newLoginContext(
HttpUtils.logResponseHeaders(log, response);
if (lc == null)
return false;
+ } finally {
+ Thread.currentThread().setContextClassLoader(currentThreadContextClassLoader);
}
Subject subject = lc.getSubject();
ClassLoader currentContextClassLoader = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(CmsServletContext.class.getClassLoader());
- LoginContext lc = new LoginContext(CmsAuth.LOGIN_CONTEXT_ANONYMOUS,
+ LoginContext lc = CmsAuth.ANONYMOUS.newLoginContext(
new RemoteAuthCallbackHandler(new ServletHttpRequest(request), new ServletHttpResponse(response)));
lc.login();
return lc;
OSGI-INF/acrContentRepository.xml,\
OSGI-INF/uuidFactory.xml
source.. = src/
+additional.bundles = org.argeo.ext.slf4j,\
+ org.slf4j.commons.logging,\
+ org.slf4j.api,\
+ org.apache.commons.codec
//
/** Either a host or an IP address. Restricts all servers to it. */
HOST("argeo.host"),
+ /** Either a host or an IP address. Restricts all servers to it. */
+ DNS("argeo.dns", 16),
//
// HTTP
//
}
public static void main(String[] args) {
- if (args.length == 0) {
- System.err.println("usage: java " + SpnegoAuthScheme.class.getName() + " <url>");
+ String principal = System.getProperty("javax.security.auth.login.name");
+ if (args.length == 0 || principal == null) {
+ System.err.println("usage: java -Djavax.security.auth.login.name=<principal@REALM> "
+ + SpnegoAuthScheme.class.getName() + " <url>");
System.exit(1);
return;
}
SINGLE_USER {
com.sun.security.auth.module.Krb5LoginModule optional
- principal="${user.name}"
useTicketCache=true;
};
import java.io.File;
import java.io.IOException;
-import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.URI;
import java.net.URISyntaxException;
super.start();
List<Dictionary<String, Object>> configs = getUserDirectoryConfigs();
for (Dictionary<String, Object> config : configs) {
- UserDirectory userDirectory = enableUserDirectory(config);
- if (userDirectory.getRealm().isPresent())
- loadIpaJaasConfiguration();
+ enableUserDirectory(config);
+// if (userDirectory.getRealm().isPresent())
+// loadIpaJaasConfiguration();
}
log.debug(() -> "CMS user admin available");
}
Optional<String> realm = userDirectory.getRealm();
if (realm.isPresent()) {
+ loadIpaJaasConfiguration();
if (Files.exists(nodeKeyTab)) {
String servicePrincipal = getKerberosServicePrincipal(realm.get());
if (servicePrincipal != null) {
}
};
try {
- LoginContext nodeLc = new LoginContext(CmsAuth.LOGIN_CONTEXT_NODE, callbackHandler);
+ LoginContext nodeLc = CmsAuth.NODE.newLoginContext(callbackHandler);
nodeLc.login();
acceptorCredentials = logInAsAcceptor(nodeLc.getSubject(), servicePrincipal);
} catch (LoginException e) {
}
}
- private String getKerberosServicePrincipal(String realm) {
- String hostname;
- try (DnsBrowser dnsBrowser = new DnsBrowser()) {
- InetAddress localhost = InetAddress.getLocalHost();
- hostname = localhost.getHostName();
+ protected String getKerberosServicePrincipal(String realm) {
+ if (!Files.exists(nodeKeyTab))
+ return null;
+ List<String> dns = CmsStateImpl.getDeployProperties(cmsState, CmsDeployProperty.DNS);
+ String hostname = CmsStateImpl.getDeployProperty(cmsState, CmsDeployProperty.HOST);
+ try (DnsBrowser dnsBrowser = new DnsBrowser(dns)) {
+ hostname = hostname != null ? hostname : InetAddress.getLocalHost().getHostName();
String dnsZone = hostname.substring(hostname.indexOf('.') + 1);
- String ipfromDns = dnsBrowser.getRecord(hostname, localhost instanceof Inet6Address ? "AAAA" : "A");
- boolean consistentIp = localhost.getHostAddress().equals(ipfromDns);
+ String ipv4fromDns = dnsBrowser.getRecord(hostname, "A");
+ String ipv6fromDns = dnsBrowser.getRecord(hostname, "AAAA");
+ if (ipv4fromDns == null && ipv6fromDns == null)
+ throw new IllegalStateException("hostname " + hostname + " is not registered in DNS");
+ // boolean consistentIp = localhost.getHostAddress().equals(ipfromDns);
String kerberosDomain = dnsBrowser.getRecord("_kerberos." + dnsZone, "TXT");
- if (consistentIp && kerberosDomain != null && kerberosDomain.equals(realm) && Files.exists(nodeKeyTab)) {
+ if (kerberosDomain != null && kerberosDomain.equals(realm)) {
return KernelConstants.DEFAULT_KERBEROS_SERVICE + "/" + hostname + "@" + kerberosDomain;
} else
return null;
SINGLE_USER {
com.sun.security.auth.module.Krb5LoginModule optional
- principal="${user.name}"
storeKey=true
- useTicketCache=true
- debug=true;
+ useTicketCache=true;
org.argeo.cms.auth.SingleUserLoginModule requisite;
};
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.SortedSet;
+import java.util.StringJoiner;
import java.util.TreeMap;
import java.util.TreeSet;
import javax.naming.Binding;
+import javax.naming.Context;
+import javax.naming.NameNotFoundException;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
private final DirContext initialCtx;
public DnsBrowser() throws NamingException {
- this(null);
+ this(new ArrayList<>());
}
- public DnsBrowser(String dnsServerUrls) throws NamingException {
+ public DnsBrowser(List<String> dnsServerUrls) throws NamingException {
+ Objects.requireNonNull(dnsServerUrls);
Hashtable<String, Object> env = new Hashtable<>();
- env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory");
- if (dnsServerUrls != null)
- env.put("java.naming.provider.url", dnsServerUrls);
+ env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.dns.DnsContextFactory");
+ if (!dnsServerUrls.isEmpty()) {
+ StringJoiner providerUrl = new StringJoiner(" ");
+ for (String dnsUrl : dnsServerUrls) {
+ if (dnsUrl != null)
+ providerUrl.add(dnsUrl);
+ }
+ env.put(Context.PROVIDER_URL, providerUrl.toString());
+ }
initialCtx = new InitialDirContext(env);
}
* Return a single record (typically A, AAAA, etc. or null if not available.
* Will fail if multiple records.
*/
- public String getRecord(String name, String recordType) throws NamingException {
- Attributes attrs = initialCtx.getAttributes(name, new String[] { recordType });
- if (attrs.size() == 0)
+ public String getRecord(String name, String recordType) {
+ try {
+ Attributes attrs = initialCtx.getAttributes(name, new String[] { recordType });
+ if (attrs.size() == 0)
+ return null;
+ Attribute attr = attrs.get(recordType);
+ if (attr.size() > 1)
+ throw new IllegalArgumentException("Multiple record type " + recordType);
+ assert attr.size() != 0;
+ Object value = attr.get();
+ assert value != null;
+ return value.toString();
+ } catch (NameNotFoundException e) {
return null;
- Attribute attr = attrs.get(recordType);
- if (attr.size() > 1)
- throw new IllegalArgumentException("Multiple record type " + recordType);
- assert attr.size() != 0;
- Object value = attr.get();
- assert value != null;
- return value.toString();
+ } catch (NamingException e) {
+ throw new IllegalStateException("Cannot get DNS entry " + recordType + " of " + name, e);
+ }
}
/**