Spring #PreAuthorize not working in RestController - spring

I have GrantedAuthorities as [admin, player, user]
To test this I have injected Authentication object in method and invoked authentication.getAuthorities().
but when at REST Controller Method I put #PreAuthorize("hasRole('ROLE_player')")I am getting response for my REST web service as 403 forbidden.
I have custom roles defined which I am picking from database. I want to authorize REST call before execution of any business logic.
Tried with #Secured but still not working.

The default prefix for hasRole is ROLE_. If a prefix isn't supplied, spring will automatically add it. Since your roles in your database aren't prefixed with ROLE_ they will not match with hasRole.
// will be checking for ROLE_admin, your role in DB is admin
#PreAuthorize("hasRole('admin')")
You can update your roles in your db to prefix them with ROLE_ or you can alter the prefix spring uses on DefaultWebSecurityExpressionHandler. You should also be able to use hasAuthority rather than hasRole. The hasAuthority will not add any prefix to the supplied parameter.
#PreAuthorize("hasAuthority('admin')")
http://docs.spring.io/spring-security/site/docs/current/reference/html/el-access.html

Related

Spring data rest deleting using id in url is not calling deleteById method

I am implementing Spring Data Rest and my resource has the default delete endpoint of /table/{id} when called with the DELETE method. My repository interface extends PagingAndSortingRepository and QuerydslPredicateExecutor and thus has the following overriden methods for delete:
deleteById(#NonNull ID id);
delete(#NonNull T entity);
deleteAll(#NonNull Iterable entities);
deleteAll();
On calling the above mentioned endpoint I find that Spring is making a call to findById and then calling delete(entity) somehow passing entity as the result of findById. This is causing me trouble with security as this requires the user to have permission over findById, which is permitted to only certain roles, and delete, which is permitted by different roles.
What can I do to tell spring to use deleteById instead when a DELETE method call is made to the deafult endpoint with ID in the path?

Custom principal and scopes using Spring OAuth 2.0

I am using SpringBoot 2.0.5 and Spring Security OAuth to implement an OAuth 2.0 server and a set of client microservices.
In the AuthServer:
I have implemented the UserDetailsService so I can provide my custom enriched principal.
For the userInfoUri controller endpoint, I return user (my principal) and authorities as a map.
In the Client:
I have implemented PrincipalExtractor to extract and create my custom principal.
For each of the methods I require the principal, I use the following notation:
public List<Message> listMessages(#AuthenticationPrincipal MyPrincipal user)
This works (and I hope it's the right way) but now I'm having an issue to secure methods using scopes.
For example, if I want to have a controller method which is only accessible by another server (using client_credentials), I mark the method with the following annotation:
#PreAuthorize("#oauth2.hasScope('trust')")
But this results in an access error as I think the scope is not being transferred. I have added the scope to the userInfoUri endpoint but am unsure what I need to do on the client side so the scope is picked up.
Any pointers or example code would be very much appreciated.

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.

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.

Spring Security #RolesAllowed Works but #Secured gives me AccessDeniedException in Spring 3.2 with Spring Security 3.1

I am having an issue where my Controller method with #RolesAllowed works correctly but if I try to use #Secured I get an AccessDeniedException. While I would prefer to use the #RolesAllowed Annotation it has been declared that for this project we should Use #Secured because the name is less confusing when mapped to our legacy access rights.
I have the annotation configured as follows:
<security:global-method-security jsr250-annotations="enabled" secured-annotations="enabled" pre-post-annotations="enabled" />
When I use #RolesAllowed("COMPANY_SEE_REPORTS") which my user has, it works correctly. When I use #Secured("COMPANY_SEE_REPORTS") I get an AccessDeniedException. Just to make sure #RolesAllowed was working correctly I changed the role to a role that didn't exist and at that point #RolesAllowed threw. So my question is how can I get #Secured to work correctly?
Try to use a security role with a name that ends with ROLE
From Spring Security Reference:
RoleVoter
The most commonly used AccessDecisionVoter provided with Spring
Security is the simple RoleVoter, which treats configuration
attributes as simple role names and votes to grant access if the user
has been assigned that role.
It will vote if any ConfigAttribute begins with the prefix ROLE_. It
will vote to grant access if there is a GrantedAuthority which returns
a String representation (via the getAuthority() method) exactly equal
to one or more ConfigAttributes starting with the prefix ROLE_. If
there is no exact match of any ConfigAttribute starting with ROLE_,
the RoleVoter will vote to deny access. If no ConfigAttribute begins
with ROLE_, the voter will abstain.
But you can modify the RoleVoter prefix RoleVoter#setRolePrefix(String rolePrefix)

Resources