What are the advantages to get principal as a parameter Principal principal in spring controller and then pass it to service layer over getting principal in the service layer immediately though SecurityContextHolder.getContext().getAuthentication().getPrincipal() ?
What is the best approach to get principal details in service layer without checking getAuthentication() and getPrincipal() objects for null everywhere (something like a custom wrapper)?
Your service API will be more easy to use. You will see dependency on principal directly, so you wan't call some service method by mistake in environment where principal does not exist.
In general less dependencies on SpringSecurity code means less problems in a case of migration to new Spring Security version.
You will be able to reuse your service layer in environment where Spring Security does not exist.
Prepare some wrapper class (for example AuthenticationService). Add getPrincipal() method to it. Implement your checks. Inject AuthenticationService everywhere insted of direct calls to SecurityContextHolder.
Related
I would like to ask if there is a point to secure the methods which I call in a REST Controller with Pre and Post annotations. I have configured a security through java configuration like this:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.and()
.formLogin()
(...)
.and()
.authorizeRequests()
.antMatchers("/api/**").hasAuthority("ROLE_USER");
}
So every request under /api should be authorized with ROLE_USER. I tried to find some information about this in the internet but the only thing i could find was this:
https://coderanch.com/t/549265/Spring/method-security-spring-security
However I really can't think of a use case where a hacker would access somehow the methods in the service layer.
URL security and method security in service layer aims at different use cases.
If all you need is control that only users with a certain role can call URL with a given prefix (here API) URL security is what you need full stop.
If you have a complex application where some service methods can be called from different controllers and you want to make sure that you did not fail to restrict an access, method security can come to help by ensuring that only valid users can do certain business actions.
If you have a complex security model, for example several officse with one manager in each that has read and/or write access to his own employees data, method security on service layer directly using business model objects is the way to go.
BTW, using method security in a controller or even worse on a rest controller is generally design smell: if you can do it inside a controller it is generally better to use URL security. If it seems to make sense, you probably have imported business logic into a Fat Ugly Controller. Not speaking about method security being implemented with Spring AOP using by default JDK proxies, when controllers generally do not implement interfaces.
In addition to making it possible to have some kinds of functionality, using both techniques gives an additional layer of security.
Method level security is used to authorize the user. Spring security performs two basic operations before allowing the access.
Authenticate (Who is the user)
Authorize (What authorities the user has)
so for example if the user is having an authority of ROLE_USER and later in the architecture you decide to have rights assigned to some of the roles.
for example let's consider a role 'ROLE_USER'
and following rights has been assigned to the USER
CAN_VIEW_DATA
CAN_ADD_SUB_USERS
and so on.
so when some of the users have the right of CAN_ADD_SUB_USERS and some dont, then the method level security comes in handy.
Of course you have to play with the spring configurations for the rights and authority. But Once configured it provides an extra level of security that the applicaton might need.
Refer to this link for more info http://www.baeldung.com/role-and-privilege-for-spring-security-registration
REST is stateless. You should send something like access token (like Google API) with every request:
https://{server}/api/customers?access_token=BGhznFGDS
You can also send this information via Header-Attribute. The validation layer (Filter) decides whether the controller method may be called or not.
I prefer to implement my own Filters to get 100% of control.
I have a REST service implemented using Spring MVC (RestControllers) with token based security (using Spring Security). How can i filter resources depending on user identity? Let's say user has some reports. How can I let authorized user by performing a call to /reports to see only his reports?
Obviously i can make userId to be a request parameter or path variable, but something tells me that this is a bad practice.
I assume i can achieve that using Spring Security features, but how exactly could i do that and, more important, where is the most appropriate place to apply such filtering? Should controllers perform calls to services passing user identity or should it be somehow retrieved at repositories level (I use Spring Data JPA)?
Thanks in advance
You have Authentication object whenever a user is successfully logged in.
It contains Object principal Object credentials and Set authorities.
All you need to do is override UserDetailsService to add new parameters for your authenticated user. Add your userId in authentication as shown in blog
Now when you do
SecurityContextHolder.getContext().getAuthentication().getPrincipal()
this will return you the User object of the spring security.
You can get the user id from here and use this in controller to do necessary actions.
I am trying to implement service to service security into spring boot services using spring oauth2. I want a service to access a secured resource of another service without any user action involved.
There are a lot of examples for authorization code grant type, but not very much about the client credentials grant type, which seems to be the right one for this use case.
I can set up the auth server and use a curl request to get a token.
The tests I found used Http Objects to check status codes.
How can I use the client credentials grant type in a java client with RestTemplate and spring oauth2?
I would think it must be as simple as adding a dependency, an annotation and a config file, yet I can't make it run.
It's quite simple:
Create a Config class which is annotated with #Configuration.
In this class, create an instance implementing the interface OAuth2ProtectedResourceDetails and create a ClientCredentialsResourceDetails instance in that method. Add your values to it and return it.
Create a second instance of type OAuth2RestTemplate in the Configuration class and create in that method a DefaultOAuth2ClientContext instance by calling the default constructor. Then create an OAuth2RestTemplate and add the OAuth2ProtectedResourceDetails instance and the DefaultOAuth2ClientContext instance to it. Subsequently return the OAuth2RestTemplate instance.
Add it with #Autowired in both your Controller and Service instances to use it.
For our current project, we are integrating JSF and the Spring Framework. I'd like to use Spring Security to handle authentication and authorization. So far, I have implemented a custom PasswordEncoder and AccessDecisionVoter which are working fine. Now I'm trying to secure methods using the #Secured annotation (among others) but I can't get that to work as I would expect it to do.
It seems that the #Secured annotation works for bean methods called directly from the JSF layer, only. Here's a simplified example:
#Named("foobarBean")
#Scope("access")
public class FoobarBean
{
#Secured("PERMISSION_TWO")
public void dummy()
{
}
#Secured("PERMISSION_ONE")
public String save()
{
dummy();
}
}
The method save() is called from the JSF layer like this:
<h:commandButton id="save" action="#{foobarBean.save}" />
Our AccessDecisionVoter is then asked to vote on PERMISSION_ONE but not on PERMISSION_TWO. Is this working as designed (I hope not) or am I doing something wrong (what could that be?).
I'd post more code or config but I'm not sure which part is relevant, and I don't want to clutter this post.
It is a simple problem of Proxy AOP! If you use Proxy AOP for Security, then the Proxy can only intercept calles that go through the proxy. If one method invoke an other method of the same bean directly, then there is no proxy that can intercept this call. -- And this is the reason why only the the Security Annotation of save() is taken in account.
One solution would be using AspectJ AOP instead of Proxy AOP. (It is supported by Spring (Security) too.)
Yes, That is how the AccessDecisionVoter works. It takes all roles allowed on a resource(method in your case) and vote for those roles form the current authenticated user's role. If the Role is matched, then only the permission is granted.
In your case also, the only Role defined for the save method is PERMISSION_ONE so the security system will check against this role only. If logged in user has that role, this method will be executed.
I am trying to create various services, such as:
UserService
UserPermissionService
AddressBookService
Which would access dao's such as:
UserDao
UserPermissionDao
AddressBookDao
CompanyDao
These will use Spring-Hibernate stack and be packaged in a backend jar for multiple webapps. I want the service functionality to be available depending on the permission of the calling user object. Also, Caller (user) object will have permissions of the calling user.
Query: Should I pass Caller to each Service method call and then check its permission? Or is there a better way using 'Spring/AOP' and/or 'Factory Pattern' where the Caller object can be available to the Service methods.
One of the patterns for this case is to store security token in a ThreadLocal and to require corresponding privilege from that token first thing in a service method.