I'm using Spring Security (well, jasper reports server, that uses Spring security) to connect to a Microsoft AD. But I'm getting a 'bad credentials' in my log but I know the credentials are fine and on my same machine I can use JXplorer to connect to my AD and can use another program to login using this account. The log shows it's connecting, but failing:
Authentication attempt using com.jaspersoft.jasperserver.api.security.externalAuth.wrappers.spring.ldap.JSLdapAuthenticationProvider
Processing authentication request for user: pharmacy
Searching for user 'pharmacy', with user search [ searchFilter: '(sAMAccountName={0})', searchBase: 'OU=Users', scope: subtree, searchTimeLimit: 0, derefLinkFlag: false ]
Got Ldap context on server 'ldap://10.17.188.4:389/dc=harris,dc=local'
Searching for entry under DN 'dc=harris,dc=local', base = 'ou=Users', filter = '(sAMAccountName={0})'
Found DN: cn=pharmacy,ou=Users
Attempting to bind as cn=pharmacy,ou=Users,dc=harris,dc=local
Removing pooling flag for user cn=pharmacy,ou=Users,dc=harris,dc=local
Failed to bind as cn=pharmacy,ou=Users: org.springframework.ldap.AuthenticationException: [LDAP: error code 49 - 8009030C: LdapErr: DSID-0C0903AA, comment: AcceptSecurityContext error, data 532, v1772
Bad credentials
In my AD the user is as follows:
distinguished name: CN=pharmacy,OU=Users,DC=harris,DC=local
My configuration is as follows:
<bean id="ldapAuthenticationProvider" class="com.jaspersoft.jasperserver.api.security.externalAuth.wrappers.spring.ldap.JSLdapAuthenticationProvider">
<constructor-arg>
<bean class="com.jaspersoft.jasperserver.api.security.externalAuth.wrappers.spring.ldap.JSBindAuthenticator">
<constructor-arg>
<ref local="ldapContextSource"/>
</constructor-arg>
<property name="userSearch">
<ref local="userSearch" />
</property>
</bean>
</constructor-arg>
</bean>
<bean id="ldapContextSource" class="com.jaspersoft.jasperserver.api.security.externalAuth.ldap.JSLdapContextSource">
<constructor-arg value="ldap://10.17.188.4:389/DC=harris,DC=local"/>
<property name="userDn" value="CN=ldadmin,OU=Users,DC=harris,DC=local"/>
<property name="password" value="xxxxx"/>
<property name="referral" value="follow" />
</bean>
<bean id="userSearch"
class="com.jaspersoft.jasperserver.api.security.externalAuth.wrappers.spring.ldap.JSFilterBasedLdapUserSearch">
<constructor-arg index="0">
<value>OU=Users</value>
</constructor-arg>
<constructor-arg index="1">
<value>(sAMAccountName={0})</value>
</constructor-arg>
<constructor-arg index="2">
<ref local="ldapContextSource" />
</constructor-arg>
<property name="searchSubtree">
<value>true</value>
</property>
</bean>
I see so many different permutations of config on the internet it's hard to know which to follow. I did have a DefaultLdapAuthoritiesPopulator constructor for the group with the authentication provider but that didn't work either.
Can anyone help? Many thanks.
It seems to have been a VPN issue. The above is fine :)
Leaving in case anyone needs to get Microsoft AD working with Jasper/Spring.
Related
I m trying to implement the Spring saml sample application and I m having issues with authentication. I followed the exact steps outlined in quick start guide namely: downloading the sample app; configuring IDP and SP metadata;
I was able to generate the SP metadata and successfully uploaded it to SSOCircle IDP.
When I enter in my SSOCircle login details - it fails to redirect back to my local application and log me in;
Here are my config changes I made:
IDP config:
<bean id="metadata" class="org.springframework.security.saml.metadata.CachingMetadataManager">
<constructor-arg>
<list>
<bean class="org.opensaml.saml2.metadata.provider.HTTPMetadataProvider">
<constructor-arg>
<value type="java.lang.String">http://idp.ssocircle.com/idp-meta.xml</value>
</constructor-arg>
<constructor-arg>
<value type="int">5000</value>
</constructor-arg>
<property name="parserPool" ref="parserPool"/>
</bean>
</list>
</constructor-arg>
</bean>
SP config:
<bean id="metadataGeneratorFilter" class="org.springframework.security.saml.metadata.MetadataGeneratorFilter">
<constructor-arg>
<bean class="org.springframework.security.saml.metadata.MetadataGenerator">
<property name="entityId" value="http://localhost:8081/spring-security-saml2-sample"/>
<property name="signMetadata" value="false"/>
<property name="extendedMetadata">
<bean class="org.springframework.security.saml.metadata.ExtendedMetadata">
<property name="idpDiscoveryEnabled" value="false"/>
</bean>
</property>
</bean>
</constructor-arg>
</bean>
Can someone please thrown some light here... Thank you in advance.
Ok, I was able to get through this; by explicitly changing the "bindingSSO" property in MetadataGenerator bean to "POST" solved my problem.
<property name="bindingsSSO" >
<list>
<value>POST</value>
</list>
</property>
It looks like, the code is setting the default binding to "SSO_ARTIFACT"
I'm using:
- Spring 3.1.3
And the problem is I'm unable to connect with the Active Directory via LDAP using valid credentials.
i don't know if is caused by a malformed pattern or a configuration issue about userdn or url's rootDn. Although , at first glance , it seems that everything is correct.
This is my current spring security config file:
...
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider ref="ldapAuthProvider" />
</security:authentication-manager>
<bean id="ldapAuthProvider"
class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
<constructor-arg>
<bean id="bindAuthenticator" class="org.springframework.security.ldap.authentication.BindAuthenticator">
<constructor-arg ref="contextSource" />
<property name="userDnPatterns">
<list><value>sAMAccountName={0}</value></list>
</property>
</bean>
</constructor-arg>
</bean>
<bean id="contextSource"
class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
<constructor-arg value="ldap://remotehost:port/OU=My%20Company,dc=domain,dc=subdomain"/>
<property name="userDn" value="CN=managerUserCN,OU=Users,OU=Test Accounts,OU=My Company,dc=domain,dc=subdomain/>
<property name="password" value="thePass"/>
</bean>
...
*I have replaced the real urls, organizations, groups, etc by descriptive data
*It's a requeriment searching by sAMAccountName.
And the NamingException throwed by doAuthentication:bindWithDn is the next:
*org.springframework.ldap.AuthenticationException: [LDAP: error code 49 - 80090308: LdapErr: DSID-0C0903A9, comment: AcceptSecurityContext error, data 52e, v1db1*
And 52e code interpretation which I read on the LDAP wiki is not entirely correct because is launching both typing a existing username and nonexistent username.
I'm refering to:
NOTE: Returns when username is valid but password/credential is invalid. Will prevent most other errors from being displayed as noted.
Not for me.
I have found the answer for my question.
I got it specifying user-Search property in the bindAuthentication. Previously I had tested the userSearch option without including base directory (first parameter). So, almost for me, it's mandatory and let the authentication works.
In code:
<bean id="ldapAuthProvider"
class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
<constructor-arg>
<bean id="bindAuthenticator" class="org.springframework.security.ldap.authentication.BindAuthenticator">
<constructor-arg ref="contextSource" />
<property name="userSearch" ref="userSearch"/>
</bean>
</constructor-arg>
</bean>
<bean id="userSearch"
class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
<constructor-arg>
<value>OU=My Company,DC=domain,DC=subdomain</value>
</constructor-arg>
<constructor-arg>
<value>(sAMAccountName={0})</value>
</constructor-arg>
<constructor-arg ref="contextSource" />
<property name="searchSubtree">
<value>true</value>
</property>
</bean>
Perhaps I can help someone with a similar issue.
pD: Another option would be use the specified ActiveDirectoryLdapAuthenticationProvider
<bean id="ldapActiveDirectoryAuthProvider" class="org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider">
<constructor-arg value="domain.subdomain" />
<constructor-arg value="ldap://host:port" />
<property name="convertSubErrorCodesToExceptions" value="true"/>
</bean>
It seems to work fine too.
This is some part of my spring-security.xml.
My requirement is - i want to use embedded LDAP server only and want to use LdapAuthoritiesPopulator with itt
<security:authentication-manager>
<security:ldap-authentication-provider
user-search-filter="(uid={0})"
user-search-base="ou=users"
group-search-filter="(uniqueMember={0})"
group-search-base="ou=groups"
group-role-attribute="cn"
role-prefix="ROLE_">
</security:ldap-authentication-provider>
</security:authentication-manager>
<!-- Use an embedded LDAP server. We need to declare the location of the LDIF file
We also need to customize the root attribute default is -->
<security:ldap-server ldif="classpath:mojo.ldif" root="dc=springframework,dc=org"/>
I want to use my custom LdapAuthoritiesPopulator.
How to use it with embedded ldap server.
I am new to spring as of now.
You can configure your authentication provider with DefaultLDAPAuthoritesPopulator and provide the details to find the groups for roles. If there is something more specific to your case, you could extend this class. Looking at the spring-security-samples. I am new to spring-security too but i found the source code to be very helpful. Good luck.
FYI
contextSource bean DefaultSpringSecurityContextSource should be configured with the url to your LDAP server.
Hope this helps.
<bean id="ldapAuthenticationProvider" class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
<constructor-arg>
<bean class="org.springframework.security.ldap.authentication.BindAuthenticator">
<constructor-arg ref="contextSource"/>
<property name="userSearch">
<bean id="userSearch" class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
<constructor-arg index="0" value="ou=Google,ou=People"/>
<constructor-arg index="1" value="(uid={0})"/>
<constructor-arg index="2" ref="contextSource"/>
</bean>
</property>
</bean>
</constructor-arg>
<constructor-arg>
<bean class="org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator">
<constructor-arg ref="contextSource"/>
<constructor-arg value="ou=Groups"/>
<property name="groupSearchFilter" value="member={0}"/>
<property name="searchSubtree" value="true"/>
</bean>
</constructor-arg>
<property name="authoritiesMapper">
<bean class="org.springframework.security.core.authority.mapping.SimpleAuthorityMapper">
<property name="convertToUpperCase" value="true"/>
</bean>
</property>
</bean>
<bean id="contextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
<constructor-arg value="ldap://127.0.0.1:389/dc=google,dc=com"/>
</bean>
I could not found any decent, clear example to learn JMS component with Spring configuration. So I wrote something like this:
<bean id="weblogic" class="org.apache.camel.component.jms.JmsComponent">
<property name="connectionFactory" ref="jmsConnectionFactory"/>
</bean>
<bean id="jmsJndiTemplate" class="org.springframework.jndi.JndiTemplate">
<property name="environment">
<props>
<prop key="java.naming.factory.initial">weblogic.jndi.WLInitialContextFactory</prop>
<prop key="java.naming.provider.url">t3://${ip}:${port}</prop>
</props>
</property>
</bean>
<bean id="jmsConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate" ref="jmsJndiTemplate"/>
<property name="jndiName" value="jms/cdrPreMO-connfact-jndi"/>
</bean>
<camelContext id="camelContext" xmlns="http://camel.apache.org/schema/spring">
<camel:endpoint id="jmsQueue" uri="weblogic:queue:jms/cdrPreMO-queue-jndi"/>
<route>
<from ref="jmsQueue"/>
<bean ref="test" method="writeFile"/>
<to uri="log:errors?level=ERROR"/>
</route>
</camelContext>
But it gives the exception :
Caused by: javax.naming.NameNotFoundException: Unable to resolve 'weblogic.jms.backend.jms'. Resolved 'weblogic.jms.backend'; remaining name 'jms'
at weblogic.jndi.internal.BasicNamingNode.newNameNotFoundException(BasicNamingNode.java:1139)
at weblogic.jndi.internal.BasicNamingNode.lookupHere(BasicNamingNode.java:252)
at weblogic.jndi.internal.ServerNamingNode.lookupHere(ServerNamingNode.java:182)
at weblogic.jndi.internal.BasicNamingNode.lookup(BasicNamingNode.java:206)
at weblogic.jndi.internal.BasicNamingNode.lookup(BasicNamingNode.java:214)
at weblogic.jndi.internal.BasicNamingNode.lookup(BasicNamingNode.java:214)
at weblogic.jndi.internal.BasicNamingNode.lookup(BasicNamingNode.java:214)
at weblogic.jndi.internal.WLEventContextImpl.lookup(WLEventContextImpl.java:254)
at weblogic.jndi.internal.WLContextImpl.lookup(WLContextImpl.java:393)
at weblogic.jms.frontend.FEManager.destinationCreate(FEManager.java:287)
... 8 more
JMS Conf is true(ip port and jndi names). It is getting the connection, and the session but gives the exception
Could someone tell me what are my mistakes?
Thanx
EDIT: fix applied according to the comment of Claus.
The Camel endpoints should refer to "weblogic" as the component name.
<camel:endpoint id="jmsQueue" uri="jms:queue:jms/cdrPreMO-queue-jndi"/>
Should be
<camel:endpoint id="jmsQueue" uri="weblogic:queue:jms/cdrPreMO-queue-jndi"/>
As that is the name you gave the JMS component in the id attribute of the < bean > tag, eg
<bean id="weblogic" class="org.apache.camel.component.jms.JmsComponent">
<property name="connectionFactory" ref="jmsConnectionFactory"/>
</bean>
Solved but with a workaround. I still do not know what the problem really is but, instead of weblogic create its own destination by itself, I gave the responsibility to spring like:
<bean id="weblogic" class="org.apache.camel.component.jms.JmsComponent">
<property name="configuration" ref="jmsConfiguration" />
</bean>
<bean id="jmsJndiTemplate" class="org.springframework.jndi.JndiTemplate">
<property name="environment">
<props>
<prop key="java.naming.factory.initial">weblogic.jndi.WLInitialContextFactory</prop>
<prop key="java.naming.provider.url">${ip}:${port}</prop>
</props>
</property>
</bean>
<bean id="jndiDestinationResolver" class="org.springframework.jms.support.destination.JndiDestinationResolver">
<property name="jndiTemplate" ref="jmsJndiTemplate"/>
</bean>
<bean id="jmsConfiguration" class="org.apache.camel.component.jms.JmsConfiguration">
<property name="connectionFactory" ref="jmsConnectionFactory"/>
<property name="destinationResolver" ref="jndiDestinationResolver"/>
</bean>
<bean id="jmsConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate" ref="jmsJndiTemplate"/>
<property name="jndiName" value="jms/cdrPreMO-connfact-jndi"/>
</bean>
It is working now.
Although question is pretty old, posting this solution for other users if they get this error. I ran into the this issue on Camel 2.19 version while trying to look up weblogic queue in weblogic 12c version. The lookup that happens here is most likely not a typical JNDI lookup when resolving queue destination in Weblogic.
The end point uri should contain the queue details as follows :
jms_server_name/jms_module_name!queue_name
For example if queue name is TestRequestQueue, created under a module named sample_jms_module and the JMS server is named sample_jms_server in Weblogic, then the uri would need to be as follows :
<camel:endpoint id="jmsQueue" uri="weblogic:queue:sample_jms_server/sample_jms_module!TestRequestQueue"/>
In the prefix portion of the uri weblogic:queue:, the component name can be anything as long as it refers to the created component. It needn't necessarily be weblogic. For example, if the JmsComponent is named as test-jms, the uri will need to be declared with prefix as test-jms:queue: .
Name of the JMS server in weblogic can be obtained from Weblogic console by navigating to the below path :
Services -> Messaging -> JMS Servers
Name of the queue, not the JNDI name, can be obtained from Weblogic console by navigating to the queue and clicking on Monitoring tab. This tab shows the destination name of the queue in the name column.
I've just run apache camel jms component in weblogic 12c with next configuration. The key is the jndi name for the queue.
It must be ./module_name!queueName. './' means local jms server.
<jee:jndi-lookup id="connectionFactoryBean" jndi-name="dpxcomConnectionFactory"/>
<bean id="dpxcomJMSConnectionFactory"
class="org.springframework.jms.connection.CachingConnectionFactory">
<constructor-arg ref="connectionFactoryBean"/>
<property name="sessionCacheSize" value="50"/>
</bean>
Route definition:
from("jms:queue:./DPXCOM!"+config.getMainQueueName()+"?concurrentConsumers="+config.getConcurrentConsumers()
+"&maxConcurrentConsumers="+config.getConcurrentConsumers()+"&jmsMessageType=Text&testConnectionOnStartup=true&connectionFactory=dpxcomJMSConnectionFactory&consumerType=Simple")
.setHeader("jmsMessage").body()
.process(new VerifyJMSMessageProcessor())
.choice()
..
..
end();
I never seen this but I wondering if somebody has come across. Having a web server which access a database. I want to pass the database password encrypted and have spring context decrypting it before setting the datasource. I know the spring security can do some of this like using a salt file in the web server, etc.
The challenge here is that I don't want to give a clear user,password,url to the web server team. Just an encrypted password and have spring decrypted before using it.
Is there something like this already? I know I could code something but is it already done?
Thanks
By using an org.jasypt.properties.EncryptableProperties object, an application would be able to correctly read and use a .properties file like this:
datasource.driver=com.mysql.jdbc.Driver
datasource.url=jdbc:mysql://localhost/reportsdb
datasource.username=reportsUser
datasource.password=ENC(G6N718UuyPE5bHyWKyuLQSm02auQPUtm)
Note that the database password is encrypted (in fact, any other property could also be encrypted, be it related with database configuration or not).
More information :
http://www.jasypt.org/encrypting-configuration.html
I actually found exactly what I was looking for in this thread:
How to use encrypted password in apache BasicDataSource?
Here are the details from jasyp http://www.jasypt.org/spring3.html
This problem and solution to it is explained here..(link)
db.Properties.
#driverClassName=oracle.jdbc.driver.OracleDriver
#url=jdbc:oracle:thin:#localhost:1521:XE
#username=ITEM_INVENTORY
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/ITEM_INVENTORY?zeroDateTimeBehavior=convertToNull
username=root
Encrypt db.Properties
##password=cGFzc3dvcmQ=
password=cm9vdA==
The spring beans configuration for the datasource would look like this
(here you may use only password part)
spring-beans.xml
<bean id="dataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="db#[driverClassName]" />
<property name="url" value="db#[url]" />
<property name="username" value="db#[username]" />
<property name="password" value="encryptedDb#[password]" />
</bean>
<bean id="dbPropertyPlaceholder" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:db.properties</value>
</list>
</property>
<property name="placeholderPrefix" value="db#[" />
<property name="placeholderSuffix" value="]" />
</bean>
<bean id="encryptedDbPropertyPlaceholder" class="com.inventory.api.util.DecryptPropertyConfigurer">
<property name="locations">
<list>
<value>classpath:encryped_db.properties</value>
</list>
</property>
<property name="placeholderPrefix" value="encryptedDb#[" />
<property name="placeholderSuffix" value="]" />
</bean>
And so on.. please refer given link for more information..