-
Notifications
You must be signed in to change notification settings - Fork 239
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
para LDAP config is not picked up correctly #67
Comments
Are you mounting the config file with The workaround you describe is setting LDAP configuration for the root app in Para, called "app:para". |
yes, i have separated application.conf for both scoold and para docker-compose.yml
scoolid-application.conf
para-application.conf
|
By creating a new app I meant calling |
@albogdano after I create new-app called app:scoold and use it. now the LDAP is not working anymore. Even though I put LDAP config in both application.conf (for scoold and para). It try to connect to localhost:8389 |
@albogdano hey, i found out the problem now. when I ran the docker-compose, the scoold is starting but the para is not ready yet. And later scoold is trying to connect para again but this time the setting is not loaded correctly. my workaround is to restart the scoold container again and it is working as expected. Later I can set TIMEOUT in the Dockerfile. |
Edit |
@ensecoz Could you please share your ldap configurations which worked ? I am trying with my settings it doesn't work. |
|
I don't have a working LDAP config for AD. Just remove most of the
properties and only keep the URL and search filter properties.
…On Mon, 11 Jun 2018, 06:31 ensecoz, ***@***.***> wrote:
- ensecoz.local is my domain
- serviceUser is service user who has permission to query the AD
- my setting is for AD so I have to put active_directory_domain
- user_dn_pattern -> i think you can ignore this. I try to change this
but nothing happen
para.security.ldap.server_url = "ldap://ensecoz.local:8389/"
para.security.ldap.base_dn = "DC=ensecoz,DC=local"
para.security.ldap.bind_dn = "CN=serviceUser,OU=Service Accounts,OU=Resources,DC=ensecoz,DC=local"
para.security.ldap.bind_pass = "xxxxyyyyzzzz"
para.security.ldap.user_search_base = "OU=Offices,DC=ensecoz,DC=local"
para.security.ldap.user_search_filter = "(&(objectClass=user)(sAMAccountName={1}))"
para.security.ldap.user_dn_pattern = "mail={0}"
para.security.ldap.password_attribute = ""
# set this only if you are connecting to Active Directory
para.security.ldap.active_directory_domain = "ensecoz.local"
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#67 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAVK-Vmae90Ygv_P1ceo_KfKnkMUqG-Oks5t7eSmgaJpZM4UaXwI>
.
|
I spent basically the whole day trying to make this work, because I didn't think to be watching the LDAP logs, but here's the config that works for me:
|
NOTE: Based on observing the logs in my OpenLDAP instance, I don't believe the |
Also, I should not that these settings should be specified on the Scoold config, not the para config |
@weisjohn I too was initially having trouble binding to an LDAP server that didn't allow unauthenticated requests. I recreated the issue by spun up OpenDJ locally, had it create 2000 dummy users, and disable anonymous binds (special thanks to Mark Craig]:
This helped me recreate the issue locally, and by playing around with the LDAP config, I was able to get Scoold to bind and authenticate to LDAP just fine. +1 in that the LDAP settings should be specified in Scoold config and not Para config too. |
@weisjohn @albogdano I'm also seeing an issue where bind_dn and bind_pass are not being picked up. The configs are set in both scoold and para. I verified this by using para-cli and checking the app-settings; if necessary I used the /v1/_settings endpoint to set the configs manually. (I seemed to had to do this for the root app (app:para) When I try to login to Scoold or hit Para's ldap_auth handler directly Para is trying to bind with the user/pass I'm trying to login as, not the bind_dn or bind_pass. |
@tongueisthirsty configuration for the root app is loaded from This is the reason why I don't recommend using the root app for Scoold because it uses |
@albogdano I really appreciate the quick response and the extra clarity. Knowing that Im going to change some things around and run some more tests. However, I'd like to point out that I've been running PUTs against /v1/settings using the app:para signature and modifying the settings there - and then seeing those changes take place in my network caps (i'm using network caps to see how the requests are being built and sent to my ldap server so I can more intelligently make config changes). |
@albogdano I'm still seeing the same issue. Whatever ID I'm trying to login with is the ID used in the initial bind request - I would expect the bind_dn to be used here, but maybe I'm misunderstanding. When I try to log in via the Scoold UI I see two bindrequests: Here is an example config I have in both the para applications.conf and the scoold applications.conf: para.security.ldap.bind_dn = "uid=scooldBindID,ou=United States,ou=Bind IDs,o=Org One" Can you clarify the /ldap_auth?username=un&password=pw handler? Is 'un' and 'pw' supposed to be the BIND ID/PW? Or the ID of the login object? |
@tongueisthirsty The username and password in I recommend that you have a separate app for Scoold only and you put the LDAP configuration settings inside Here's an example working config for the ForumSys LDAP test server:
|
Gotcha @albogdano. I have a separate app for Scoold already (app:scoold) but I've been putting the configurations in both Scoold and Para. I'll make the appropriate changes and review the example you provided. Thank you. |
@tongueisthirsty Basically each time you edit |
@albogdano Do you have a suggestion on how I can configure Scoold so LDAP BINDS are only done via the ID? eg. no dn, no dc=springframework,dc=org, no uid={0},ou=people, no (cn={0}). All I need passed to my LDAP server is the ID being logged in with however there doesn't appear to be a set of configurations to do that. |
@tongueisthirsty Have you tried leaving those properties blank, i.e. |
@albogdano I apologize for being MIA for a couple days. I have tried that. That is when I start getting <ROOT> showing up in the network trace. I'm going to dig more into that as well as other ways to BIND (eg. full DN). |
I'm having a hard time configuring scoold for AD auth using the UPN. This one works for me:
As you probably guessed, this lets you in with
None of them works. I'm afraid the For the record, here's everything LDAP-related:
|
I'm not sure if I can help here. All LDAP settings are passes to Spring
LDAP directly and should work for all LDAP servers. The problem is probably
related to a misconfiguration of some other LDAP property.
…On Wed, 13 Feb 2019, 22:09 bviktor ***@***.*** wrote:
I'm having a hard time configuring scoold for AD auth using the UPN. This
one works for me:
para.security.ldap.user_search_filter = "(&(objectClass=user)(sAMAccountName={1}))"
As you probably guessed, this lets you in with user.name. But I want to
log in with the full email address. So I tried with
para.security.ldap.user_search_filter = "(&(objectClass=user)(userPrincipalName={0}))"
para.security.ldap.user_search_filter = "(&(objectClass=user)(userPrincipalName={1}))"
para.security.ldap.user_search_filter = "(&(objectClass=user)(mail={0}))"
para.security.ldap.user_search_filter = "(&(objectClass=user)(mail={1}))"
None of them works. I'm afraid the @ might not be escaped correctly
somehwere. Any ideas?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#67 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAVK-czxgdTlgz5bR71FQ3KOnIUg1YXjks5vNHDlgaJpZM4UaXwI>
.
|
We use LDAP auth happily with dozens of other services. No offense, but if I had to guess where the problem is, I think it's far more probable it's in Scoold/Para, and not in Spring. Yes, you "only" pass the parameters, and it's exactly the passing itself that always causes problems if escapes are not proper. But anyhow, I no longer think that improper escapes are the issue here. Here's some tests:
Case 4 doesn't even make any sense to me, since
What's "domain" anyway? Is this the AD domain from settings? Is this the UPN suffix of the AD object? Or the part after To me it seems there's at least 2 unjustified assumptions made in the code:
In our case, the domain name is In other words, UPN/mail and AD domain name usually have nothing in common. |
@bviktor I understand that you're having difficulties with the configuration but I'm not sure what I'm supposed to do about that. Have a look at line 57 in this source file ActiveDirectoryLdapAuthenticationProvider.java If your users try to login with |
Yes. Yours. Not AD's. And that's why authentication fails with correct credentials. Plus the bind DN is a completely different entity, yet you try to auth them both with the same logic. Also, the code "guesses" incorrectly, since it appends the AD domain even if the user enters an email address for login, but doesn't have a mail attribute. But does have a UPN. The list goes on. Neither do I know what else to say to you. I made it crystal clear what the problem is. Auth fails, not because the credentials are bad, but because bind and lookup have incorrect logic. I even explained what the issue with the logic is. Redmine, Jenkins, GitLab, Nexus, SVN, PostgreSQL, Cisco ASA, just to name a few. They all work correctly via LDAP, with the mail attribute, with a different domain than the AD domain. And Scoold doesn't. But according to you, the obvious conclusion to this is that our setup is bad, and Scoold is fine. Okay... You know, I would happily accept an answer like "I don't care". Seriously, that'd be way better, coz then at least I wouldn't have spent around 6 hours so far testing this app inside out to demonstrate how broken it is. All in vain. You keep saying everything's fine, even though it clearly isn't fine at all. It's broken. Have you ever tested it in the mentioned setup? If not, why do you insist the issue is in my setup, or in Spring (used by millions), or anywhere else but in the front- and backend written by you? I mean that's quite some self-confidence for sure. I've spent the better part of this week showing other professional programmers how to fix their code which I actually paid for, so that's hard to top, but this one's surely a close second. If anyone ever figured out how to make users log in via LDAP with email login, please let me know. Until then, no Scoold for us. |
@bviktor There's no "logic" in Scoold. Para handles LDAP requests and it has no logic either. Login credentials are forwarded to I'm not saying it's your fault. I'm just saying it's very likely that your LDAP configuration needs to be tweaked because I've talked to other people about the same thing and eventually they all managed to get it working. I understand your frustration but please, let's try to keep the discussion positive and constructive. If you find a bug - I'll fix it. That's about all I can do for now. |
@bviktor BTW, are you by any chance testing against https://paraio.com? I'm asking because EC2 crashed without notice and the service was down for a while. |
…ogins would fail if the UPN suffix is different than the given domain, related to Erudika/scoold#67
@bviktor I think I finally fixed your issue after 1 year 😄 Just to clarify a few things:
para.security.ldap.user_search_filter = "(&(objectClass=user)(sAMAccountName={1}))"
Here's a working LDAP configuration for AD: para.security.ldap.user_search_filter = "(&(objectClass=user)(sAMAccountName={1}))"
para.security.ldap.base_dn = "ou=dev,dc=erudika,dc=com"
para.security.ldap.server_url = "ldap://192.168.123.70:389"
para.security.ldap.active_directory_domain = "erudika.com" For the above configuration the following logins should work, given that a user
As you can see the domain part is actually ignored because it is irrelevant. You cannot bind an AD user with their email. You can bind them based on their |
@albogdano I am not sure if your I made a small spring boot app to test authentication against the ldap server. This is the minimum configuration I needed to get it working. I will try and "translate" this to what you are doing in para LDAPAuthenticator, but wondering if this is something you've ran into before or have advice in the meantime? @Autowired
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.ldapAuthentication()
.userSearchFilter("(blah)")
.contextSource()
.url("ldap://ldap.host.com:3456/DC=company,DC=com")
//This is the critical config required
.managerDn("username")
.managerPassword("password");
} I've only spent like 1-2 hrs getting this sample working and haven't looked too much into how/if it translates to bindDn/bindPassword. But hoping you might know something I don't? Thanks in advanced! |
@mljohns89 Not really but you can configure LDAP authentication with a few system properties in Scoold. |
My ldap server requires authentication to query. So in this scenario, Para
is the ldap client. Para needs to authenticate to the ldap server using
the managerDn and managerPassword config in my snippet.
I am trying to figure out how (or if) Para has support for this?
In your testing, did you only try connecting to an ldap server with
anonymous authentication?
…On Sun, Mar 31, 2024, 3:06 PM Alex Bogdanovski ***@***.***> wrote:
@mljohns89 <https://github.com/mljohns89> Not really but you can
configure LDAP authentication with a few system properties in Scoold.
What are you trying to integrate with Scoold and LDAP exactly? Scoold
makes LDAP auth requests to Para which calls the LDAP server in turn.
—
Reply to this email directly, view it on GitHub
<#67 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABO5DKA7EEWVTOHWXUBWXJLY3BNEBAVCNFSM4FDJPQEKU5DIOJSWCZC7NNSXTN2JONZXKZKDN5WW2ZLOOQ5TEMBSHA4DOOJQGY4Q>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
@albogdano I figured it out. I copied your LDAPAuthenticator and LDAPAuthenticationProvider into my code and played around until I got it working! I will upload a gist or something and share with you. Essentially, I needed the |
@albogdano Disregard my previous comment...I must have done something dumb and got a false positive. When the LDAP Server requires Authentication to query, I essentially need to pass the I did a side-by-side with how Spring Security handles LDAP out of the box. What do you think about adding this nested class to class SimpleAuthenticationSource implements AuthenticationSource {
private final String bindDn;
private final String bindPass;
SimpleAuthenticationSource(String bindDn, String bindPass) {
this.bindDn = bindDn;
this.bindPass = bindPass;
}
public String getPrincipal() {
return this.bindDn;
}
public String getCredentials() {
return this.bindPass;
}
} And then we would have to modify if(bindAuthenticationRequired) {
contextSource.setAuthenticationSource(new SimpleAuthenticationSource(bindDn, bindPass));
} else {
contextSource.setAuthenticationSource(new SpringSecurityAuthenticationSource());
} We'd have to add a new config property too: Let me know your thoughts and if you want me to open a PR |
@albogdano OK for real now I found the problem! You need to add a call to If you compare to the Jenkins LDAP Plugin (they are also using Spring LDAP library): https://github.com/jenkinsci/ldap-plugin/blob/master/src/main/java/jenkins/security/plugins/ldap/LDAPConfiguration.java#L613 I tested this out locally and it will setup the required Bind Authentication Context in Para. Here's the full /*
* Copyright 2013-2022 Erudika. http://erudika.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* For issues and patches go to: https://github.com/erudika
*/
package com.erudika.para.server.security;
import com.erudika.para.core.utils.Utils;
import java.util.Arrays;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ldap.core.DirContextOperations;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.ldap.DefaultSpringSecurityContextSource;
import org.springframework.security.ldap.authentication.AbstractLdapAuthenticator;
import org.springframework.security.ldap.authentication.BindAuthenticator;
import org.springframework.security.ldap.authentication.LdapAuthenticator;
import org.springframework.security.ldap.authentication.PasswordComparisonAuthenticator;
import org.springframework.security.ldap.authentication.SpringSecurityAuthenticationSource;
import org.springframework.security.ldap.search.FilterBasedLdapUserSearch;
import org.springframework.security.ldap.search.LdapUserSearch;
/**
* LDAP authenticator for either bind-based or password comparison authentication.
* @author Alex Bogdanovski [[email protected]]
*/
public final class LDAPAuthenticator implements LdapAuthenticator {
private static final Logger logger = LoggerFactory.getLogger(LDAPAuthenticator.class);
private AbstractLdapAuthenticator authenticator = null;
/**
* Default constructor.
* @param ldapSettings LDAP config map for an app
*/
public LDAPAuthenticator(Map<String, String> ldapSettings) {
if (ldapSettings != null && ldapSettings.containsKey("security.ldap.server_url")) {
String serverUrl = ldapSettings.get("security.ldap.server_url");
String baseDN = ldapSettings.get("security.ldap.base_dn");
String bindDN = Utils.noSpaces(ldapSettings.get("security.ldap.bind_dn"), "%20");
String bindPass = ldapSettings.get("security.ldap.bind_pass");
String userSearchBase = ldapSettings.get("security.ldap.user_search_base");
String userSearchFilter = ldapSettings.get("security.ldap.user_search_filter");
String userDnPattern = ldapSettings.get("security.ldap.user_dn_pattern");
String passAttribute = ldapSettings.get("security.ldap.password_attribute");
boolean usePasswordComparison = ldapSettings.containsKey("security.ldap.compare_passwords");
DefaultSpringSecurityContextSource contextSource =
new DefaultSpringSecurityContextSource(Arrays.asList(serverUrl), baseDN);
contextSource.setAuthenticationSource(new SpringSecurityAuthenticationSource());
contextSource.setCacheEnvironmentProperties(false);
if (!bindDN.isEmpty()) {
// this is usually not required for authentication - leave blank
contextSource.setUserDn(bindDN);
}
if (!bindPass.isEmpty()) {
// this is usually not required for authentication - leave blank
contextSource.setPassword(bindPass);
}
contextSource.afterPropertiesSet(); //THIS IS THE NEW LINE
LdapUserSearch userSearch = new FilterBasedLdapUserSearch(userSearchBase, userSearchFilter, contextSource);
if (usePasswordComparison) {
PasswordComparisonAuthenticator p = new PasswordComparisonAuthenticator(contextSource);
p.setPasswordAttributeName(passAttribute);
p.setUserDnPatterns(getUserDnPatterns(userDnPattern));
p.setUserSearch(userSearch);
authenticator = p;
} else {
BindAuthenticator b = new BindAuthenticator(contextSource);
b.setUserDnPatterns(getUserDnPatterns(userDnPattern));
b.setUserSearch(userSearch);
authenticator = b;
}
}
}
@Override
public DirContextOperations authenticate(Authentication authentication) {
try {
if (authenticator != null) {
return authenticator.authenticate(authentication);
}
} catch (Exception e) {
logger.warn("Failed to authenticate user with LDAP server: {}", e.getMessage());
}
throw new AuthenticationServiceException("LDAP user not found.");
}
private String[] getUserDnPatterns(String userDnPattern) {
if (StringUtils.isBlank(userDnPattern)) {
return new String[]{""};
}
if (userDnPattern.contains("|")) {
return userDnPattern.split("\\|");
}
return new String[]{userDnPattern};
}
} |
@albogdano Another PR: Erudika/para#266 |
I'm setting up server like this:
at first try, everything is working but after adjust some of the configuration. I am not sure what is the root cause. now suddenly there is an error cannot authenticate with LDAP server localhost:8389 (which is the default)
my workaround is:
I have to also put the config inside the para (application.conf) too and now it is working again.
The text was updated successfully, but these errors were encountered: