How to config spring security to use my customized UserDetailsManager? - java

I'm using spring security to manage user log in/signup in my project. I need to implement user lockout functionality after three failed log in attempts.What I did is to add another field 'account_non_locked' in 'Users' table in database.
The problem I'm facing is that spring security does not update that newly added column. I digged into the source code and found in the default UserDetailsManager the sql statement is written as:
"insert into users (username, password, enabled) values (?,?,?)"
which explains why it does not recognized my new column.
So I copy that file and change it to fit my own need, which is CustomUserDetailsManager.java
Now I can't configure spring security to use my own customized UserDetailsManager. The configuration file right now is:
<authentication-manager alias="authenticationManager">
<authentication-provider>
<password-encoder ref="passwordEncoder" />
<jdbc-user-service id="userDetailsService" data-source-ref="dataSource" />
</authentication-provider>
</authentication-manager>
<beans:bean id="passwordEncoder" class="org.springframework.security.crypto.password.StandardPasswordEncoder" />
I can't find any examples online that will configure this properly. Please help and thanks in advance!

The section 3.2.4 Using other Authentication Providers covers how to do this using authentication-provider#user-service-ref.
Your example would look something like the following:
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="customUserDetailsManager">
<password-encoder ref="passwordEncoder" />
</authentication-provider>
</authentication-manager>
<beans:bean id="passwordEncoder"
class="org.springframework.security.crypto.password.StandardPasswordEncoder" />
<beans:bean id="customUserDetailsManager"
class="com.example.CustomUserDetailsManager">
<!-- additional properties -->
</beans:bean>

Related

How to write authenticationManager as a bean (Converting SamlAuthenticationManager to bean)

I am implementing Spring SAML in my web app which already has spring security implemented, due to which I have 2 authentication managers now. As spring always refer to the last declared authenticationManager, I found the solution to define one authenticationManager as a bean.
Following was my AuthenticationManager before conversion to bean:
<authentication-manager alias="samlAuthenticationManager">
<!-- Register authentication manager for SAML provider -->
<authentication-provider ref="samlAuthenticationProvider"/>
<!-- Register authentication manager for administration UI -->
<authentication-provider>
<user-service id="adminInterfaceService">
<user name="admin" password="admin" authorities="ROLE_ADMIN"/>
</user-service>
</authentication-provider>
</authentication-manager>
Following is my code after converting to bean:
<beans:bean id="samlAuthenticationManager" class="org.springframework.security.authentication.ProviderManager">
<beans:constructor-arg>
<beans:list>
<beans:bean class="org.springframework.security.saml.SAMLAuthenticationProvider">
<beans:property name="userDetails" value="adminInterfaceService"/>
</beans:bean>
</beans:list>
</beans:constructor-arg>
</beans:bean>
<user-service id="adminInterfaceService">
<user name="admin" password="admin" authorities="ROLE_ADMIN"/>
</user-service>
Authentication provider is defines as follows:
<beans:bean id="samlAuthenticationProvider" class="org.springframework.security.saml.SAMLAuthenticationProvider">
<!-- OPTIONAL property: can be used to store/load user data after login -->
<!--
<beans:property name="userDetails" ref="bean" />
-->
</beans:bean>
I am getting following exception:
Cannot convert value of type 'java.lang.String' to required type
'org.springframework.security.saml.userdetails.SAMLUserDetailsService'
for property 'userDetails'
Please help regarding the same. I will be highly obliged.
Thanks in advance
Found the solution here
https://github.com/spring-projects/spring-security/issues/2163
Just had to use id instead of alias in both the authentication-manager
You shouldn't need to use Spring beans. If you don't specify an ID,
you will override the "default" instance. That's pretty much the way
standard Spring beans work. In the referenced thread, the user is
specifying an alias, rather than an ID, so that doesn't create a
separate instance. Again that's the way normal bean instances work, so
I'm not sure we should deviate from that.

What's the best way to support the "ROLE_" prefix for Spring Security?

