I want to implement roles and permissions on a web app we have created and I am looking at using System.Web.Security.SqlRoleProvider to implement this.
My problem is that each client will want to be able to configure who can and cannot perform actions in the system and no two clients will want the same, so creating basic
Admin, User, Manager roles to cover all won't suffice.
What I am proposing to do for each screen is create roles as follows
Screen1Create, Screen1Update, Screen1Delete, Screen1Read
Screen2Create, Screen2Update, Screen2Delete, Screen2Read
and so on.
I would then allow the client to select the roles per user, which would be stored in a cookie when the user logs in.
I could then read the cookie and use user.isinrole to check if each method can be called by the current user.
I realise there is a size constraint with cookies that I need to be aware of. Apart form that, does this sound feasable, is there as better way to do it?
Many thanks for any input.
Really if you want to program this all yourself to the cookie level you're risking opening security holes. The way to do this is with forms authentication combined with role based authorization. Asp.net will give the user a tamperproof cookie.
If you implement roles you can then easily mark methods:
[PrincipalPermission(SecurityAction.Demand, Role="Screen1Create")]
or use code to see if someone is in a particular role.
Lots of info:
http://weblogs.asp.net/scottgu/archive/2006/02/24/ASP.NET-2.0-Membership_2C00_-Roles_2C00_-Forms-Authentication_2C00_-and-Security-Resources-.aspx
Remember that cookies are user-supplied inputs, so if you're going to store the privileges of users in cookies, you must use a keyed hash function (such as HMAC-SHA256) to make sure that users do not grant themselves additional permissions.
Or, if you store all the permissions in your database, it'll be persistent across client computers and you won't need to validate its integrity every time you wish to use it.
Related
I'm creating a website using ASP.NET core with MVC where a few people will have accounts to manage a database. Since anonymous users will be able to view the website, I don't want them to be allowed to create accounts and mess stuff up. I'm not sure if adding the [Authorize(policy)] attribute to the create account page is possible since the ASP.NET core template hides the page that I need to add it too. Is there a way I could do it? Now that I'm thinking about it, does individual authentication even allow you to do such a thing?
Before you say this is a duplicate question, I've looked through previous answers only to find that they just add [Authorize] to the create account page, which I said I'm fairly certain I can't do. Unless there is something I missed, of course.
Take a step back and think about what you are saying. You want to enforce authorization on anonymous users. Does that make sense to you? How can you authorize someone you don't know?
If you don't want anyone to be able to create accounts, your action simply cannot be exposed to anonymous users. You should remove the code generated by the template or at the very least, hide it behind an authorization scheme like the other answers have suggested.
That leaves you with the problem of how to create a user when the page to create a user cannot be accessed. I've dealt with this in a couple of ways in the past:
Create a user with admin rights programmatically (if it doesn't already exist) on application start. This user is authorized to access a page within the app (usually an admin panel on a separate Area) where he/she can create other users. You use this account to grant access to other accounts and assign proper roles as needed. OR,
Have the application check for initialization on start up and if it hasn't done it before, show a workflow that allows you to create an admin account (kind of like a first time installation step). Once created, you use it the same way as in option 1.
In both cases, you will be applying the Authorize attribute to your controllers and/or actions as desired and will need an "admin" facility where users with proper rights can manage things.
We have an application (C# on the server, using AngularJS / Web Apis for a single page application) that assigns users different roles, which are stored in the database. When the user logs in, the user object (including RoleID's and RoleName) is transformed into a JWT and sent to the user, which is then used as authentication.
We're having trouble determining the best way to maintain and use these access roles however. Specifically, to use them in the current set up, it would seem that we have to hard code either the name of the role or the ID into the application.
For example, on the client side, if we want only users with a Manager role to be able to see and click a button, we would have to explicitly state that, ie if (UserService.HasRole('Manager')) { doStuff(); }.
Conversely, we'd have to do the same thing on the server side (because everyone knows relying on client-side security is bad). When the server gets a request on the API, it checks the JWT for validity and, if valid, checks the User's roll to see if they are allowed access to the specific web API endpoint.
This all seems prone to breaking if a role is renamed, or the ID changes. I generally hate hardcoding things like this. Is there a better methodology or approach that can be taken here?
In the past, when we've done RBAC (Role Based Access Control), we decouple the Role from the Permission e.g.
Role Permission
===============================
Manager Create Order
Manager Delete Order
Till Operative Create Order
Administrator Create User
Administrator Suspend User
etc.
This could be stored in a database and cached in something like Redis. Two tables, Role and Permission, where the Permissions need to match the ones built into the application (you could script this).
So your permissions grow with your application e.g. you add a new dining service, you can add a "seat diners" permission. The permissions for existing/mature bits of the software should rarely change (unless they were written incorrectly), whereas the roles are entirely fluid and can be renamed etc.
You can then use an annotation/security framework to ensure that the user making each API call on the server side has the correct role required.
You can even make it additive and allow a user to occupy multiple roles at once to blend things together.
You may maintain your user to role mapping in the database also in another table (using FK constraints) or you may use something like LDAP with the mapping being looked up from the DB/cache.
On the server side, Microsoft has built in management for roles. I would first look at
http://www.asp.net/identity/overview/getting-started/introduction-to-aspnet-identity
And then I'd also look at the the IdentityServer project for working with JSON Tokens on the server side.
https://brockallen.com/2013/04/14/getting-json-web-tokens-jwts-from-adfs-via-thinktecture-identityservers-adfs-integration/
On the client, I would suggest storing the tokens as either just in memory javascript or if you want them to persist, I would store them as cookies but make sure to set the cookies to not be accessible by JavaScript by using the httponly parameter when creating the cookie.
HTH's
I am using a stateless design for a MVC5 Web API 2, ASP.NET application.
User roles are created by administrators by selecting permissions.
Each user in the application is assigned a custom user role, one role may be shared amongst users.
Razor views are structured based on the permission in the users role.
MVC and API controllers are available depending on the permissions in the users role.
For each request to the server, the users permissions need to be processed.
I can think of 2 ways to do this:
Store the id of the users role in the Role claim and perform a database lookup to retrieve the permissions for each page-load/request.
At the user login, retrieve all the permissions assigned to the users role, serialise them as JSON and store them in the Authentication claim. Then at each page-load/request, de-serialise the JSON back into objects and process the permissions.
Which of these would be the better option?
Option 1 is a lot slower than option 2.
Is there a security risk of storing the permissions in the cookie?
Is there a better or alternative solution which is quick and secure.
Storing permissions and other sensible data inside a cookie is always a very bad idea as it's quite easy to manipulate them. Trusting cookies requires an additional server-side check which defeats the purpose of storing it inside a cookie.
You're way better off only trusting the data that is under your control, aka the data in your database(s).
Depending on your application it might be useful to lazily evaluate permissions only when you really need to access them if the performance hit is too big. Keep in mind that you can make use of things like Redis to improve performance dramatically.
So again, depending on your application I'd probably go for option 1 as it's the more secure way.
I've found a lot of information about this subject; however, not much in the way of how to implement my specific scenario. Unfortunately, my company's AD is half-pregnant, so to speak. The users are there, but that's about it.
I'm creating an intranet and obviously need to authenticate users which I'll use Windows Authentication to do so. However, since my AD does not contain any of the additional information typically used in an intranet (heirarchy of users, meaning managers and departments associated with each employee, etc.), I wanted to use Identity to satisfy that need. And although we do utilize AD Groups, it's painfully difficult to get that setup and want to use Identity for role based authorization instead of AD.
Although fairly new to Identity, it's easy enough to figure out, and Windows Auth is easy to implement.
What I'm missing is the know-how to marry the two together.
So my scenario is - Authenticate the users with Windows Authentication. Once authenticated, switch over to Identity for role-based authorization (claims?) and any other meta-data (such as user information or application specific data)
I've seen this question asked, but not sure if it really is that simple or is there more to it. And I'm not sure if it really fits my scenario. And this question seems to be exactly what I'm asking, but no responses. Finally, this question seems even closer to what I'm asking, albeit using the Membership Provider. I'm guessing this may be the way with Identity as well?
So, in my instance, I'm using Windows Authentication and so I will not have a login form or action (strict requirement to NOT have users enter username/password - it should be seemless). In the case of an employee going to the intranet for the first time, they authenticate with AD, but then how would I save that user to the Identity store? Would it make sense to send new users (employees that have never been to the intranet before) to a Register page after they've been authenticated through AD to ensure there's an associated record in Identity? I could then, as part of the registration process, have them select their department and manager. After they register, a human-based validation process would have to happen to ensure the user selected the correct department and manager, but that's the least of my worries right now.
Recommendations, links, or just some simple guidance would be appreciated. Thank You!
I need an advise. I'm building a Web API for my app and I need to auth users who use it. The user will have access to his data, but may have access to others users data as well. In my database I manage the users and what other users they have access to (you might think of it like in Facebook where a user has access to his profile and his friends profiles, but not to other people profiles).
In my app, the user enters a username and password, and those are saved encrypted on the devise. They are later sent (via SSL) to the API on each call - what I've done is implement a Basic Authentication. If there is a better "best practice" to work please feel free to suggest - I'm new to this.
So far it works - but the problem is that working like this
the user once authenticated also has access to other profiles - what I would like to do is have him only get the profile (http://myaddress.com/Users/{id}) that belongs to him and the items that he owns (http://myaddress.com/Users/{id}/items) - and not for profiles and items by other users.
If the user is trying to access a profile or items of another user that he is connected to - allow that access.
What I thought about is passing the requested URI to my login method, and then check what user / resource the user is trying to access and than check the database - but that seems like a lot of work and a lot of IF statements.
So before I start writing, I thought I'd ask to see if there's a better way to do this. I have the HttpActionContext, I just don't know how to use it to my advantage.
Hope I was clear about my question. If not, feel free to ask for clarifications.
So you identify the user from his/her credentials that are sent on every API request. Could be switched some token based flow, that user authenticates just once and gets token(acts like user credentials) which is then sent to back-end API on every resource request. Then you can control the token, revoke access etc. What you could is make some kind of permission service, that all resources/objects have permissions attached to it and then just assign needed persmission to users read/write to this object maybe. Might be a massive task to implement. My opinions.