Use LDAP AuthenticationManager factory in reference docs

Closes gh-10789
This commit is contained in:
Eleftheria Stein 2022-01-28 17:03:56 +01:00
parent 9baf1134c7
commit d5824521e8
1 changed files with 109 additions and 85 deletions

View File

@ -118,7 +118,8 @@ depenendencies {
---- ----
==== ====
You can then configure the Embedded LDAP Server You can then configure the Embedded LDAP Server using an `EmbeddedLdapServerContextSourceFactoryBean`.
This will instruct Spring Security to start an in-memory LDAP server.
.Embedded LDAP Server Configuration .Embedded LDAP Server Configuration
==== ====
@ -126,6 +127,30 @@ You can then configure the Embedded LDAP Server
[source,java,role="primary"] [source,java,role="primary"]
---- ----
@Bean @Bean
public EmbeddedLdapServerContextSourceFactoryBean contextSourceFactoryBean() {
return EmbeddedLdapServerContextSourceFactoryBean.fromEmbeddedLdapServer();
}
----
.Kotlin
[source,kotlin,role="secondary"]
----
@Bean
fun contextSourceFactoryBean(): EmbeddedLdapServerContextSourceFactoryBean {
return EmbeddedLdapServerContextSourceFactoryBean.fromEmbeddedLdapServer()
}
----
====
Alternatively, you can manually configure the Embedded LDAP Server.
If you choose this approach, you will be responsible for managing the lifecycle of the Embedded LDAP Server.
.Explicit Embedded LDAP Server Configuration
====
.Java
[source,java,role="primary"]
----
@Bean
UnboundIdContainer ldapContainer() { UnboundIdContainer ldapContainer() {
return new UnboundIdContainer("dc=springframework,dc=org", return new UnboundIdContainer("dc=springframework,dc=org",
"classpath:users.ldif"); "classpath:users.ldif");
@ -228,6 +253,35 @@ fun ldapContainer(): ApacheDSContainer {
Once you have an LDAP Server to point your configuration to, you need configure Spring Security to point to an LDAP server that should be used to authenticate users. Once you have an LDAP Server to point your configuration to, you need configure Spring Security to point to an LDAP server that should be used to authenticate users.
This is done by creating an LDAP `ContextSource`, which is the equivalent of a JDBC `DataSource`. This is done by creating an LDAP `ContextSource`, which is the equivalent of a JDBC `DataSource`.
If you have already configured an `EmbeddedLdapServerContextSourceFactoryBean`, Spring Security will create an LDAP `ContextSource` that points to the embedded LDAP server.
.LDAP Context Source with Embedded LDAP Server
====
.Java
[source,java,role="primary"]
----
@Bean
public EmbeddedLdapServerContextSourceFactoryBean contextSourceFactoryBean() {
EmbeddedLdapServerContextSourceFactoryBean contextSourceFactoryBean =
EmbeddedLdapServerContextSourceFactoryBean.fromEmbeddedLdapServer();
contextSourceFactoryBean.setPort(0);
return contextSourceFactoryBean;
}
----
.Kotlin
[source,kotlin,role="secondary"]
----
@Bean
fun contextSourceFactoryBean(): EmbeddedLdapServerContextSourceFactoryBean {
val contextSourceFactoryBean = EmbeddedLdapServerContextSourceFactoryBean.fromEmbeddedLdapServer()
contextSourceFactoryBean.setPort(0)
return contextSourceFactoryBean
}
----
====
Alternatively, you can explicitly configure the LDAP `ContextSource` to connect to the supplied LDAP server.
.LDAP Context Source .LDAP Context Source
==== ====
@ -287,15 +341,10 @@ An example of bind authentication configuration can be found below.
[source,java,role="primary",attrs="-attributes"] [source,java,role="primary",attrs="-attributes"]
---- ----
@Bean @Bean
BindAuthenticator authenticator(BaseLdapPathContextSource contextSource) { AuthenticationManager authenticationManager(BaseLdapPathContextSource contextSource) {
BindAuthenticator authenticator = new BindAuthenticator(contextSource); LdapBindAuthenticationManagerFactory factory = new LdapBindAuthenticationManagerFactory(contextSource);
authenticator.setUserDnPatterns(new String[] { "uid={0},ou=people" }); factory.setUserDnPatterns("uid={0},ou=people");
return authenticator; return factory.createAuthenticationManager();
}
@Bean
LdapAuthenticationProvider authenticationProvider(LdapAuthenticator authenticator) {
return new LdapAuthenticationProvider(authenticator);
} }
---- ----
@ -310,15 +359,10 @@ LdapAuthenticationProvider authenticationProvider(LdapAuthenticator authenticato
[source,kotlin,role="secondary",attrs="-attributes"] [source,kotlin,role="secondary",attrs="-attributes"]
---- ----
@Bean @Bean
fun authenticator(contextSource: BaseLdapPathContextSource): BindAuthenticator { fun authenticationManager(contextSource: BaseLdapPathContextSource): AuthenticationManager {
val authenticator = BindAuthenticator(contextSource) val factory = LdapBindAuthenticationManagerFactory(contextSource)
authenticator.setUserDnPatterns(arrayOf("uid={0},ou=people")) factory.setUserDnPatterns("uid={0},ou=people")
return authenticator return factory.createAuthenticationManager()
}
@Bean
fun authenticationProvider(authenticator: LdapAuthenticator): LdapAuthenticationProvider {
return LdapAuthenticationProvider(authenticator)
} }
---- ----
==== ====
@ -333,19 +377,11 @@ If instead you wished to configure an LDAP search filter to locate the user, you
[source,java,role="primary",attrs="-attributes"] [source,java,role="primary",attrs="-attributes"]
---- ----
@Bean @Bean
BindAuthenticator authenticator(BaseLdapPathContextSource contextSource) { AuthenticationManager authenticationManager(BaseLdapPathContextSource contextSource) {
String searchBase = "ou=people"; LdapBindAuthenticationManagerFactory factory = new LdapBindAuthenticationManagerFactory(contextSource);
String filter = "(uid={0})"; factory.setUserSearchFilter("(uid={0})");
FilterBasedLdapUserSearch search = factory.setUserSearchBase("ou=people");
new FilterBasedLdapUserSearch(searchBase, filter, contextSource); return factory.createAuthenticationManager();
BindAuthenticator authenticator = new BindAuthenticator(contextSource);
authenticator.setUserSearch(search);
return authenticator;
}
@Bean
LdapAuthenticationProvider authenticationProvider(LdapAuthenticator authenticator) {
return new LdapAuthenticationProvider(authenticator);
} }
---- ----
@ -361,18 +397,11 @@ LdapAuthenticationProvider authenticationProvider(LdapAuthenticator authenticato
[source,kotlin,role="secondary",attrs="-attributes"] [source,kotlin,role="secondary",attrs="-attributes"]
---- ----
@Bean @Bean
fun authenticator(contextSource: BaseLdapPathContextSource): BindAuthenticator { fun authenticationManager(contextSource: BaseLdapPathContextSource): AuthenticationManager {
val searchBase = "ou=people" val factory = LdapBindAuthenticationManagerFactory(contextSource)
val filter = "(uid={0})" factory.setUserSearchFilter("(uid={0})")
val search = FilterBasedLdapUserSearch(searchBase, filter, contextSource) factory.setUserSearchBase("ou=people")
val authenticator = BindAuthenticator(contextSource) return factory.createAuthenticationManager()
authenticator.setUserSearch(search)
return authenticator
}
@Bean
fun authenticationProvider(authenticator: LdapAuthenticator): LdapAuthenticationProvider {
return LdapAuthenticationProvider(authenticator)
} }
---- ----
==== ====
@ -394,13 +423,11 @@ An LDAP compare cannot be done when the password is properly hashed with a rando
[source,java,role="primary"] [source,java,role="primary"]
---- ----
@Bean @Bean
PasswordComparisonAuthenticator authenticator(BaseLdapPathContextSource contextSource) { AuthenticationManager authenticationManager(BaseLdapPathContextSource contextSource) {
return new PasswordComparisonAuthenticator(contextSource); LdapPasswordComparisonAuthenticationManagerFactory factory = new LdapPasswordComparisonAuthenticationManagerFactory(
} contextSource, NoOpPasswordEncoder.getInstance());
factory.setUserDnPatterns("uid={0},ou=people");
@Bean return factory.createAuthenticationManager();
LdapAuthenticationProvider authenticationProvider(LdapAuthenticator authenticator) {
return new LdapAuthenticationProvider(authenticator);
} }
---- ----
@ -417,13 +444,12 @@ LdapAuthenticationProvider authenticationProvider(LdapAuthenticator authenticato
[source,kotlin,role="secondary"] [source,kotlin,role="secondary"]
---- ----
@Bean @Bean
fun authenticator(contextSource: BaseLdapPathContextSource): PasswordComparisonAuthenticator { fun authenticationManager(contextSource: BaseLdapPathContextSource?): AuthenticationManager? {
return PasswordComparisonAuthenticator(contextSource) val factory = LdapPasswordComparisonAuthenticationManagerFactory(
} contextSource, NoOpPasswordEncoder.getInstance()
)
@Bean factory.setUserDnPatterns("uid={0},ou=people")
fun authenticationProvider(authenticator: LdapAuthenticator): LdapAuthenticationProvider { return factory.createAuthenticationManager()
return LdapAuthenticationProvider(authenticator)
} }
---- ----
==== ====
@ -436,17 +462,12 @@ A more advanced configuration with some customizations can be found below.
[source,java,role="primary"] [source,java,role="primary"]
---- ----
@Bean @Bean
PasswordComparisonAuthenticator authenticator(BaseLdapPathContextSource contextSource) { AuthenticationManager authenticationManager(BaseLdapPathContextSource contextSource) {
PasswordComparisonAuthenticator authenticator = LdapPasswordComparisonAuthenticationManagerFactory factory = new LdapPasswordComparisonAuthenticationManagerFactory(
new PasswordComparisonAuthenticator(contextSource); contextSource, new BCryptPasswordEncoder());
authenticator.setPasswordAttributeName("pwd"); // <1> factory.setUserDnPatterns("uid={0},ou=people");
authenticator.setPasswordEncoder(new BCryptPasswordEncoder()); // <2> factory.setPasswordAttribute("pwd"); // <1>
return authenticator; return factory.createAuthenticationManager();
}
@Bean
LdapAuthenticationProvider authenticationProvider(LdapAuthenticator authenticator) {
return new LdapAuthenticationProvider(authenticator);
} }
---- ----
@ -467,23 +488,18 @@ LdapAuthenticationProvider authenticationProvider(LdapAuthenticator authenticato
[source,kotlin,role="secondary"] [source,kotlin,role="secondary"]
---- ----
@Bean @Bean
fun authenticator(contextSource: BaseLdapPathContextSource): PasswordComparisonAuthenticator { fun authenticationManager(contextSource: BaseLdapPathContextSource): AuthenticationManager {
val authenticator = PasswordComparisonAuthenticator(contextSource) val factory = LdapPasswordComparisonAuthenticationManagerFactory(
authenticator.setPasswordAttributeName("pwd") // <1> contextSource, BCryptPasswordEncoder()
authenticator.setPasswordEncoder(BCryptPasswordEncoder()) // <2> )
return authenticator factory.setUserDnPatterns("uid={0},ou=people")
} factory.setPasswordAttribute("pwd") // <1>
return factory.createAuthenticationManager()
@Bean
fun authenticationProvider(authenticator: LdapAuthenticator): LdapAuthenticationProvider {
return LdapAuthenticationProvider(authenticator)
} }
---- ----
==== ====
<1> Specify the password attribute as `pwd` <1> Specify the password attribute as `pwd`
<2> Use `BCryptPasswordEncoder`
== LdapAuthoritiesPopulator == LdapAuthoritiesPopulator
@ -504,8 +520,11 @@ LdapAuthoritiesPopulator authorities(BaseLdapPathContextSource contextSource) {
} }
@Bean @Bean
LdapAuthenticationProvider authenticationProvider(LdapAuthenticator authenticator, LdapAuthoritiesPopulator authorities) { AuthenticationManager authenticationManager(BaseLdapPathContextSource contextSource, LdapAuthoritiesPopulator authorities) {
return new LdapAuthenticationProvider(authenticator, authorities); LdapBindAuthenticationManagerFactory factory = new LdapBindAuthenticationManagerFactory(contextSource);
factory.setUserDnPatterns("uid={0},ou=people");
factory.setLdapAuthoritiesPopulator(authorities);
return factory.createAuthenticationManager();
} }
---- ----
@ -529,8 +548,13 @@ fun authorities(contextSource: BaseLdapPathContextSource): LdapAuthoritiesPopula
} }
@Bean @Bean
fun authenticationProvider(authenticator: LdapAuthenticator, authorities: LdapAuthoritiesPopulator): LdapAuthenticationProvider { fun authenticationManager(
return LdapAuthenticationProvider(authenticator, authorities) contextSource: BaseLdapPathContextSource,
authorities: LdapAuthoritiesPopulator): AuthenticationManager {
val factory = LdapBindAuthenticationManagerFactory(contextSource)
factory.setUserDnPatterns("uid={0},ou=people")
factory.setLdapAuthoritiesPopulator(authorities)
return factory.createAuthenticationManager()
} }
---- ----
==== ====