Spring Security and multiple ldap configuration - spring-security

I use Spring Security to manage user and group securities.
All datas are stored in a ldap server. My configuration is the following:
<authentication-manager alias="authenticationManager">
<ldap-authentication-provider
user-search-filter="(mail={0})"
user-search-base=""
group-search-filter="(uniqueMember={0})"
group-search-base="ou=groups"
group-role-attribute="cn"
role-prefix="ROLE_"
user-context-mapper-ref="contextMapper">
</ldap-authentication-provider>
<lda
</authentication-manager>
<beans:bean id="contextMapper" class="com.mycompany.CustomContextMapper">
<beans:property name="indexer" ref="entityIndexer" />
</beans:bean>
<ldap-user-service server-ref="ldapServer" user-search-filter="(mail={0})" />
<ldap-server manager-dn="cn=admin,dc=springframework,dc=org" manager-password="password" url="ldap://server/dc=springframework,dc=org" id="ldapServer" />
All runs like a charm. Now, I want to add a second ldap server if the first one is down (fallback). I can't find an easy way to do it.
So, my question si simple: how to add a second ldap server in this config to provide a fallback if the first one is down ?

Use space delimited value for url attribute:
url="ldap://server1/dc=springframework,dc=org ldap://server2/dc=springframework,dc=org"
Ref: LDAP & LDAPS URLs

That's so simple that I missed it.
Just configure multiple url separated by a space as it:
<ldap-server ... url="ldap://server1/dc=springframework,dc=org ldap://server2/dc=springframework,dc=org" />

The previous answers are correct.
I wanted to add information on LDAP server redundancy. Since that is the objective for adding multiple LDAP urls, hope it is useful.
I tested few scenarios:
For LDAP Server urls(url1, url2)
If both LDAP servers specified by urls are down, application login will fail.
If one LDAP server is down. Consider server1 as url1 : ldap://url1
(irrespective of url1 position 1st or 2nd), application works fine.
If either url is syntactically malformed: url1 : ldap://MALFORMED_URL , the application will fail to startup.

Related

Oauth 1.0a consumer code equesting an access token twice

