org.wildfly.security.auth.realm.ldap.AttributeMapping Maven / Gradle / Ivy
/*
* JBoss, Home of Professional Open Source.
* Copyright 2015 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* 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.wildfly.security.auth.realm.ldap;
import java.util.Locale;
import org.wildfly.common.Assert;
import javax.naming.directory.DirContext;
/**
* Definition of a mapping from LDAP to an Elytron attribute.
*
* @author Darran Lofthouse
*/
public class AttributeMapping {
public static final String DEFAULT_FILTERED_NAME = "filtered";
public static final String DEFAULT_DN_NAME = "dn";
public static final String DEFAULT_ROLE_RECURSION_ATTRIBUTE = "CN";
private final String ldapName;
private final String searchDn;
private final boolean recursiveSearch;
private final String filter;
private final String reference;
private final String name;
private final String rdn;
private final int roleRecursionDepth;
private final String roleRecursionName;
String getLdapName() {
return ldapName;
}
/**
* Get name of LDAP attribute to obtain from identity entry
* @return LDAP attribute to obtain from identity entry
*/
String getIdentityLdapName() {
if (filter != null) return null;
return reference != null ? reference : ldapName;
}
String getName() {
return name;
}
String getSearchDn() {
return searchDn;
}
boolean getRecursiveSearch() {
return recursiveSearch;
}
String getFilter() {
return filter;
}
String getRdn() {
return rdn;
}
String getReference() {
return reference;
}
int getRoleRecursionDepth() {
return roleRecursionDepth;
}
String getRoleRecursionName() {
return roleRecursionName;
}
boolean isFilteredOrReference() {
return filter != null || reference != null;
}
/**
* Determine which context should be used to search filtered/referenced entry.
* Has effect if the identity is behind referral, in different context.
* If {@code true}, attribute will be searched in context, where was the identity found.
* {@link DirContext} of the LdapRealm will be used otherwise.
*/
boolean searchInIdentityContext() {
return reference != null;
}
/**
* Create an attribute mapping using LDAP entry of identity itself.
*
* @return this builder
*/
public static Builder fromIdentity() {
Builder builder = new Builder();
builder.ldapName = null;
return builder;
}
/**
*
Create an attribute mapping based on the results of the given {@code filter}.
*
*
The {@code filter} may have one and exactly one {0} string that will be used to replace with the distinguished
* name of the identity. In this case, the filter is specially useful when the values for this attribute should be obtained from a
* separated entry. For instance, retrieving roles from entries with a object class of groupOfNames where the identity's DN is
* a value of a member attribute.
*
* @param filter the filter that is going to be used to search for entries and obtain values for this attribute
* @return this builder
*/
public static Builder fromFilter(String filter) {
Assert.checkNotNullParam("filter", filter);
Builder builder = new Builder();
builder.filter = filter;
return builder;
}
/**
*
Create an attribute mapping using LDAP entry referenced by attribute of identity entry.
*
* @param reference the name of LDAP attribute containing DN of LDAP entry, from which should be value loaded.
* @return this builder
*/
public static Builder fromReference(String reference) {
Assert.checkNotNullParam("reference", reference);
Builder builder = new Builder();
builder.reference = reference;
return builder;
}
public static class Builder {
private String ldapName;
private String searchDn;
private boolean recursiveSearch = true;
private String filter;
private String reference;
private String name;
private String rdn;
private int roleRecursionDepth;
private String roleRecursionName;
/**
* Set type of RDN, whose value will be used as identity attribute value.
* Use in case the attribute value is in DN form or when DN of entry is used
*
* @param rdn the name of type of RDN
* @return this builder
*/
public Builder extractRdn(String rdn) {
Assert.checkNotNullParam("rdn", rdn);
this.rdn = rdn;
return this;
}
/**
* Set name of the attribute in LDAP from where the values are obtained.
*
* @param ldapName the name of the attribute in LDAP from where the values are obtained
* @return this builder
*/
public Builder from(String ldapName) {
Assert.checkNotNullParam("ldapName", ldapName);
this.ldapName = ldapName.toUpperCase(Locale.ROOT);
return this;
}
/**
* Set name of the attribute in LDAP from where are {0} in role recursion obtained.
* Wildcard {0} is in filter replaced by user name usually. When role recursion is used,
* roles of roles are searched using the same filter, but {0} is replaced by
* role name - obtained from role entry attribute specified by this method.
*
* If not specified, attribute specified in {@link #from(String)} is used.
*
* @param roleRecursionName the name of the attribute in LDAP which will replace {0} in filter while role recursion
* @return this builder
*/
public Builder roleRecursionName(String roleRecursionName) {
Assert.checkNotNullParam("roleRecursionName", roleRecursionName);
this.roleRecursionName = roleRecursionName.toUpperCase(Locale.ROOT);
return this;
}
/**
* Set name of identity attribute to which will be mapping done.
*
* @param name the name of identity attribute (not LDAP attribute)
* @return this builder
*/
public Builder to(String name) {
Assert.checkNotNullParam("name", name);
this.name = name;
return this;
}
/**
* Set search DN of LDAP search for attribute entries.
* If not specified, search DN from identity mapping will be used.
* @param searchDn the name of the context (DN) to be used when executing the filter
* @return this builder
*/
public Builder searchDn(String searchDn) {
Assert.checkNotNullParam("searchDn", searchDn);
Assert.checkNotNullParam("filter", filter);
this.searchDn = searchDn;
return this;
}
/**
* Set whether LDAP search for attribute entries should be recursive. Enabled by default.
* @param recursiveSearch whether the LDAP search should be recursive
* @return this builder
*/
public Builder searchRecursively(boolean recursiveSearch) {
Assert.checkNotNullParam("filter", filter);
this.recursiveSearch = recursiveSearch;
return this;
}
/**
* Set recursive search of filtered attribute (for recursive roles assignment and similar)
* @param roleRecursionDepth maximum depth of recursion, 0 by default (no recursion)
* @return this builder
*/
public Builder roleRecursion(int roleRecursionDepth) {
Assert.checkMinimumParameter("roleRecursionDepth", 0, roleRecursionDepth);
this.roleRecursionDepth = roleRecursionDepth;
return this;
}
public AttributeMapping build() {
if (name == null) {
name = ldapName != null ? ldapName : (filter != null ? DEFAULT_FILTERED_NAME : DEFAULT_DN_NAME);
}
if (roleRecursionName == null) {
roleRecursionName = ldapName != null ? ldapName : DEFAULT_ROLE_RECURSION_ATTRIBUTE;
}
return new AttributeMapping(searchDn, recursiveSearch, filter, reference, ldapName, name, rdn, roleRecursionDepth, roleRecursionName);
}
}
AttributeMapping(String searchDn, boolean recursiveSearch, String filter, String reference, String ldapName, String name, String rdn, int roleRecursionDepth, String roleRecursionName) {
this.searchDn = searchDn;
this.recursiveSearch = recursiveSearch;
this.filter = filter;
this.reference = reference;
this.ldapName = ldapName;
this.name = name;
this.rdn = rdn;
this.roleRecursionDepth = roleRecursionDepth;
this.roleRecursionName = roleRecursionName;
}
}