mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-06-26 13:53:14 +00:00
OPEN - issue SEC-807: Allow mapping to a standard Ldap UserDetails through the namespace
http://jira.springframework.org/browse/SEC-807. Added support for user-details-class attribute to ldap-authentication-provider and ldap-user-service.
This commit is contained in:
parent
104716fedb
commit
e4b32b8d29
@ -93,6 +93,8 @@ public class LdapProviderBeanDefinitionParser implements BeanDefinitionParser {
|
|||||||
RootBeanDefinition ldapProvider = new RootBeanDefinition(LdapAuthenticationProvider.class);
|
RootBeanDefinition ldapProvider = new RootBeanDefinition(LdapAuthenticationProvider.class);
|
||||||
ldapProvider.getConstructorArgumentValues().addGenericArgumentValue(authenticator);
|
ldapProvider.getConstructorArgumentValues().addGenericArgumentValue(authenticator);
|
||||||
ldapProvider.getConstructorArgumentValues().addGenericArgumentValue(LdapUserServiceBeanDefinitionParser.parseAuthoritiesPopulator(elt, parserContext));
|
ldapProvider.getConstructorArgumentValues().addGenericArgumentValue(LdapUserServiceBeanDefinitionParser.parseAuthoritiesPopulator(elt, parserContext));
|
||||||
|
ldapProvider.getPropertyValues().addPropertyValue("userDetailsContextMapper",
|
||||||
|
LdapUserServiceBeanDefinitionParser.parseUserDetailsClass(elt, parserContext));
|
||||||
|
|
||||||
ConfigUtils.getRegisteredProviders(parserContext).add(ldapProvider);
|
ConfigUtils.getRegisteredProviders(parserContext).add(ldapProvider);
|
||||||
|
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
package org.springframework.security.config;
|
package org.springframework.security.config;
|
||||||
|
|
||||||
|
import org.springframework.security.userdetails.ldap.InetOrgPersonContextMapper;
|
||||||
|
import org.springframework.security.userdetails.ldap.LdapUserDetailsMapper;
|
||||||
import org.springframework.security.userdetails.ldap.LdapUserDetailsService;
|
import org.springframework.security.userdetails.ldap.LdapUserDetailsService;
|
||||||
|
import org.springframework.security.userdetails.ldap.PersonContextMapper;
|
||||||
import org.springframework.security.ldap.search.FilterBasedLdapUserSearch;
|
import org.springframework.security.ldap.search.FilterBasedLdapUserSearch;
|
||||||
import org.springframework.security.ldap.populator.DefaultLdapAuthoritiesPopulator;
|
import org.springframework.security.ldap.populator.DefaultLdapAuthoritiesPopulator;
|
||||||
import org.springframework.beans.factory.xml.ParserContext;
|
import org.springframework.beans.factory.xml.ParserContext;
|
||||||
@ -29,6 +32,9 @@ public class LdapUserServiceBeanDefinitionParser extends AbstractUserDetailsServ
|
|||||||
public static final String DEF_GROUP_SEARCH_BASE = "ou=groups";
|
public static final String DEF_GROUP_SEARCH_BASE = "ou=groups";
|
||||||
|
|
||||||
static final String ATT_ROLE_PREFIX = "role-prefix";
|
static final String ATT_ROLE_PREFIX = "role-prefix";
|
||||||
|
static final String ATT_USER_CLASS = "user-details-class";
|
||||||
|
static final String OPT_PERSON = "person";
|
||||||
|
static final String OPT_INETORGPERSON = "inetOrgPerson";
|
||||||
|
|
||||||
protected Class getBeanClass(Element element) {
|
protected Class getBeanClass(Element element) {
|
||||||
return LdapUserDetailsService.class;
|
return LdapUserDetailsService.class;
|
||||||
@ -42,6 +48,7 @@ public class LdapUserServiceBeanDefinitionParser extends AbstractUserDetailsServ
|
|||||||
|
|
||||||
builder.addConstructorArg(parseSearchBean(elt, parserContext));
|
builder.addConstructorArg(parseSearchBean(elt, parserContext));
|
||||||
builder.addConstructorArg(parseAuthoritiesPopulator(elt, parserContext));
|
builder.addConstructorArg(parseAuthoritiesPopulator(elt, parserContext));
|
||||||
|
builder.addPropertyValue("userDetailsMapper", parseUserDetailsClass(elt, parserContext));
|
||||||
}
|
}
|
||||||
|
|
||||||
static RootBeanDefinition parseSearchBean(Element elt, ParserContext parserContext) {
|
static RootBeanDefinition parseSearchBean(Element elt, ParserContext parserContext) {
|
||||||
@ -86,6 +93,17 @@ public class LdapUserServiceBeanDefinitionParser extends AbstractUserDetailsServ
|
|||||||
return contextSource;
|
return contextSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static RootBeanDefinition parseUserDetailsClass(Element elt, ParserContext parserContext) {
|
||||||
|
String userDetailsClass = elt.getAttribute(ATT_USER_CLASS);
|
||||||
|
|
||||||
|
if(OPT_PERSON.equals(userDetailsClass)) {
|
||||||
|
return new RootBeanDefinition(PersonContextMapper.class);
|
||||||
|
} else if (OPT_INETORGPERSON.equals(userDetailsClass)) {
|
||||||
|
return new RootBeanDefinition(InetOrgPersonContextMapper.class);
|
||||||
|
}
|
||||||
|
return new RootBeanDefinition(LdapUserDetailsMapper.class);
|
||||||
|
}
|
||||||
|
|
||||||
static RootBeanDefinition parseAuthoritiesPopulator(Element elt, ParserContext parserContext) {
|
static RootBeanDefinition parseAuthoritiesPopulator(Element elt, ParserContext parserContext) {
|
||||||
String groupSearchFilter = elt.getAttribute(ATT_GROUP_SEARCH_FILTER);
|
String groupSearchFilter = elt.getAttribute(ATT_GROUP_SEARCH_FILTER);
|
||||||
String groupSearchBase = elt.getAttribute(ATT_GROUP_SEARCH_BASE);
|
String groupSearchBase = elt.getAttribute(ATT_GROUP_SEARCH_BASE);
|
||||||
|
@ -90,10 +90,13 @@ user-search-filter-attribute =
|
|||||||
attribute user-search-filter {xsd:string}
|
attribute user-search-filter {xsd:string}
|
||||||
user-search-base-attribute =
|
user-search-base-attribute =
|
||||||
## Search base for user searches. Defaults to "".
|
## Search base for user searches. Defaults to "".
|
||||||
attribute user-search-base {xsd:string}?
|
attribute user-search-base {xsd:string}
|
||||||
group-role-attribute-attribute =
|
group-role-attribute-attribute =
|
||||||
## The LDAP attribute name which contains the role name which will be used within Spring Security. Defaults to "cn".
|
## The LDAP attribute name which contains the role name which will be used within Spring Security. Defaults to "cn".
|
||||||
attribute group-role-attribute {xsd:string}
|
attribute group-role-attribute {xsd:string}
|
||||||
|
user-details-class-attribute =
|
||||||
|
## Allows the objectClass of the user entry to be specified. If set, the framework will attempt to load standard attributes for the defined class into the returned UserDetails object
|
||||||
|
attribute user-details-class {"person" | "inetOrgPerson"}
|
||||||
|
|
||||||
|
|
||||||
ldap-user-service =
|
ldap-user-service =
|
||||||
@ -115,6 +118,8 @@ ldap-us.attlist &=
|
|||||||
cache-ref?
|
cache-ref?
|
||||||
ldap-us.attlist &=
|
ldap-us.attlist &=
|
||||||
role-prefix?
|
role-prefix?
|
||||||
|
ldap-us.attlist &=
|
||||||
|
user-details-class-attribute?
|
||||||
|
|
||||||
ldap-authentication-provider =
|
ldap-authentication-provider =
|
||||||
## Sets up an ldap authentication provider
|
## Sets up an ldap authentication provider
|
||||||
@ -136,6 +141,8 @@ ldap-ap.attlist &=
|
|||||||
attribute user-dn-pattern {xsd:string}?
|
attribute user-dn-pattern {xsd:string}?
|
||||||
ldap-ap.attlist &=
|
ldap-ap.attlist &=
|
||||||
role-prefix?
|
role-prefix?
|
||||||
|
ldap-ap.attlist &=
|
||||||
|
user-details-class-attribute?
|
||||||
|
|
||||||
password-compare-element =
|
password-compare-element =
|
||||||
## Specifies that an LDAP provider should use an LDAP compare operation of the user's password to authenticate the user
|
## Specifies that an LDAP provider should use an LDAP compare operation of the user's password to authenticate the user
|
||||||
|
@ -238,7 +238,7 @@
|
|||||||
<xs:attribute name="user-search-filter" use="required" type="xs:string"/>
|
<xs:attribute name="user-search-filter" use="required" type="xs:string"/>
|
||||||
</xs:attributeGroup>
|
</xs:attributeGroup>
|
||||||
<xs:attributeGroup name="user-search-base-attribute">
|
<xs:attributeGroup name="user-search-base-attribute">
|
||||||
<xs:attribute name="user-search-base" type="xs:string">
|
<xs:attribute name="user-search-base" use="required" type="xs:string">
|
||||||
<xs:annotation>
|
<xs:annotation>
|
||||||
<xs:documentation>Search base for user searches. Defaults to "".</xs:documentation>
|
<xs:documentation>Search base for user searches. Defaults to "".</xs:documentation>
|
||||||
</xs:annotation>
|
</xs:annotation>
|
||||||
@ -252,6 +252,21 @@
|
|||||||
</xs:annotation>
|
</xs:annotation>
|
||||||
</xs:attribute>
|
</xs:attribute>
|
||||||
</xs:attributeGroup>
|
</xs:attributeGroup>
|
||||||
|
<xs:attributeGroup name="user-details-class-attribute">
|
||||||
|
<xs:attribute name="user-details-class" use="required">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Allows the objectClass of the user entry to be specified. If set, the
|
||||||
|
framework will attempt to load standard attributes for the defined class into the returned
|
||||||
|
UserDetails object</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
<xs:simpleType>
|
||||||
|
<xs:restriction base="xs:token">
|
||||||
|
<xs:enumeration value="person"/>
|
||||||
|
<xs:enumeration value="inetOrgPerson"/>
|
||||||
|
</xs:restriction>
|
||||||
|
</xs:simpleType>
|
||||||
|
</xs:attribute>
|
||||||
|
</xs:attributeGroup>
|
||||||
<xs:element name="ldap-user-service" substitutionGroup="security:any-user-service">
|
<xs:element name="ldap-user-service" substitutionGroup="security:any-user-service">
|
||||||
<xs:complexType>
|
<xs:complexType>
|
||||||
<xs:attributeGroup ref="security:ldap-us.attlist"/>
|
<xs:attributeGroup ref="security:ldap-us.attlist"/>
|
||||||
@ -272,7 +287,11 @@
|
|||||||
</xs:annotation>
|
</xs:annotation>
|
||||||
</xs:attribute>
|
</xs:attribute>
|
||||||
<xs:attribute name="user-search-filter" type="xs:string"/>
|
<xs:attribute name="user-search-filter" type="xs:string"/>
|
||||||
<xs:attributeGroup ref="security:user-search-base-attribute"/>
|
<xs:attribute name="user-search-base" type="xs:string">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Search base for user searches. Defaults to "".</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
<xs:attribute name="group-search-filter" type="xs:string">
|
<xs:attribute name="group-search-filter" type="xs:string">
|
||||||
<xs:annotation>
|
<xs:annotation>
|
||||||
<xs:documentation>Group search filter. Defaults to (uniqueMember={0}). The substituted
|
<xs:documentation>Group search filter. Defaults to (uniqueMember={0}). The substituted
|
||||||
@ -303,6 +322,19 @@
|
|||||||
persistent storage (e.g. "ROLE_").</xs:documentation>
|
persistent storage (e.g. "ROLE_").</xs:documentation>
|
||||||
</xs:annotation>
|
</xs:annotation>
|
||||||
</xs:attribute>
|
</xs:attribute>
|
||||||
|
<xs:attribute name="user-details-class">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Allows the objectClass of the user entry to be specified. If set, the
|
||||||
|
framework will attempt to load standard attributes for the defined class into the returned
|
||||||
|
UserDetails object</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
<xs:simpleType>
|
||||||
|
<xs:restriction base="xs:token">
|
||||||
|
<xs:enumeration value="person"/>
|
||||||
|
<xs:enumeration value="inetOrgPerson"/>
|
||||||
|
</xs:restriction>
|
||||||
|
</xs:simpleType>
|
||||||
|
</xs:attribute>
|
||||||
</xs:attributeGroup>
|
</xs:attributeGroup>
|
||||||
<xs:element name="ldap-authentication-provider">
|
<xs:element name="ldap-authentication-provider">
|
||||||
<xs:annotation>
|
<xs:annotation>
|
||||||
@ -362,7 +394,11 @@
|
|||||||
</xs:documentation>
|
</xs:documentation>
|
||||||
</xs:annotation>
|
</xs:annotation>
|
||||||
</xs:attribute>
|
</xs:attribute>
|
||||||
<xs:attributeGroup ref="security:user-search-base-attribute"/>
|
<xs:attribute name="user-search-base" type="xs:string">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Search base for user searches. Defaults to "".</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
<xs:attribute name="user-search-filter" type="xs:string"/>
|
<xs:attribute name="user-search-filter" type="xs:string"/>
|
||||||
<xs:attribute name="group-search-base" type="xs:string">
|
<xs:attribute name="group-search-base" type="xs:string">
|
||||||
<xs:annotation>
|
<xs:annotation>
|
||||||
@ -395,6 +431,19 @@
|
|||||||
persistent storage (e.g. "ROLE_").</xs:documentation>
|
persistent storage (e.g. "ROLE_").</xs:documentation>
|
||||||
</xs:annotation>
|
</xs:annotation>
|
||||||
</xs:attribute>
|
</xs:attribute>
|
||||||
|
<xs:attribute name="user-details-class">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Allows the objectClass of the user entry to be specified. If set, the
|
||||||
|
framework will attempt to load standard attributes for the defined class into the returned
|
||||||
|
UserDetails object</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
<xs:simpleType>
|
||||||
|
<xs:restriction base="xs:token">
|
||||||
|
<xs:enumeration value="person"/>
|
||||||
|
<xs:enumeration value="inetOrgPerson"/>
|
||||||
|
</xs:restriction>
|
||||||
|
</xs:simpleType>
|
||||||
|
</xs:attribute>
|
||||||
</xs:attributeGroup>
|
</xs:attributeGroup>
|
||||||
<xs:attributeGroup name="password-compare.attlist">
|
<xs:attributeGroup name="password-compare.attlist">
|
||||||
<xs:attribute name="password-attribute" type="xs:string">
|
<xs:attribute name="password-attribute" type="xs:string">
|
||||||
|
@ -7,6 +7,8 @@ import org.springframework.security.util.AuthorityUtils;
|
|||||||
import org.springframework.security.util.InMemoryXmlApplicationContext;
|
import org.springframework.security.util.InMemoryXmlApplicationContext;
|
||||||
import org.springframework.security.userdetails.UserDetailsService;
|
import org.springframework.security.userdetails.UserDetailsService;
|
||||||
import org.springframework.security.userdetails.UserDetails;
|
import org.springframework.security.userdetails.UserDetails;
|
||||||
|
import org.springframework.security.userdetails.ldap.InetOrgPerson;
|
||||||
|
import org.springframework.security.userdetails.ldap.Person;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
@ -100,6 +102,27 @@ public class LdapUserServiceBeanDefinitionParserTests {
|
|||||||
"</authentication-provider>");
|
"</authentication-provider>");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void personContextMapperIsSupported() {
|
||||||
|
setContext(
|
||||||
|
"<ldap-server />" +
|
||||||
|
"<ldap-user-service id='ldapUDS' user-search-filter='(uid={0})' user-details-class='person'/>");
|
||||||
|
UserDetailsService uds = (UserDetailsService) appCtx.getBean("ldapUDS");
|
||||||
|
UserDetails ben = uds.loadUserByUsername("ben");
|
||||||
|
assertTrue(ben instanceof Person);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void inetOrgContextMapperIsSupported() {
|
||||||
|
setContext(
|
||||||
|
"<ldap-server id='someServer'/>" +
|
||||||
|
"<ldap-user-service id='ldapUDS' user-search-filter='(uid={0})' user-details-class='inetOrgPerson'/>");
|
||||||
|
UserDetailsService uds = (UserDetailsService) appCtx.getBean("ldapUDS");
|
||||||
|
UserDetails ben = uds.loadUserByUsername("ben");
|
||||||
|
assertTrue(ben instanceof InetOrgPerson);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private void setContext(String context) {
|
private void setContext(String context) {
|
||||||
appCtx = new InMemoryXmlApplicationContext(context);
|
appCtx = new InMemoryXmlApplicationContext(context);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user