reactjsspring-bootauthenticationldapreact-spring

Unable to use axios with password in React to authenticate to spring with external LDAP server(403 Error)


I am using external LDAP with spring as Backend and react as Frontend.

My Spring configuration for LDAP was:

    @Autowired
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
//https://stackoverflow.com/questions/45867724/how-to-connect-with-an-external-online-ldap-server-using-spring-boot
        auth
            .ldapAuthentication()
            .userSearchFilter("(uid={0})")
            .userSearchBase("dc=example,dc=com")
            .groupSearchBase("ou=mathematicians,dc=example,dc=com")
            .groupSearchFilter("cn={0}")
            .contextSource()
            .url("ldap://127.0.0.1:3890")
            .port(3890)
            .managerDn("cn=admin,ou=people,dc=example,dc=com")
            .managerPassword("password");
    }

My Security Config was as below:

@Configuration
@EnableWebSecurity
@Order(1)
public class SecurityConfig {
    private String url = "ldap://127.0.0.1:3890";
    private String domain = "127.0.0.1";
    private String userDNPattern = "cn=abc,ou=people,dc=example,dc=com";

    @Value("${app.http.auth-token-header-name}")
    private String principalRequestHeader;
    @Value("${app.http.auth-token}")
    private String principalRequestValue;

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {

        ApiKeyAuthFilter filter = new ApiKeyAuthFilter(principalRequestHeader);
        filter.setAuthenticationManager(new AuthenticationManager() {

            @Override
            public Authentication authenticate(Authentication authentication) throws AuthenticationException {
                String principal = (String) authentication.getPrincipal();
                if (!principalRequestValue.equals(principal)) {
                    throw new BadCredentialsException("The API key was not found or not the expected value.");
                }
                authentication.setAuthenticated(true);
                return authentication;
            }
        });





//        http
//                .authorizeRequests()
//                .anyRequest().authenticated()
//                .and()
//                .formLogin(withDefaults());
//        return http.build();

        http
                .authorizeHttpRequests(authorize -> authorize
                    .requestMatchers(HttpMethod.GET, "/api/user/test").authenticated()
                    .anyRequest().permitAll())
                    .httpBasic(Customizer.withDefaults());
        return http.build();
    }

i was ok to use APIKEY to Authenticate with below setting in spring: in app property

app.http.auth-token-header-name=X-API-KEY
app.http.auth-token=1234567890

@Value("${app.http.auth-token-header-name}")
private String principalRequestHeader;
@Value("${app.http.auth-token}")
private String principalRequestValue;

http
    .csrf(AbstractHttpConfigurer::disable)
    .authorizeHttpRequests(authCustomizer -> authCustomizer
    .requestMatchers(HttpMethod.GET, "/api/race").permitAll()
    .requestMatchers(HttpMethod.GET, "/api/user").permitAll()
    .requestMatchers(HttpMethod.GET, "/api/race/all").authenticated()
    .anyRequest().permitAll()
    //                        .requestMatchers("/api/**").authenticated()
        );
http.addFilter(filter);
return http.build();

And in react :

 const [data, setData] = useState([]);
    const apiheader = {
        'X-API-KEY': "1234567890"
              }
    useEffect(() => {
        axios.get(`${apiurl}/race/all`,
        {
            headers: apiheader,
        }
        ).then(function(response) {   
            setData(response.data);
        }).catch(function(error) {
            console.log(error);
        });
}, [])

and for using form login to compare with LDAP sever:

 http
            .authorizeRequests()
            .anyRequest().authenticated()
            .and()
            .formLogin(withDefaults());
    return http.build();

Both using API and default form was able to authenciate ,however when using password i was GETTING 403 back:

My Spring config was :

http
                .authorizeHttpRequests(authorize -> authorize
                    .requestMatchers(HttpMethod.GET, "/api/user/test").authenticated()
                    .anyRequest().permitAll())
                    .httpBasic(Customizer.withDefaults());
        return http.build();

and react side: from How to send Basic Auth with axios

 const [data, setData] = useState([]);
    useEffect(() => {
        axios.post(`${apiurl}/user/test`,{},
        {
            auth :             {
                username: "abc",
                password: "12345678",
            },    
        }
        ).then(function(response) {
            setData(response.data);
            console.log(data)
        }).catch(function(error) {
            console.log(error);
        });
    }, [])

I will be appreciate if someone can pinpoint my problem , thanks


Solution

  • I found my answer here Basic Authentication

    the basic setting for a html page to set user/password is :

        http
                .csrf(csrf -> csrf.disable())
                .authorizeHttpRequests(authorize -> authorize
                .requestMatchers(HttpMethod.GET, "/api/race/all").authenticated()
                .anyRequest().permitAll())
                .httpBasic(withDefaults());
        return http.build();
    

    in above , only one page is setted to need to use password and other wont need to authenticate

    and most important thing is to set the logging level in app property => logging.level.org.springframework.security=TRACE