I've setup a consumer app, and most of the oauth workflow looks correct, but for some reason after the callback url is invoked by the provider, it tries to get an access token TWICE. The first time works
http://localhost:8080/app/ws/oauth/token
[OAuth oauth_consumer_key="itd79n64zlwv5hhv", oauth_nonce="cac26978-c36c-4a8b-8f3e-3e779ff927ab", oauth_signature="5c8BM9qQoijXC2f5IXpQGtSQsys%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1458938403", oauth_token="5451cf20-7eed-4797-819c-ee2316981654", oauth_verifier="c56de555-79df-455e-ab87-f5f11b953fef", oauth_version="1.0"]
response is a 200, payload includes oauth_token=a95d6305-4261-4c1d-a9b0-43411a0c2f2c&oauth_token_secret=573702d2-70ca-412c-84e5-868e9ee07169
but then, it calls the URL again.
http://localhost:8080/app/ws/oauth/token
[OAuth oauth_consumer_key="itd79n64zlwv5hhv", oauth_nonce="6c013ef9-2f3c-49dd-84fb-97db73b5fb39", oauth_signature="5RTQE5XtcqUwEFVvYQjExhH1eio%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1458938403", oauth_token="5451cf20-7eed-4797-819c-ee2316981654", oauth_verifier="c56de555-79df-455e-ab87-f5f11b953fef", oauth_version="1.0"
which causes an exception on the server since the request token has been removed and the access token has already been issued.
When stepping through the code, I can see that the OAuthConsumerContextFilter stores the access token fine after the first call.
Somehow the filter chain ends up bring it back to readResource in CoreOAuthConsumerSupport with the request token.
I built the consumer app using spring-boot.
from: applicationContext.xml
<bean id="oscarService" class="com.mdumontier.oscar.labline.service.OscarService">
<property name="oscarRestTemplate">
<bean class="org.springframework.security.oauth.consumer.client.OAuthRestTemplate">
<constructor-arg ref="oscar" />
</bean>
</property>
</bean>
<security:authentication-manager>
<security:authentication-provider>
<security:user-service>
<security:user name="marissa" password="wombat" authorities="ROLE_USER" />
<security:user name="sam" password="kangaroo" authorities="ROLE_USER" />
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
<security:http auto-config='true' >
</security:http>
<oauth:consumer resource-details-service-ref="resourceDetails" oauth-failure-page="/oauth_error.jsp">
<oauth:url pattern="/oscar/**" resources="oscar"/>
</oauth:consumer>
<oauth:resource-details-service id="resourceDetails">
<oauth:resource id="oscar"
key="itd79n64zlwv5hhv"
secret="d3psvmrn8k1xws9x"
request-token-url="http://localhost:8080/app/ws/oauth/initiate"
user-authorization-url="http://localhost:8080/app/ws/oauth/authorize"
access-token-url="http://localhost:8080/app/ws/oauth/token"/>
</oauth:resource-details-service>
Spring Boot automatically registers any Beans which implement Filter in the main application filter chain. See: https://stackoverflow.com/a/28428154 for a bit more detail.
The oauth:consumer helper registers both OAuth filters as beans, and seems to not have been updated in a while. I couldn't even get the XML config to work properly under the latest Spring Boot. Anyway, this means that both will be run twice, and in the case of the OAuthConsumerContextFilter this is destructive since it will run outside the security sub-chain and fail every time.
To fix this you have two options.
One, hint to Spring Boot to avoid this behavior by providing a FilterRegistrationBean for each filter it's automatically picking up, like so:
#Bean
public FilterRegistrationBean registration(OAuthConsumerContextFilter filter) {
FilterRegistrationBean registration = new FilterRegistrationBean(filter);
registration.setEnabled(false);
return registration;
}
Two, bypass the XML config entirely and use Java config. I've posted a complete working code sample of getting on OAuth 1 consumer in Spring Boot using Java config in this answer: https://stackoverflow.com/a/42143001/2848158
Within the Java config, you would have to either repeat the FilterRegistrationBean trick, or just not register those filters as beans in the first place but rather create and register instances directly with the Security filter chain.

Hazelcast IMap not available in JMX on startup

I am trying to add monitoring for a hazelcast map to Nagios. Now I face the issue that the IMap entry in JMX is not available before the first usage of this map (get/set values)
Is there any option to initialize this during hazelcast startup.
The map is configured as follows
<map name="myMap">
<backup-count>1</backup-count>
<time-to-live-seconds>0</time-to-live-seconds>
<max-idle-seconds>0</max-idle-seconds>
<eviction-policy>LRU</eviction-policy>
<max-size policy="USED_HEAP_SIZE">256</max-size>
<eviction-percentage>25</eviction-percentage>
<merge-policy>com.hazelcast.map.merge.PutIfAbsentMapMergePolicy</merge-policy>
<map-store enabled="true" initial-mode="EAGER" />
</map>
I already tried to add map-store eager loading but this also did not fixed the issue:
<map name="myMap">
...
<map-store enabled="true" initial-mode="EAGER" />
</map>
The JMX path which I try to access is
com.hazelcast:instance=_hzInstance_1_dev,type=IMap,name=myMap
How can I configure the map in such a way that the JMX values are always available.

LDAP authentication without managerDN and manager password

I am writing an application in Java Spring framework to perform Active Directory LDAP authentication.
I am succeeding in connecting to my organization LDAP.
Here is the configuration settings:Spring-security.xml
<!-- This is where we configure Spring-Security -->
<security:http auto-config="true" use-expressions="true"
access-denied-page="/oops">
<security:intercept-url pattern="/auth/*"
access="isAuthenticated()" />
<security:logout invalidate-session="true"
logout-success-url="/" logout-url="/logout" />
</security:http>
<security:authentication-manager>
<security:ldap-authentication-provider
user-search-filter="(&(sAMAccountname={0})(objectCategory=user))"
user-search-base="DC=am, DC=example, DC=com" group-search-filter="(&(sAMAccountname={0})(objectCategory=group))"
group-search-base="DC=am, DC=example, DC=com">
</security:ldap-authentication-provider>
</security:authentication-manager>
<security:ldap-server url="ldaps://myserver.am.example.com:4567"
manager-dn="CN=Johnson \, Mitchell, OU=San Francisco,DC=am,DC=example,DC=com"
manager-password="sdvsdvsvs" />
My question here is that,is there any way to authenticate LDAP without supplying manager-dn and manager-password in security:ldap-server tag.
Please provide a solution to this.Thanks in advance.
Yes it is possible: you can let the user who is actualy logging in connecting to the LDAP himself to test his credential and fetch its userdata.
AuthenticationManager configuration:
#Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
ActiveDirectoryLdapAuthenticationProvider activeDirectoryLdapAuthenticationProvider = new ActiveDirectoryLdapAuthenticationProvider(domain, url, rootDn);
activeDirectoryLdapAuthenticationProvider.setSearchFilter(searchFilter);
auth.authenticationProvider(activeDirectoryLdapAuthenticationProvider);
}
Spring security does two things:
Let the user log in with his username and password
Find the user to fetch user info, groups, etc. For this step, you must specify a searchFilter that can find a user based on it's username, like "userPrincipalName={0}" where {0} is the provided username.
Define an administrative user who has the necessary permissions, and use that. You certainly shouldn't use the managerDN for anything in your application.

