Spring Security: Creating multiple entry point for securing different rest controllers - spring

I'm exploring the Spring framework, and in particular I am working on a Cinema Management Application that will be connected to a React.JS SPA (Single Page Application).
The problem is the following. On my database I do have three different tables representing three different types of users, namely Admin, Customer, and Cinema_Employee.
For each type of user, I created a #RestController with a list of RequestMethods that a particular user is able to perform:
"/admin"
"/customer"
"/employee"
What I am trying to achieve now, it's to secure each endpoint offering three different login pages that will handle the authentication the respective type of user.
How can I set up three AuthenticationManager that handle different Authentication objects within a SecurityConfig class given these requirements, and most importantly, how can I override the Authorisation mindful that each user once has logged in, will have access only to the respective endpoint?
I looked carefully at other examples online, and most of them are radical different, following a pattern where the database has another additional 'Authorities' table aside the 'user' one that stores the credential. In my case this solution cannot be applied, not only because the whole design would become redundant, but also because the name of the table where the application will perform the authentication check against, explicitly imply the authorisation that a given user has inside the system.

Your design sounds strange to me.
A user should have a role, e.g. Admin, Customer, Employee and based on the user's role he gets access to methods or not. Have a look at role based access control concepts. For Spring Security there is for example this tutorial:
https://www.baeldung.com/role-and-privilege-for-spring-security-registration

Related

Spring security user based permission? (not role based)

Assume I have a database composed of user and projects. A user has a one to many relationship with projects. The user can do operations using rest endpoints.
The problem is:
how can I verify that this user owns this resource?
I don't want a malicious user to change an id then suddenly he views another person's project details/images/etc. Think of it like a social media (my app is not a social media but trying to illustrate the issue): where you can view only your images but not another person's images despite having the same "status".
Most spring-security blogs online is using a role based approach. I have no idea what to even search for in this case (tried multiple search queries to no avail).
One option is to run some sort of multijoin query on every resource request/operation till I reach that resource id and check it's owning user to check if it is the logged in user. However, I am not sure if this way is efficient since there are multiple tables in a chain in the real app (could have a lot of joins if I go this way manually; example: user -> project -> tasklist-> ... -> Note; deleting a note would trigger a large chain) or how to make the "authorizer" use it.
what are my options?
In case it matters:
I am using spring-boot + hibernate/JPA + spring-security
Spring Security has the following concepts:
Authentication:
Proving the an actor is who it vouches to be. Authentication is done using credentials, where credentials can take any number of forms - username/password, token, hardware key, etc.
You can set up Spring Security with a set of acceptable authentication providers.
Authorization:
Given an authenticated user, deciding if that user has access to a given resource. Where the resource can be:
An HTTP endpoint.
An Java Method.
A property of an object.
What you want to do here is provide a custom authorization scheme.
You can read about Spring Security's authorization architecture here, including how to set up custom authorization. Once you're ready you might ask specific questions as you go.

Separate access in one app with keycloak

I have the following setup - the Spring SAAS REST service, which allows different companies to manage different events. And there is a rest client (a mobile app) also, shipped separately for each company.
I want to use keycloak for security stuff, and I have a question of how to separate one company from another.
I need companyA to not be able to access companyB event, and also need different roles within the company - some can create events, some can only read it.
First I thought each company will have own realm created in keycloak, but I learned that realm actually specified in the spring boot REST service parameters like
keycloak.realm=demo-realm
Which means it is only one realm per REST application. And I don't want to configure REST service instance per client. I only want one REST rule them all.
Am I trying to use something which really doesn't fit my use case?
Will it be right way to have a keycloack Group configured for each company, and make a logic in such a way that users of one group won't have access to what is created by other group. But then it actually feels wrong, since as I understand group are supposed to be used in a different way - to have admin group and user group, etc, segregating users "vertically" by "privileges", and not "horizontally".
Can you please suggest a right approach for this problem?
I would implement a custom protocol mapper which loads extra user permissions for your application and stores them in a token. This way, you use a single realm and if there are more companies in the future it scales well. Here you've got an example of how to implement it.
Basically, the otherClaims field of the access token is a JSON field that allows a map of properties to be set. You could add a field here such as:
userAccessibleCompanyIds: [1,3,4]
How to load the company ids for the concrete user? You can access your application database from the mapper or get them using the REST API.
Then in your application you need to have a control of what the user accesses. What I do is decode the token and see if the user request suits. If not, return a 403 response.

