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
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