How to connect with an external/online LDAP server using Spring Boot? - spring-boot

I am trying to integrate LDAP based login in my Spring Boot application.
As initial step, I am trying to use this LDAP server (http://www.forumsys.com/tutorials/integration-how-to/ldap/online-ldap-test-server/).
But, I am unable to successfully connect with the server and getting this error.
nested exception is javax.naming.AuthenticationException: [LDAP: error code 49 - Invalid Credentials]
I am using this information in configuration class.
authenticationManagerBuilder.ldapAuthentication()
.contextSource().url("ldap://ldap.forumsys.com:389/dc=example,dc=com")
.managerDn("cn=read-only-admin,dc=example,dc=com").managerPassword("password")
.and()
.userSearchBase("ou=mathematicians")
.groupSearchBase("ou=mathematicians")
.userSearchFilter("(cn={0})");
And this is my application.properties file for this project.
spring.ldap.urls=ldap.forumsys.com:389
spring.ldap.base=cn=read-only-admin,dc=example,dc=com
spring.ldap.password=password
Can anyone provide a working configuration for a Spring Boot application using an LDAP server?

As I was getting this error code from LDAP server.
LDAP: error code 49 - Invalid Credentials
The issue was with information that I was sending to LDAP server for opening a communication channel. So when I changed my request to a different object it started to working.
Here is the correct reqeust that we need to send from Spring to LDAP server.
authenticationManagerBuilder
.ldapAuthentication()
.userDetailsContextMapper(inetOrgPersonContextMapper())
.userSearchFilter("(uid={0})")
.userSearchBase("dc=example,dc=com")
.groupSearchBase("ou=mathematicians,dc=example,dc=com")
.groupSearchFilter("cn={0}")
.contextSource()
.url("ldap://ldap.forumsys.com")
.port(389)
.managerDn("cn=read-only-admin,dc=example,dc=com")
.managerPassword("password");

This is the correct configuration:
authenticationManagerBuilder
.ldapAuthentication()
.userSearchFilter("(uid={0})")
.userSearchBase("dc=example,dc=com")
.groupSearchFilter("uniqueMember={0}")
.groupSearchBase("ou=mathematicians,dc=example,dc=com")
.userDnPatterns("uid={0}")
.contextSource()
.url("ldap://ldap.forumsys.com:389")
.managerDn("cn=read-only-admin,dc=example,dc=com")
.managerPassword("password");

Use below application property.
ldap.enabled = true
####### LDAP TEST##############
ldap.urls= ldap://ldap.forumsys.com:389/
ldap.base.dn= dc=example,dc=com
ldap.username= cn=read-only-admin,dc=example,dc=com
ldap.password= password
ldap.user.dn.pattern = uid={0}

Related

Spring Boot LDAP - Eror code 80 when trying to auth users

I am trying to auth users through secured adlds server from a spring boot application, and I am facing an issue for 2 weeks now, and no solutions found in the internet worked for me.
First I had an error that says that I need to bind the authentication before successful operation. I added the right properties to the context source but now I am getting an error code 80 which gives me no clues on the error.
Here is my code:
Application.yml
spring:
ldap:
url: ldaps://<hostname>:636
base: DC=<dc>>,DC=<dc>
username: CN=<cn>>,OU=Privileged,OU=<ou>,OU=<ou>,OU=<ou>,DC=<dc>,DC=<dc>
password: <secret>
base-environment:
com.sun.jndi.ldap.connect.timeout: 500
management:
health:
ldap:
enabled: false
Configuration.java
#Bean
#DependsOn("frameworkInstance")
public LdapContextSource contextSource() {
LdapContextSource contextSource = new LdapContextSource();
contextSource.setUrl("ldaps://<hostname>:636");
contextSource.setBase("<base>");
contextSource.setUserDn("CN=<cn>,OU=<ou>>,OU=<ou>>,OU=<ou>>,OU=<ou>,DC=<dc>,DC=<dc>>");
contextSource.setPassword("<secret>");
contextSource.afterPropertiesSet();
return contextSource;
}
#Bean
#DependsOn("frameworkInstance")
public LdapTemplate ldapTemplate() {
return new LdapTemplate(contextSource());
}
My auth process :
Filter filter = new EqualsFilter("cn", "<cn>");
ldapTemplate.authenticate(LdapUtils.emptyLdapName(), filter.encode(), "<secret>");
The error code is :
Uncategorized exception occured during LDAP processing; nested exception is javax.naming.NamingException: [LDAP: error code 80 - 80090304: LdapErr: DSID-0C090447, comment: AcceptSecurityContext error, data 20ee, v3839\u0000]
I tried everything for a couple of days but nothing ... The account used for the "bind" and for the authentication is the same, to ensure that the auth will be succesfull. Keep in mind that the words between chevrons are hidden because of production environment, I am not allowed to display credentials, etc.
Do you have please any clues to resolve that issue ? it's very critical
Best regards,
In the error message, the data 20ee indicates the Windows System Error Code. According to the Microsoft documentation, that is:
ERROR_DS_INTERNAL_FAILURE
8430 (0x20EE)
The directory service encountered an internal failure.
I don't think that indicates any problem with your code. It sounds more like a problem with your Active Directory environment.
Have you tried connecting via regular LDAP rather than LDAPS? (ldap://<hostname>). If that works, then it would indicate a problem with the LDAPS configuration.
As a side note, if you indicate ldaps:// in the path, you don't need to include :636, since that is the default LDAPS port.

Spring Boot Security and Keycloak - receive 403 forbidden /sso/login after successfull login when using HTTPS

I have a Spring Boot App using Spring Security and Keycloak as IDP.
Keycloak is available under https://auth.example.com, having a realm backo with a client backo-core and a testuser configured with the required roles.
If I configure my local app, using
keycloak.enabled=true
keycloak.auth-server-url=https://auth.example.com/auth
keycloak.realm=backo
keycloak.public-client=true
keycloak.resource=backo-core
keycloak.ssl-required=external
keycloak.confidential-port=443
Everything works fine.
If I deploy it to my DEV environment under https://backo.example.com/backo with https://backo.example.com/sso/login, when accessing the app I get redirect to the Keycloak login. After successful login I get redirected to the redirect URL with the state, session-state and code parameters but receive 403.
https://backo.example.com/sso/login?state=...&session_state=...&code=...
with request initiator chain coming from https://auth.example.com/auth/realms/backo/login-action/authenticate?...
If I set locally keycloak.ssl-required=all, the redirect_url parameter when accessing the login page is https://localhost/sso/login, so I can change it manually to http://localhost:8080/sso/login. After a successful login I have the exact same problem with a 403 Forbidden response for
http://localhost:8080/sso/login?state=...&session_state=...&code=...
with request initiator chain coming from https://auth.example.com/auth/realms/backo/login-action/authenticate?...
This is how my security config looks like
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http
.authorizeRequests()
.antMatchers("/backo").hasAnyRole(ROLE_ADMIN, ROLE_BACKOFFICE)
.anyRequest().permitAll();
http.csrf().disable();
http.headers().frameOptions().disable(); // otherwise Vaadin doesn't work properly
http
.logout()
.addLogoutHandler(keycloakLogoutHandler())
.logoutUrl("/sso/logout").permitAll()
.logoutSuccessUrl("/");
}
You can ignore this Vaadin workaround, as it fails in /sso/login already.
http.csrf().disable(); is required to prevent other 403 Forbidden errors on post request while authorization.
One thing that could be worth mentioning:
The Spring Boot App has no HTTPS enabled, in our dev environment it sits behind an AWS Application loadbalancer ALB. HTTPS is terminated in the ALB.
We have faced the similar problem three days ago with spring boot thymeleaf application. We have used keycloak adapter (13.0.1) for spring boot.
After successful login it was redirecting to /sso/login page with 403 error.
After lots of effort we finally got the configuration required to fix this issue. you need to use the below application properties :
server.use-forward-headers=true
keycloak.public-client=true
keycloak.ssl-required=all
keycloak.confidential-port=443

heroku app asks for sign in without me enabling it

I am making a spring application deployed on Heroku. However when I go to the url (.herokuapp.com) I get asked to provide my username and password, even when I didnt put that in my code anywhere. I tried to add the following to my code:
#Override
protected void configure(HttpSecurity security) throws Exception {
security
.httpBasic().disable()
.formLogin().disable();
}
however when I make a request using postman I now get a 403 forbidden error.
Any ideas? Thanks in advance.
You must have added Spring security in your project and as soon as you include spring security in your application it automatically protects your whole application, so in order to access the pages without login you need to configure it, you can use AntMatcher("/endpoint").permitAll();
something like this to configure it and the default username is user and password is generated at the start of the application.
You should probably go through the basics of spring security in order to understand it properly. Follow this video spring security to get ht e insight.

Configuring spring-boot-starter-oauth2-client to authenticate with Azure AD

I want to add Azure AD as an OAuth2 provider in Spring Boot 2.4. I followed Spring Boot's OAuth2 docs and came up with the following configuration:
spring.security.oauth2.client.provider.azuread.issuer-uri=https://login.microsoftonline.com/<tenant uuid>/v2.0
spring.security.oauth2.client.registration.azuread.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.azuread.client-id=<client uuid>
spring.security.oauth2.client.registration.azuread.client-name=Azure AD
spring.security.oauth2.client.registration.azuread.client-secret=<client secret>
spring.security.oauth2.client.registration.azuread.provider=azuread
spring.security.oauth2.client.registration.azuread.scope=openid
Just for completeness, this is my web security configuration:
#EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
// #formatter:off
http
.authorizeRequests(a -> a
.antMatchers("/", "/login", "/error", "/webjars/**").permitAll()
.anyRequest().authenticated()
)
.oauth2Login();
// #formatter:on
}
}
When coming back from entering the credentials on https://login.microsoftonline.com, I get the following error:
[invalid_id_token] An error occurred while attempting to decode the Jwt: Signed JWT rejected: Another algorithm expected, or no matching key(s) found.
The problem originates in DefaultJWTProcessor.java from Nimus-JOSE-JWT.
Looking through the requests in Firefox's network inspector, Spring Boot picks up the right URLs from the Issuer URI. I'm at a loss what's going wrong and appreciate any pointers.
Azure AD has some pretty unintuitive (in my opinion) default behaviour - I think this is what you are experiencing:
YOUR PROBLEM CAUSE (I THINK)
You are using standard OpenID Connect scopes
This causes Azure AD to issue an access token intended for the Graph API
This token fails standards based validation in Custom APIs since it is only designed for Graph APIs to use - it is recognisable by the nonce field in the JWT header
WHAT YOU NEED TO DO
Expose an API scope such as 'default'
Use the full value of this scope in your web client, with a value such as 'api://cb398b43-96e8-48e6-8e8e-b168d5816c0e/default', where the long identifier is that of the API
You will then get a normal OAuth token that Spring can validate - with no nonce field in the JWT header
FURTHER INFO
See steps 3 to 8 of my blog post from a couple of years ago
See the OpenID Connect settings of my web code sample
I had a similar problem and if I remember correctly there was an issue with scope. Don't know whether this is also your issue but in any case following configuration is working for me (note I'm using client credentials not auth code):
spring:
security:
oauth2:
client:
provider:
azure:
token-uri: https://login.microsoftonline.com/${custom.azure.account.tenant-id}/oauth2/token
registration:
azure:
client-id: ${custom.azure.service-principal.client-id}
client-secret: ${custom.azure.service-principal.client-secret}
authorization-grant-type: client_credentials
scope:
- https://graph.microsoft.com/.default
According to your description, it seems that you wanna use azure ad as the an OAuth2 provider in Spring Boot, and I found a doc said that 'Spring Starter for Azure Active Directory (AD) is now integrated with Spring Security 5.0'. It also offered a sample of springboot web app. I also tried it and it did work.
What I think need to note is, the tutorial said the redirect url setted in azure ad is 'http://localhost:8080/login/oauth2/code/', but when my tested, it proved to be 'http://localhost:8080/login/oauth2/code/azure'.
Upon your error, I'm not sure but maybe you can change your configuration of 'scope' to 'openid,profile,offline_access'.

Connect secured Client with Spring Boot Admin Security

Can someone guide me how can I connect my secured client with the spring boot admin application?
Scenario: I have a spring boot application (client) with spring security and spring-actuator enabled. The actuator endpoints are secured and for this I have the following (working) configuration in my web security config:
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth, UserDetailsService userDetailsService) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
auth.inMemoryAuthentication().withUser("Test-Actuator").password("Test-Baby").roles("ADMIN", "ACTUATOR");
}
Now I want to integrate the Spring Boot Admin Application in our environment. I set up a simple application with spring-boot-admin-server and spring-boot-admin-server-ui enabled. In the application.properties file I provide the following properties:
spring.boot.admin.username=test
spring.boot.admin.password=test
these are for the server admin, right?
spring.boot.admin.client.metadata.user.name=Test-Actuator
spring.boot.admin.client.metadata.user.password=Test-Baby
these are for the client, right?
Now when I run the applications I get the following error from the client: Failed to register application as Application [...] at spring-boot-admin ([...]) 401 null
I call the spring boot admin page and get a HttpBasic Authentication Pop Up. No credentials from above work for this Pop Up.
Note: If I disable the security in the client application.properties file it works but (like expected) the client doesn't work anymore.

Resources