Spring Security 3 + Random Salt - spring-security

So I understand that you can check a password in Spring Security with salt based on a userDetail property and then hash it to compare to a hash in the database, however what if the salt used when creating each user is random (and is stored in the DB), would I need to create my own userDetails class that contains a salt property and then set that as the field spring security uses to salt with in the securityApplicationContext?
If so how would I go about writing my own userDetails class to accomplish that? Sorry still pretty new to Spring/Java.

Ok but then how do I tell the securityApplicationContext to use myCustomUserDetails class to store the user instead of the default userDetails class?
Like this:
<b:bean id="customUserDetailsService" class="com.your.company.security.MyUserDetailsService"/>
<s:authentication-provider user-service-ref="customUserDetailsService" />
This goes in your security context.
Also this might help.
Writing a custom UserDetailsService.

Related

Why must I store a password column in my User domain if I'm using LDAP authentication?

I have a Grails application that uses the Spring Security Core and Spring Security LDAP plugins. I am using the bind method of authentication with an LDAP server as my only authentication provider. Why must I still store a password column in my database? My application has absolutely no need to store a value for a password, but it will not work if I remove the password field from the generated User domain class. Do I really have to store a password column with the value of null in my User table? Surely there must be a different approach to this.
I don't think you must!
simply define the password field as transient in your UserAccount class:
class UserAccount {
String password
static transients = [ 'password' ]
}

Loading UserDetails by username and password in spring security?

I'm pretty new to Spring Security and have run into a problem, hope someone here help:
DaoAuthenticationProvider retrieves a user by username ONLY (when you implement UserDetailsService.loadUserByUsername(String username), but my problem is that our password is hashed on the DB by a DB function, meaning if I retrieve by username, it wouldn't match with the supplied password since what I get from the DB is a hashed version.
How do I go about implementing a solution on Spring Security where I can match both a username and password on the DB side before I retrieve the User object and mark a user as authenticated?
Something like UserDetailsService.loadUserByUsernameAndPassword(String username, String password) is what I'm looking for.
I have a feeling I'll have to cook up my own custom implemenation since I read somewhere that Spring Security never sends the password to the DB. If I do, can someone please point me to the right direction on how to get started?
Any help would be much appreciated. Thanks!
You may write a UserDetailsServiceImpl extends org.springframework.security.core.userdetails.UserDetailsService
override the loadbyusername() method. Read user from db.. Your user will have a hashed password..
On login screen, doAuthenticate user as login(username, hash(password))..
they will match..

what's the best way to check user's current authority in spring3 controller methods?

User's authority is frequently changed in my web service.
In this case, how do I check user's authority effectively?
I wrote code that check user's authority in every controller temporarily.
But I think this way would not good for maintenance.
How do I check user's authority without writing checking method in every controller?
Not sure what you are doing - Spring Security automatically keeps track of authorities in the User's security context. If you need to programmatically check for some other reason, then implement the HandlerInterceptor interface, and in the preHandle method, call SecurityContextHolder.getContext().getAuthentication() to get the current user. You can then check the User's authorities.
The interceptor would be configured as follows:
<mvc:interceptors>
<bean class="com.my.package.MyInterceptor" />
</mvc:interceptors>
Add an intercept-url element to your config with the role that is required, eg.
<http auto-config='true'>
<intercept-url pattern="/**" access="ROLE_FOO" />
</http>
Use HandlerMethodArgumentResolver to let Spring inject GrantedAuthority in the controller method. If a user can have more than one authority then you will need to create a class to hold user's authorities (can be named as GrantedAuthorities). After you are done, your controller method will look something like this:
#RequestMapping({"/xyz"})
public String handleXYZRequest(GrantedAuthorities authorities) {
/* use authorities if not null */
...
}
In resolver, you will use the same code that your are currently using to get authorities and it will return either null or GrantedAuthorities object. If you are using older version of Spring then use WebArgumentResolver and register it with AnnotationMethodHandlerAdapter.
Above approach avoids duplication of code and it can be used to inject anything you need from SecurityContextHolder in controller methods.
Edit
This is similar to the approach used by greenhouse. Please see WebConfig, where principal (which is Account object) is injected in controller through argument resolver.

Grails spring security core, how to set principal manually

Hi im trying to make facebook's login in a grails app, the problem I have is that when the user is logged in facebook, spring security core doesn't recognize him, how can I set the user's principal manually?
I can look for the user object but i don't know how to set it in order to get a true user when i call getAuthenticatedUser() (now it returns a null object)
Thanks in advance,
Regards
Cannot say anything regarding facebook, but Spring Security has a SecurityContextHolder that can be used to manipulate the authentication (and therefore the principal) like this:
import org.springframework.security.core.context.SecurityContextHolder as SCH
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken
....
def securityContext = SCH.context
def principal = <whatever you use as principal>
def credentials = <...>
securityContext.authentication = new PreAuthenticatedAuthenticationToken(principal, credentials)
Maybe you'll need to use a different implementation of the Authentication interface as the one used in the example.

How do I encrypt a string in a Grails domain class?

For example, I created this domain class:
package loginproject
class User {
String name
String password
Boolean state
static constraints = {
}
}
I think it is a good idea to encrypt the password string but I do not know where to start. What algorithm? What do I need to do?
If you need a complete authentication and authorization solution +1 for spring security core plugin. If you just want to encrypt a domain class or parts of it in the DB, go for http://www.grails.org/plugin/crypto.
You can utilize a plugin, such as Spring Security core plugin. And actually, we often save password hash instead of its encryption.

Resources