If you are supporting an older application that does not have prefixes on all the roles, what is the best way to support the "ROLE_" prefix? Is there a way to ignore or omit it from loading?
There doesn't seem to be an easy way to ignore the prefix within the normal spring security configuration. However, I found that you can easily append "ROLE_" to all your roles when loading from the database. I just use the CONCAT function within MySQL to add "ROLE_" to all roles. See below:
<authentication-manager>
<authentication-provider>
<password-encoder hash="md5"/>
<jdbc-user-service
data-source-ref="dataSource"
authorities-by-username-query="SELECT username, CONCAT('ROLE_', rolename) as authority FROM user_role WHERE active = 1 AND username = ?"
users-by-username-query="SELECT username, password, active FROM user WHERE username = ?" />
</authentication-provider>
</authentication-manager>
This concept can also be applied if you create your own class using the UserDetailsService interface:
<!-- Select users and user_roles from database -->
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="myUserDetailsService">
<password-encoder ref="encoder" />
</authentication-provider>
</authentication-manager>
<beans:bean id="encoder" class="com.my.security.MyPasswordEncoder" />
NOTE: I use an "alias" for the "authentication-manager" instead of an ID, because my customization seems to be ignored during the authentication process if I override the default ID.

Spring Security Active Directory Ignoring PartialResultException

I have the following configuration in my spring security xml file. When I try to authenticate I get the following message but cannot proceed.
INFO: Ignoring PartialResultException
I am aware that spring's documentation states that you can set ignorePartialResultException to true but this property seems to be in the LdapTemplate class which may require additional coding. I would like to accomplish all of this through bean configuration as I am not interested in role mapping.
<authentication-manager>
<authentication-provider ref="activeDirectoryAuthProvider" />
</authentication-manager>
<beans:bean id="activeDirectoryAuthProvider"
class="org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider">
<beans:constructor-arg value="mydomain.com" />
<beans:constructor-arg value=" ldap://mydomain.com:389" />
</beans:bean>
After digging around we found out that our role mapping was blocking the authentication. We were in fact hitting AD but Spring was trying to map a group name to a role that didn't exist within our system. Once we did that we were good to go.

enable security check to access wsdl url

I have created a web service in my machine. Its URL is
http://localhost:8080/aaa/test?wsdl
I want to enable one feature to it. As soon as the user enters the url in browser, it should ask for the credentials. Can it be done in web services.
If yes, can some one guide how to achieve it.
Thanks.
If you're already using Spring, you can easily apply basic authentication to a specific URL pattern with Spring Security. In your applicationContext.xml, just add:
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.0.3.xsd">
<!-- HTTP basic authentication in Spring Security -->
<http>
<intercept-url pattern="/*wsdl?" access="ROLE_USER" />
<http-basic />
</http>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="someUser" password="somePassword" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
</beans:beans>
Example taken from Mkyong's Spring Security HTTP Basic Authentication Example.
If you'd like to lookup users in a database, you'd need to use a different authentication provider. The Spring Security reference mentions data-source-ref if you'd like to query the standard Spring Security user data tables. If you've already got your own structure, you might be interested in using user-service-ref instead, in which you can lookup the users yourself.
<authentication-manager>
<authentication-provider user-service-ref='myUserDetailsService'/>
</authentication-manager>
<beans:bean id="myUserDetailsService"
class="mypackage.MyUserDetailsService">
<beans:property name="dataSource" ref="dataSource"/>
</beans:bean>
And code mypackage.MyUserDetailsService extending JdbcDaoImpl and implementing UserDetailsService.

Java Spring NtlmProcessingFilter second controller

<bean id="ntlmFilter" class="org.springframework.security.ui.ntlm.NtlmProcessingFilter">
<security:custom-filter position="NTLM_FILTER" />
<property name="stripDomain" value="true" />
<property name="defaultDomain" value="company" />
<property name="domainController" value="192.168.1.1" />
<property name="authenticationManager" ref="_authenticationManager" />
</bean>
may i know how to set failover second controller?
Unfortunately, NTLM isn't supported by Spring 3.
If using a secondary domain controller is a critical requirement for your application, I think you'll need to look into the jcifs source. Even jcifs doesn't want to support NTLM anymore either. But the old libraries are out there. I've hacked around so that my app will invisibly authenticate users whether they're from domainA or domainB. So it's possible, although possibly a bit daunting.
If I understood your question properly, you are looking for a fallback authentication provider, You can setup a list of authentication managers, so that if first one fails, it will automatically check with second one.
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider ref="ntlmServiceAuthenticationProvider"/>
<security:authentication-provider ref="ldapAuthProvider"/>
</security:authentication-manager>

Categories

Resources