spring-projects / spring-boot

Spring Boot helps you to create Spring-powered, production-grade applications and services with absolute minimum fuss.
https://spring.io/projects/spring-boot
Apache License 2.0
75.19k stars 40.69k forks source link

Auto-configure an ActiveDirectoryLdapAuthenticationProvider from configuration properties #7929

Open bbrouwer opened 7 years ago

bbrouwer commented 7 years ago

We could configure a good chunk of Spring security for LDAP (probably other places too) simply with application.properties:

security.ldap.url=ldaps://example.com
security.ldap.user-dn-pattern=uid={0},ou=Users,o=example
security.ldap.group-dn=ou=example,ou=Roles,o=example
security.ldap.group-search-base=(uniqueMember={0})
security.ldap.auth.user-dn=uid=exampleAuthUser,ou=Users,o=example
security.ldap.auth.password=somePassword

I have code that I can contribute if there is interest.

shakuzen commented 7 years ago

@bbrouwer FYI, support for auto-configuring LDAP was recently added with Spring Boot 1.5 RC1. See the release notes and new documentation section for more details. Perhaps this covers (some of) what you had in mind already?

bbrouwer commented 7 years ago

That is pretty cool. I didn't know about that yet. My use case is specifically related to security, not a generic use that Spring Data LDAP gives me. Is Spring Security going to switch to use Spring Data LDAP? I didn't find anything specifically saying that, but it would make sense.

I could definitely see being able to write a custom UserDetails implementation that would use the Spring Data LDAP repositories to get the user details and roles that Spring Security needs, but I'm hoping for something that simply requires setting a few properties.

It looks like Spring Data LDAP provides a few of the properties I'm looking for:

spring.ldap.urls=ldap://myserver:1235
spring.ldap.username=admin
spring.ldap.password=secret

But that leaves the needing to specify the group-dn, group-search-base, user-dn-pattern, user-role-attribute, ...

wilkinsona commented 7 years ago

Thank you for the suggestion and the offer of a contribution.

We want to simplify our auto-configuration for Spring Security in Boot 2.0 and, unfortunately, this feels like a step in the wrong direction. I think we'd end up with an auto-configured WebSecurityConfigurerAdapter that kicked in when some spring.security.ldap properties were set.

We'd prefer that people use Spring Security's Java DSL to set this up rather than us trying to recreate that DSL in configuration properties.

ffroliva commented 9 months ago

@jzheaux suggested I should open an issue here, for spring-boot team, instead of in spring security project.

I feel here is the right submit my request and perhaps this thread can be reopen. Please let me know if you want to submit my request in a different (separate) issue.


I am currently working to integrate ActiveDirectoryLdapAuthenticationProvider with SecurityFilterChain.

To configure ActiveDirectoryLdapAuthenticationProvider I need to provide the following properties (or a combination of them).

        private final String domain;

    private final String rootDn;

    private final String url;

    private String searchFilter = "(&(objectClass=user)(userPrincipalName={0}))";

Currenty, there is no spring configuration properties that would allow me to externalize the configuration from application.properties or application.yml. I have to create a custom bean for that purpose.

Spring provides LdapProperties for ldap configuration.

My suggestion would be to take similar approach. An initial suggestion for the list of properties would be:

package org.springframework.security.ldap.authentication.ad;

import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

@Getter
@Setter
@Configuration
@ConfigurationProperties(prefix = "spring.security.ldap.active-directory")
public class LdapSecurityProperties {
    String domain;
    String url;
    String rootDn;
    String searchFilter;
}

Then in application.properties we would have:

spring.security.ldap.activeDirectory.url=ldap://localhost:389
spring.security.ldap.activeDirectory.domain=
spring.security.ldap.activeDirectory.rootDn=dc=example,dc=com
spring.security.ldap.activeDirectory.searchFilter=(sAMAccountName={0})

My current approach to configuring AD authentication provider looks this:

    @Bean
    public AuthenticationProvider activeDirectoryLdapAuthenticationProvider(LdapSecurityProperties ldapProperties) {
        ActiveDirectoryLdapAuthenticationProvider provider =
                new ActiveDirectoryLdapAuthenticationProvider(
                        ldapProperties.getDomain(),
                        ldapProperties.getUrl(),
                        ldapProperties.getRootDn());

        // to parse AD failed credentials error message due to account - expiry,lock | credentials - expiry,lock
        provider.setConvertSubErrorCodesToExceptions(true);
        provider.setUseAuthenticationRequestCredentials(true);
        provider.setSearchFilter(ldapProperties.getSearchFilter());
        return provider;
    }
philwebb commented 9 months ago

Thanks for the suggestion @ffroliva, we'll re-open this one to see what we can do.