Spring social linkedin not sending "state" parameter with oAuth2

I am trying to implement Linkedin social login in a Spring Application; I am using the most recent release spring-social-linkedin-1.0.0.RC4 and spring-social-1.0.3.RELEASE.
I manage to get to the point where authorization link is sent to Linkedin:
https://www.linkedin.com/uas/oauth2/authorization?client_id=....&response_type=code&redirect_uri=....
but the request is sent without the mandatory "state" request parameter, so it always results in an error from Linkedin. I double checked that simply adding the missing parameter to te url by hand results in the correct login page from linkedin, so I know client id is right.
Here's the code I use to connect to Linkedin:
User principal = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
ConnectionRepository repository = usersConnectionRepository.createConnectionRepository(principal.getUsername());
Connection<LinkedIn> connection = repository.findPrimaryConnection(LinkedIn.class);
return connection.getApi();
And the configuration for connectionFactoryLocator, where placeholders are resolved correctly:
<bean id="connectionFactoryLocator"
class="org.springframework.social.connect.support.ConnectionFactoryRegistry">
<property name="connectionFactories">
<list>
<bean
class="org.springframework.social.linkedin.connect.LinkedInConnectionFactory">
<constructor-arg value="${linkedin.api.key}" />
<constructor-arg value="${linkedin.api.secret}" />
</bean>
</list>
</property>
</bean>
Everything else is configured by the book and it's pretty standard spring social + jdbc setup.
I think "state" and "scope" parameters should be configured in the same way as "api.key" and "api.secret" (which are correctly set in the request), but I can't find how.
Did someone manage to get this right?
I found out: the simplest way to do it is to use an Interceptor and add it to the ConnectController. You will be able to add any parameter you like there.
Or upgrade to spring social 1.1.0 which has automatic state parameter handling (it's currently at RC1 stage).

WiX IIS Authentication mode on subdirectories

I'm trying to install a ASP.NET MVC web application with wix. So far so good.
Unfortunately I came up with a pretty annoying issue I don't know how to implement.
Imagine the following WebSite structure:
Default Web Site (Windows authentication)
MyApplication (Windows authentication)
WebServices (Anoynmous authentication)
As you can see the whole website can only be accessed with valid NT credentials.
But I need to set anonymous authentication on the WebServices directory.
How can I accomplish this with wix?
<DirectoryRef Id="INSTALLDIR_WEB">
<!-- Configuring app pool -->
<Component Id="Cmp_AppPool" Guid="27CE75BF-1118-4E15-9CD5-6FA973A20B45" KeyPath="yes">
<util:User Id="AppPoolUser" Domain="[APPPOOL_IDENTITYDOMAIN]" Name="[APPPOOL_IDENTITY]" Password="[APPPOOL_IDENTITYPWD]" CreateUser="no" />
<iis:WebAppPool Id="CustomAppPool" ManagedPipelineMode="[APPPOOL_PIPELINEMODE]" ManagedRuntimeVersion="[APPPOOL_ManagedRuntimeVersion]" Name="[APPPOOL_NAME]" Identity="other" User="AppPoolUser" />
</Component>
<!-- Create new WebApplication -->
<Component Id="Cmp_CreateApplication" Guid="65591914-46A9-4CB7-BF2E-9F30F4DEE3EC" KeyPath="yes">
<Condition><![CDATA[Installed OR WEBAPP_NAME <> ""]]></Condition>
<iis:WebVirtualDir Id="MyWebVirtualDir" Alias="[WEBAPP_NAME]" Directory="INSTALLDIR_WEB" WebSite="DefaultWebSite">
<iis:WebDirProperties Id="MyWebVirtDirProperties" AnonymousAccess="no" BasicAuthentication="no" WindowsAuthentication="yes" />
<iis:WebApplication Id="MyWebWebApplication" Name="[WEBAPP_NAME]" WebAppPool="CustomAppPool" />
</iis:WebVirtualDir>
</Component>
<!-- Install directly in the IIS ROOT -->
<Component Id="Cmp_SetPermissions">
<iis:WebDir Path="WebServices" DirProperties="EnableAnonymousAuth" WebSite="DefaultWebSite" Id="ServiceDir" />
</Component>
</DirectoryRef>
<iis:WebDirProperties Id="EnableAnonymousAuth" Read="yes" Write="yes" Script="yes" Execute="yes" AnonymousAccess="yes" Index="no" LogVisits="no" />
The above code successfully creates the webapplication but does not set anonymous access on the WebServices directory.
Any ideas?
Regards
Lukas
There is WebDirProperties element for WebDir.
You can set AnonymousAccess="yes" there.
Also you should also provide the user account using the AnonymousUser attribute, and determine what setting to use for the IIsControlledPassword attribute.

Resources