Cas and Spring example: I don't understand "setUserDetailsService" - spring

In this example: https://www.baeldung.com/spring-security-cas-sso
there is this piece of code:
#Bean
public CasAuthenticationProvider casAuthenticationProvider() {
CasAuthenticationProvider provider = new CasAuthenticationProvider();
provider.setServiceProperties(serviceProperties());
provider.setTicketValidator(ticketValidator());
provider.setUserDetailsService(
s -> new User("casuser", "Mellon", true, true, true, true,
AuthorityUtils.createAuthorityList("ROLE_ADMIN")));
provider.setKey("CAS_PROVIDER_LOCALHOST_9000");
return provider;
}
I don't understand this part:
provider.setUserDetailsService(
s -> new User("casuser", "Mellon", true, true, true, true,
AuthorityUtils.createAuthorityList("ROLE_ADMIN")));
what are we supposed to put here ? Am I supposed to create my own UserDetailsService (if yes, how ?) ? I was expected some 'default cas user detail service'...
how does this code work? creating a user to provide a UserDetailsService ?

This is how Spring security works on high level.
User tries to authenticate via some type of UI (part of CAS for example). The UI will pass username/password to Spring. Spring will eventually call UserDetailService.loadUserByUsername and pass the username to it, and if user exists the UserDetailService will return non null UserDetails. In case of null UserDetails or non null one with different password Spring will fail authentication.
CAS is just an authentication server, it leaves open how user is stored. You can choose to use LDAP or database. That choice is based on different implementation of UserDetailService. Look at javadoc again. It has list of default implementations you can use.
See part 5 of your linked tutorial. It shows how you can change both CAS and Spring Boot app to use database as user storage. The key here is that in order for back end to work with CAS server against users stored in database both need to be configured appropriately in order to look up user against database. CAS is configured via application.properties and Spring boot via UserDetailService.
Now to your questions in the comment:
why should the client bother about how cas server store the users ?
Client should not bother with UserDetailService. It is only used by back end service that is secured by CAS.
Just to be sure that I get it tight: if I just need to know 'is that
user connected?' then CAS is enough and I will never use
UserDetailService. But if I need some information about the user
(name, telephone etc..) then I call the UserDetailService to load it
(from db, ldap or whatever).
Yes and no. You dont need to store password in UserDetails but you need to be able to return UserDetails for successful CAS authenticated user. See this part from your linked tutorial:
Note again that the principal in the database that the server uses
must be the same as that of the client applications.

Related

Spring JDBC Authentication vs LoadUserByName Differences

Im new on spring security and I had some research on authentication ,I saw two options there are some guys posted.First one Jdbc authentication or In memory authentication ,and there are also loadUserByName(UserDetailService).
what is difference between them ,and also what is use case of loadUserByName (UserDetailService)
This is the official reference https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#jc-authentication
For In Memory Authentication, you have a set of username-password pair hard-coded in your xml/java config class.
In jdbc authentication, you can have a direct database contact to fetch users and authorities, provided you have configured a datasource
You can define custom authentication by exposing a custom UserDetailsService as a bean. You can do whatever functionality to return an instance of UserDetails in loadUserByUsername(). This method is called implicitly to authenticate a user, when creating an authentication.

Using/configuring Spring Security with Spring 4 and Hibernate