Role based access to service methods using spring and mongodb

I have a requirement where I need to use role based access to service methods. I have restful services and i use spring-data to interact with MongoDB.
There are some of the restrictions that I have. I deal with a document in DB called "Organization". In each organization, I know who are the Admins. I do not have a repository of users who can access the services.
So the only way I can enforce some access based rules is to check if the logged in user is one of the admin's configured for each organization and then allow the user to access the methods.
Should I think of applying Spring security in this case? Otherwise will a simple check on user against the configured admins in the database document help? Can I make this check at a single point so that I can apply it to service methods based on my use case needs.
Please provide your suggestions / thoughts on how to go about this.
If you use Spring Security your rest methods can take advantage of a passed-in authenticated Principal object (example here) whereupon you can do whatever extra validation desired (such as checking if the admin is good for the given organization requested, etc.) There are many other parameters also available, perhaps allowing for this org checking to be done once and stored in the session object.

ASP.NET MVC3 / User registration, membership, roles and privilege

In my application I need to register users. The users can be any of three: admin, client and general. They have different attributes (Admin may have only name, client may have company address and so on). The default MVC membership scheme is okay but how can it be extended to register more information during registration time? Or should I use custom membership?
I need to have a record of clients and general users with clientID or generalID.
The default MVC membership scheme is okay but how can it be extended
to register more information during registration time? Or should I use
custom membership?
I think too many people, yourself included, are expecting to get too much from the default ASP.NET Membership Provider. It was never designed to handle application-specific things, like what company your customer works for, your admin's name, and so on. It's main purpose is storing passwords for authentication.
Sure, the password needs to be linked to a username, so that there can be a 2-key authentication pair. Sometimes you also need the user's email address, when it is different from their username, in order to contact the user regarding their password. But don't store anything else about your users in the membership store. Store it in your application database.
In order to join data between your application and the membership provider, use the membership provider's UserName or ProviderKey as a column in one of your database tables. You end up with 2 entities which are not explicitly related. You can even have your SqlMembershipProvider implemented in a separate database from your application database. Even if they are in the same database, avoid having a foreign key between any of the provider tables and your application tables. This muddies the waters between what you own, and what you "outsource" to the membership provider.
You end up with 2 physically isolated representations of your user. One is the MembershipProvider, which contains a password for your user. The other is your application, which contains other business-specific details. The two are only logically associated within your application. After you authenticate a user with the membership API, their UserName and/pr ProviderKey become available to your application. You can then use that piece of data to query your app database and get the additional details. This is where you might put something like the clientID or generalID you mentioned.
If you look at the System.Web.Security.Member* API, this should make things clearer. It does one thing really well -- associating your users with passwords and other information related to password resetting (like the email address, question and answer, etc). So outsource just the password provider, and rely on your application to do the important stuff.
You could customise the default profile provider or create your own... Follow this reference
http://msdn.microsoft.com/en-us/library/8zs47k7y
You can add new properties to the profile for anything in the web.config too
I highly suggest creating your own membership roles. It's dead simple and nothing can beat the flexibility of having your own implementation.
Here's a video I made a while back showing you step by step how to achieve this:
http://www.youtube.com/watch?v=BsxUsyMSGeA
The gist of it is, you create your own AuthorizeAttribute and create your own roles; protecting each controller or even individual Action methods along the way.
The one drawback of this approach is that you can determine what Role a user has in your system, but not what a Role can do in your system. Does that make sense?
There are other choices if you need to edit what a role can do at runtime.

Spring Security and the Proper Way to Verify that User has Access to a Resource

I'm using Spring Security which works great to make sure that a user has a certain role before accessing a resource. But now I need to verify something a little different:
`/product/edit/{productId}`
What is the best way to verify that the logged in user "owns" productId? My business mappings handle the relationship (a user has a list of products). I need to verify this product belongs to the user and hence, they can edit it.
I know how to gain access to productId and the logged in user in both the controller and an interceptor. I don't believe this logic belongs in the controller at all. The interceptor seems better but I wondered if Spring Security had an "accepted" way of handling this situation.
Yes, in Spring you can implement this by implementing Access Control Lists. ACL declaration specifies permissions for individual objects per user. Once you have everything setup like acl entries in your database and logic, you can use SpEL and #PostFilter annotation to control the list of objects returned to a user.
Spring Security Documentation
Related:

Resources