Store Roles and Permissions in backend to reduce database calls - c#

Let's suppose we have 3 microservices, one of them is the identity server. When the user login, we create a token and get his roles and permissions after validating the credentials (obviously).
So, every time the user accesses/calls the API from the other 2 microservices, we don't want to make a database call based on the token to check whether the user has access/permission for the particular API or not. Also, we don't want to store the roles and permissions in session as there could be thousands (suppose 50000) of user login in at the same time.
Can anyone suggest a solution to reduce the database call in the .NET backend only?
I thought of creating a txt file by the name of token or username and storing the roles and permissions for that user and retrieving them when required. If the token expired, will delete the txt file and create a new one with the new token name.
But I think this is not the correct way to code for major projects. So, looking for good and effective use of DOT NET features.

Related

Storing logged user on asp net core 2

I need suggestion about storing logged user.
i have front application and we are using token for authorization, I check that token on some authentication server, then I got user from db to do some extra checks for access rights..
But somewhere I need that user again (like to log some changes that he did), and I need advice, is it better to every time get user's email from token, then need to ping database or it's better to make same global variable and to get it when I need.. I know that second approach is faster, but is it good one?
When you authorise a user using token, the best way is to add this to the ClaimsPrinciple (claims). Then you can be able to access it using Identity.User

Does the ASP.NET-Core application hit the database anytime it requires access to claims?

I'm about to make a decision on whether to use claims or session for some items that would require frequent access in my application but I am concerned about performance.
That is why I want to find out whether the application will always query the database to get the claims of a given role or logged in user anytime such is required in the application or is there a way the ASP.NET-Core application stores claims in a way that it does not require to always query the database to retrieve claims for a currently logged in role or user.
I'm in a dilema to rather store the items in session for the sake of performance. If that is the case, is there a downside to using session instead of claims to store items that would be needed as long as the user is logged in to the application?
Guidance please
"Claims are the user data and they are issued by a trusted source. If we are working with token-based authentication, a claim may be added within a token by the server that generates the token. A claim can have any kind of data such as "DateOfJoining", "DateOfBirth", "email", etc. Based on a claim that a user has, a system provides the access to the page, which is called Claim based authorization". So using claims does not represent any additional effort in accessing the database.

Managing permissions on RESTful service

I am working on an SPA application using angularjs and Web API. I've been working on setting up user permissions for the resources on the api.
Since the api is a RESTful service, I'm not sure the best practice to store/retrieving the permissions. The permissions in my application can change somewhat frequently, as users have different permissions for different companies they belong to. The user can change their company on the fly in the application.
The way I have is solved currently, is when the user logs in, the application stores a claim for every permission the user has, for all companies. The claim is stored with permission name and company id concatenated together. Then I have an attribute that accepts a permission name. Then I concatenate that name with the selected company id in the app and see if it exists in the claims. If so, they have access.
Another option I see is to only store only pertinent user info in claims (user id, name). Then do a lookup every time I need roles or permissions. A drawback here is there will be a lot of traffic since I need that information on almost every api request. Also, since I have the authentication and resource server separated, it's not a simple lookup. I'd have to go over http to get the data.
Are these my only options or is there a better way to handle this?
You want to use Bearer Tokens to solve this problem. A bearer token is essentially an encrypted JSON string, that can contain all of the claims for a user. In your case, I recommend a having separate claim for every company/permission combination.
Bearer tokens are created on the server, and the exact technique you would use to generate one depends on the server technology/framework you are using.
Your SPA will send the bearer token with every request (take a look at $HttpInterceptor service to accomplish this). At the server, your service will decrypt the token, and use the claims information therein to verify whether or not the user has permissions for the given endpoint.

SQL login technique for authentication