I want to implement the login/logout (authentication/authorization) system of my Spring 4 MVC application with Spring Security.
Currently I use a very simple hand-made implementation which basically does nothing more than comparing the entered username and MD5 hashed password with the database values by looking up the user by the username using a custom service method and comparing the encrypted passwords.
If the passwords match, the username of the logged in member is saved in the session and a ControllerAdvice looks up the Member object for the user using the username in the session prior to each request. The checkLogin method returns true is username and password match:
#Service("loginService")
#Transactional
public class LoginServiceImpl implements LoginService {
private MemberDao dao;
//more methods
#Override
public boolean checkLogin(String username, String password) {
String hashedPassword = getPasswordHash(password);
return dao.checkLogin(username, hashedPassword);
}
}
This does work but is not a very elegant solution, does not handle different roles and is probably not very secure. Besides I want to become familiar with Spring Security.
Reading the official tutorial for Spring Security (http://docs.spring.io/spring-security/site/docs/4.0.4.RELEASE/reference/htmlsingle/#tech-userdetailsservice) the way to go to authenticate against the Login service method does not become clear to me.
The tutorial discusses authentication direct against the database but I cannot find anything about using a Service method to perform the authentication and in my layered architecture, the database is hidden behind the Servoce and Dao (Hibernate) layers.
Also most examples in the tutorial use XML based instead of Java based configuration which I use for my application.
After having search a lot with search engines, I still have not found a tutorial which implements Spring Security in a Spring MVC application using a familiar layered structure using a Service and Dao layer.
Do I need to bypass Service and DAO/Hibernate layers and authenticate directory against the database? Or write a custom authentication-provider implementing UserDetailsService as described in this post?
Spring Security 3 database authentication with Hibernate
And is configuring Spring Security possible with Java based configuration only? I am a bit lost with this issue so I hope for some hints...

get user role in resource server from authorization server

I have an authorization server which on the basis of username and password fetches the user details from the DB along with the roles.
Now while accessing the protected resource in the resource server (passing the access_token), I want to authorize the rest call on the basis of role.How do I do that ?
Because, while I am checking the Principal user in resource server, its getting the default [ROLE_USER]
//Will #preAuthorize() work here ?
#RequestMapping(value="/pinaki", method=RequestMethod.GET)
public String home(Principal principal) {
return "Hello World";
}
Please guide..Thanks in advance
AFAIK spring-security-oauth2 only supports getting the user details (including roles) for a Authorization Server/Ressource Server that share a common data store (either database or in memory)out of the box.
If you do have a common data store you can use the InMemoryClientDetailsService or JdbcClientDetailsService.
However it should not be too hard to extend this by yourself if in your setup there is no common data store. The key interfaces for this task are ClientDetailsService and ResourceServerTokenServices.
A ResourceServerTokenServices implementation returns a OAuth2Authentication including roles. So you could call the tokeninfo endpoint from the authorization server here.
Implementing a ClientDetailsService and using that would be more elegant. Here also you would need to call the tokeninfo endpoint.
In XML configuration you can setup the beans to use in the oauth:resource-server tag in the parameters token-services-ref and auth-details-source-ref.
Details on the Java config can be found on page http://projects.spring.io/spring-security-oauth/docs/oauth2.html
(My info refers to version 2.0.8 of spring-security-oauth2)

Spring Security, Customizing Authorization, AccessDecisionManager vs Security Filter

I'm going to implement a custom authorization based on ([User<-->Role<-->Right]) model and Rights should be compared to controller and method name (e.g. "controller|method").
I used customizing UserDetails and AuthenticationProvider to adjust granted authority (here), but as checked source codes and docs about how customizing the compare of authority I found there is a filter SecurityContextHolderAwareRequestWrapper) that implements isGranted and isUserInRole to compare authority, while the documents say using AccessDecisionManager voters to customize (As I understood). Which one should be used ? Where I have controller and method(action) name to compare authority with them ?
I got confused about Spring security a little. Is there any other resource than official docs that illustrate how it works, I mean sequence of actions and methods and how customize them.
There are several approaches:
Role based, where you assign each user a role and check the role before proceeding
Using Spring security expressions
There is also a new spring acl components which lets you perform acl control on class level and are stored in a database.
My personal usage so far has been 1 and 2, where you only assign roles to users.
But option 3 allows you to create finer grained security model, without having to rebuild your webapp when chaning the security model
Role Based
A role based security mechanism can be realised implementing the UserDetailsService interface and configuring spring security to use this class.
To learn on how to such a project can be realized, take a look at the following tutorials:
Form based login with in memory user database Link
Form based login with custom userdetails service Link
In short spring security performs the following behind the scenes:
Upon authentication (e.g. submitting a login form) an Authentication Object is created which holds the login credentials. For example the UsernamePasswordAuthenticationFilter creates an UsernamePasswordAuthenticationToken
The authentication object is passed to an AuthenticationManager, which can be thought of as the controller in the authentication process. The default implementation is the ProviderManager
The AuthenticationManager performs authentication via an AuthenticationProvider. The default implementation used is the DaoAuthenticationProvider.
The DaoAuthenticationProvider performs authentication by retrieving the UserDetails from a UserDetailsService. The UserDetails can be thought of as a data Object which contains the user credentials, but also the Authorities/Roles of the user! The DaoAuthenticationProvider retrieves the credentials via its loadUserByUsername method
and then compare it to the supplied UsernamePasswordAuthenticationToken.
UserDetailsService collects the user credentials, the authorities and builds an UserDetails object out of it. For example you can retrieve a password hash and authorities out of a database. When configuring the website url-patterns you can refer to the authorities in the access attribute. Furthermore, you can retrieve the Authentication object in your controller classes via the SecurityContextHolder.getContext().getAuthentication().
Furthemore to get a better understanding of the inner workings of these classes you can read the javadocs:
UserDetails - how the user credentials are stored and accessed
AuthenticationManager.authenticate(..) - contract on how AuthenticationExceptions are handled
UserDetailsService.loadUserByUsername(..)- contact on how username lookup failures are handled, e.g. user does not exist
Spel
Instead of checking authorities, SPEL enables you also to check other properties of a user.
You can use these in the URL patterns, but also annotate methods with #Preauthorize.
This way securing the business layer is less intrusive.
ACL Based
The ACL based model was introduced in spring security 3.0, but hasn't been well documented.
Their suggestion is to look at the Contacts XML example, since this one uses their new acl component.
Last this book contains great examples on how to further customize your security wishes.

How can I get the user information using Spring Security with LDAP

Im using Spring 3.1.1 with Spring Security 3.2.0 with LDAP authencitation.
I have gotten it to a point that works fine and I can log in using my LDAP username and password, I can even display the username with this
<security:authentication property="principal.username" />, is currently logged in.
I want to know how, if at all possible, can I get the first name, surname, email address or other information like that stored in my LDAP credentials.
I've tried property="credentials" but this returns null...
PLEASE HELP!!
This is eerily similar to my question a few days ago:
How do I use a custom authorities populator with Spring Security and the ActiveDirectoryLdapAuthenticationProvider?
If you're not using Active Directory, you can simply extend the LdapAuthenticationProvider class and override the loadUserAuthorities method, in which you can capture the relevant user information based on the LDAP attributes for the user:
String firstName = userData.getStringAttribute("givenName");
String lastName = userData.getStringAttribute("sn");
//etc.
You can store these wherever or however you like, and you're only limited to the attributes available via LDAP. Then, you'd have to specify your LdapAuthoritiesProvider in the appropriate bean (ldapAuthoritiesPopulator, if memory serves).
I believe the above will work for non-AD LDAP, but you'll obviously need to test it to be sure. I recommend the LDAP browser for Eclipse provided by Apache Studios, if you're not already using it.
Implement your own UserDetailsContextMapper and load LDAP user properties into the UserDetails object
http://docs.spring.io/spring-security/site/docs/3.2.x/reference/htmlsingle/#ldap-custom-user-details

Resources