Spring webapp security based on owner of record - spring-security

Let's say I have users and articles.
Anonymous can list and read articles.
Only registered and logged user can create articles.
User can edit only own articles.
And, of course, admin can do anything.
I've looked at spring security, but didn't found a way to do that. My app don't need roles, and ACL will be too "heavy" for that.
Maybe I should implement my own security?

You're right, ACL would be too much for the task.
You can use Spring Security's authorize tag in JSP, which provides access to the logged in user via the principal object. Example to limit access to editing an article to the user with a given username:
<sec:authorize access="hasRole('SOME_PRIVILEGE_OR_ROLE') and ${someArticle.username} == principal.username">
...
</sec:authorize>
Note that SOME_PRIVILEGE_OR_ROLE could be some role like 'LOGGED_IN_USER', but could also rather specify a certain privilege, e.g. 'READ_ARTICLE' or 'UPDATE_ARTICLE'. Spring Security is flexible here. Whatever you choose, it needs to be in the GrantedAuthorities collection of your user object.
Note also that you can implement your own user object, adding further info to what the UserDetails interface provides, e.g. comparing the user's id rather than the username.
Finally, note that you need a recent version of Spring Security (>=3.1) for the Spring EL to work as in the example.

Related

Spring Security Users With Same Name

If two users have same username in the database then how can spring security handle that?
I have two users with following login CREDENTIALS in database:-
1.Username:rohit password:1234
2.Username:rohit password:123
That means the user cannot be unique identified by the username only. So you have to think about the business requirements how to unique identify an user based on the information collected from the user request.
Enforcing the username to be unique across the system can definitely solve the problem. Ask the product owner if it is okay to do it .If not , ask him how to handle such case from the business 's point of view. Then based on the actual requirements of how to unique identify an user , you may need to customise the following classes (Assuming you are using the default username and password login form and authenticate against the user records from DB using JDBC) :
UsernamePasswordAuthenticationFilter
DaoAuthenticationProvider
UserDetailsService

Spring Security - How to check user has access to his own resources?

In Spring Security we can have roles but this is not sufficient for my case. For example if User A log in he can't view/change User B's data and both users will have same role like ROLE_USER. Is there any built in mechanism for this in Spring Security ?
You can add method level security in that you check if that user with ROLE_USER can access particular resource with help some expression as given here
And configuration can be done as given here

Using Spring Security authorization with context-specific authorities

We need to add access control to our application, making sure that every command is performed by a user who has the proper authorities for the given domain objects. We are already using Spring Security 4.0 for authentication and intend to use it for authorization as well.
What makes this complex is the way that authorities are granted to a given user. In our problem space, a User can found several Companies and hire other Users, making them Employees. Each User can be an Employee of several Companies. Some authorities can be granted to a User directly (e.g. canResetOtherUserPassword); other authorities can also be granted by a Company to an Employee based on their Role in the Company (e.g. canOpenProject, canRenameProject). When performing Company-independent commands, User-specific authorities must be checked by the service layer. When performing Company-specific commands (e.g. open a project for a company, rename an existing project), Employee-specific authorities must be checked.
Now let's consider these last two commands, which would have the following service signatures:
long openProject(long companyId, String title)
void renameProject(long projectId, String title)
To control access for the 1st method, the authorization component could retrieve the acting User through the thread-local SecurityContext.authentication, retrieve the Company using the companyId parameter, retrieve the Employee corresponding to the current User, then match Employee-specific authorities against the required canOpenProject authority.
To control access for the 2nd method, the authorization component could again retrieve the acting User through the Thread-local SecurityContext.authentication, retrieve the Project using the projectId, retrieve the owner Company through project.ownerCompanyId, retrieve the Employee corresponding to the current User, then match Employee-specific authorities against the required canRenameProject.
Clearly, this can be done using procedural code, as I just described. We would prefer to use a declarative approach similar to the #PreAuthorize interceptor that Spring Security already offers, and obviously to write as little code as possible. We just don't know where to start.
Any ideas?
Thanks in advance!
You can implement UserDetails (org.springframework.security.core.userdetails.UserDetails) or just extend a default implementation of UserDetails, like User (org.springframework.security.core.userdetails.User) ---> CustomUserDetails with additional attributes like company (with getters).
finally : use simply #PreAuthorize("principal.company.companyId == #companyId")
Reference : Spring Security 3.1 chapter 10 (you need to go back to chapter 3 for UserDetails implementation)
It was very useful for me !

How to handle dynamic roles changing in Spring security?

Suppose in one application we have interface(UI) to assign roles.
First scenario:
So to say user A who is normal user. And one admin assigns him ADMIN role using UI.
Now when user A logins the application then he can see all the tabs which can be accessed by ADMIN.
Second scenario:
In the same time (when he is logged in and have session with ADMIN role), admin makes user A as normal USER who have normal privileges.
But as he is login as ADMIN so he can access all the admin information for all the tabs as in this session he has ADMIN role.
How I can solve this problem??
The first approach would be to expire any existing user sessions on the on the fly.
the following post describes two alternatives Is it possible to invalidate a spring security session?
A more sophisticated approach would be to flag the use in a list when his authorities changes.
Here is a good example Implementation of singleton thread-safe list
Furthermore, if you add a custom spring security filter which checks if the user is in the list and if necessary reauthenticates the user. I would use the switchuserfilter as a reference implementation. Instead of switching a user, you create a new authentication object and update the SecurityContextHolder.
All the necessary logic should be included in http://docs.spring.io/autorepo/docs/spring-security/3.0.x/apidocs/org/springframework/security/web/authentication/switchuser/SwitchUserFilter.html

Remember me in Spring security to remember only user-name

I am using Spring security in my application and wish to know if there is a way to "ask" spring to only remember the user-name of the user that comes to the application (by means of the remember-me checkbox).
What I could gather from the reference documentation is that Spring is able to save the userName and the password of the user, and directly log him/her in the next time. But what I want is that user be taken to the login page each time he comes back, but with his user-name already typed in.
Ofcourse if Spring doesn't have a way to do this, I would need to implement some cookie storage logic to take care of this requirement.
Many thanks for your answers as always.
So, you need to set a cookie containing the user name after authentication, and access it during rendering of the login page.
If you use Spring Security 3.x, the former can be done by subclassing AuthenticationSuccessHandler (SavedRequestAwareAuthenticationSuccessHandler is the default implementation) and setting a cookie with response.addCookie().
The latter is a regular cookie access (request.getCookies(), etc).

Resources