I have a very basic question and want to know how other experts do this
I have an application with some 100s of users. I have been using SQL LOGINS to authenticate these users. These users have password policy enforced. and I face difficulty when any user's password is expired i.e. i have to reset it from SSMS myself. It sometimes becomes a difficult job along with other tasks that i do.
I was told by some experts that it is a good practice to create my own user table and have all the user details in that table. I have created a user table with following columns.
User Id
User Name
Password
PasswordCreationDate
PasswordExpiryDate
PasswordActive
One simple question. How do my users connect to the database . Offcourse i would need a connection string from the application. That connection string would require a user name and a password isn't it? and I can not get the information from the user table until and unless i am connected to the database.
Another problem, how do i keep track of last 5 password. The policy says that the user can not use any of the last 5 already used passwords.
All this can be avoid if I can get a solution of notifying my users that their Password is due to expire in 'n' days and they must change it before it expires.
What do the other developers do when authenticating their users. Please Guide Me
If you keep your user's login credentials in the database, then for access to sql server itself you may only need one login for the entire app. This login would have full access to your database, because it would be up to your application to enforce access rights.
If you go this route, you need to be aware of two things:
There is still a security concern for larger applications that need to give ad hoc reporting capabilities to users through tools such as Reporting Services, Crystal Reports, Infomaker, etc. In this case, users can use these reporting tools to gain read access to areas of the database they should not be able to see.
If you store your own credential information for your users, you need to make sure you do it properly. That means no plain text passwords. You need a cryptographically secure password hash (not md5!) and a per-user salt. If that's greek to you, best to leave this alone.
Another option open to you is to use Active Directory/Windows Authentication for your database. The trick here is that you still have to set up access rights for all your users. However, you can use Active Directory groups for this to reduce the number of logins you need to create, and it will at least prevent you from needing to reset Sql Server logins by hand, because users will log in with their Active Directory account.
A pretty common scenario amongst web applications is to use one username/password (so only one sql login, typically some kind of dedicated login with minimal rights for the application). This way, connection pooling can be used. This is of course a backend account, configured in the web.config and not visible to the end-users.
The users are maintained as a type of data within the application. Asp.net comes with a solution that is called Membership. User authentication is done against the Membership provider and several classes give you programmataic support for authentication, roles, etc. You can use AD as a provider for example, or forms authentication. Or you can write your own.
Since you are now using a dedicated sql login for each user, you need to be aware that this approach moves data access security to the application level. So this might not always suit your needs.
Ideally you'd use existing Active Directory infrastructure to handle your authentication/authorisation of individual users, and you could then have end-users' credentials passed via the web server to your SQL server (You'd probably need to look into handling the Kerberos "double-hop issue" to effect this).
But failing this, it's easy to set up so that the application it self has a SQL login to access the database in order to retrieve user level authentication information. One-way hashes on user passwords would ensure that even if the app's password is read from connection string, user passwords can't be obtained.
Or somewhere in between those two solutions, where the application has a service account within AD, which has access to the SQL database, in order to retrieve the user account info from within the DB.
Either way, if AD is available you can secure further with Kerberos Service Point Names to ensure database access from only your expected end-point (ie the ASP.NET server).

Identify roles from Azure ACS

As we knew in Web got a lot of tutorial for Azure ACS, but most of it stop at inset simple ACS into website or application. Now, i wondering is that possible to identify and link up all the famous user oauth provider, and add them a new user in database then assign role to them ? After the process, they just simply click any provider then will bring them back to the same account ? Do you having such tutorial can share? Here is the process flow i want to make:
Window live + google + Yahoo + Facebook, one person may having all four account, but then i need their info also, then i create my cuatom data entering page and the problem is how can i link up ? How can withdraw the unique id to identify ? So i can recognize it..and assign role to it..
Question 1: how to link up ?
Question 2: how to identify in system?
Question 3: how to give role ? Not giving from azure admin page but through the code
Thx
There is one thing you should be aware of, when working with ACS (and with Claims in general) - you shall get to know the Claims.
Now, to the ACS specific question. Windows Azure Access Control service is not the magic wand that will do what you desire automatically. ACS is the easiest way to get working with Claims, and to work with only one set of specific claims, and don't bother with all different implementations of different protocols. In fact, what you work with, when creating browser based application, is WS-Federation protocol (and SAML token by default, but you can also use SWT token), and not OAuth protocol. The user uniqueness you get, when someone logs-in with your site, when using ACS is the strict combination of following two factors:
User identity
ACS namespace
The uniqueness you get is NameIdentifier claim (represented by: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier).
The first catch is that, say I am "john.doe#gmail.com" identified to your site through http://yourcompany.accesscontrol.windows.net you will get nameidentifier "X". When, I, the same "john.doe#gmail.com" identify myself to your site, through http://yourcompany-live.accesscontrol.windows.net/, you get nameidentifier "Y"! And this is true for all identity providers, which you link via your Access Control Service.
The second catch is: Live ID identity provider, when configured via ACS, will only give you a NameIdentifier claim. And nothing more.
Now to the questions:
Question 1: how to link up ?
The only feasible way to link up identities, is to built your own linking logic in your application. What I would do, is to stop using all the auto generated code and passive redirection to ACS, but to handle some of the Passive Federation manually. This would mean - I will watch out whether the user is logged-in or no. If not logged in, I will redirect the user to my own custom login page, where I will get from ACS the configured login options. When the user is logged-in, I will create an entry in my own user data base for that user. I will have fields (or linked table) for all possible identity providers that I would like to link up to a single user. Understand, I will store all the NameIdentifiers the user may have. Now, how will I link a user account. There may be different approaches. First, you must indentify the user to allow him/her to link an account. Then create let's say a "linkage ticket" with some unique ID (not GUID, to be easily remembered by the user). Show this ID to the user, and offer him an option to login with another provider (retrieve the list of privers from ACS). When user comes with another provider - show the field when one could enter the ticket. Check the ticket, and if it is valid - link to the existing account.
Question 2: how to identify in system?
As mentioned in answe one - you will need to have your own custom user database, where you will have one account per user, but that account will hold all the NameIdentifier claims, issued by the different authorities. Thus you will be able to uniquely identify the users with linked accoutns.
Question 3: how to give role ? Not giving from azure admin page but
through the code
In your architecture it will be very hard to maintain the roles in the ACS, because of the complexity you enter when requiring to link multiple accounts. I suggest that you keep user-role assignment withing the application database. The part that you have local user accounts, you will assign role(s) to each account.
Note, when I say local user account, I don't mean to support local login credentials, but just user profiles!

Categories