SignalR on ASP.NET MVC and Multiple User Types - asp.net

I am currently in the process of sketching-out an application that allows real-time interactions with website visitors.
Therefore, I have two different "User-types":
Unregistered User: these are the visitors
Registered User: these have a (custom) ASP.NET MVC membership
Now, I am persisting "UserNames" and ConnectionIds in a DB so I can freely scale at some point in the future. I do this by accessing Context.Identiy.User.UserName from within the Hub and then query the DB for any existing "sessions".
Here is the problem:
I need two different types of "User"
For one, I want to dynamically generate a GUID - these are the visitors and will be removed from the database after a given amount of inactivity.
These are the admins, they have their proper identities attached to the Context object.
So, how would one go about accessing a "session" from SignalR? It is not really a Session, I just need to get a SessionId from a Cookie on each initial request to the MVC-Controller, that's all. All I need to be able to do is:
Have an auto-generated "SessionId" which I can use to persist visitors across requests
Have a more "extended" identity: I want to use UserId instead of UserName
Anyway, I hope this makes sense but chip in if anything is unclear.

Okay, I just realised that I can use "HttpContext.Current.Request.AnonymousId" and I am linking this up to a Session-database.
Here some relevant documentation: http://msdn.microsoft.com/en-us/library/system.web.httprequest.anonymousid.aspx
This solved my problem in this case. :-)

Related

ASP.NET Identity - How to manage claims?

I would like to implement claims based authorization in a Web Api project. I understand the idea of claims and can manually add a claim to a user and authorize a request based on it. However, I don't know how I should manage the claims, assign them to users and update them in future.
For example, say I have a Product entity and ProductCreate, ProductRead, ProductUpdate and ProductDelete claims for the CRUD operations on this entity. So I have a few questions:
I can store the claims in the DB, but what is the best way to add the "default" claims to a user on registration?
If I add new functionality to list the products which is only authorized if the user has the ProductList claim - new users would get this claim, but how would I add this claim to all existing users in the system?
Should there be a limit on the number of claims associated with a user? In a larger system with many entities, a user could end up with hundreds of claims
As I said, I know how to physically add the claims to the user etc., but it's more the bigger picture of the process of how you would manage claims and users in a real world example.
Thanks!
UPDATE
Thanks Brendan, I appreciate your help! I don't know if I'm misunderstanding something fundamental or if the answer is staring me in the face - either way, I'm not getting it.
So I have web api and would like to give granular access to the different controller methods. As the Admin, I want to be authorized on all calls so I should have all claims. Registered users should have read access to some methods and you as a moderator should have update and create access to some. My understanding is that these claims should be stored in a DB (SQL server in my case) somewhere and "assigned" to the user when they register. Using Asp.Net Identity, each user's claims would be stored in the AspNetUserClaims table, so when they login they get all their claims in the token by default. Simples!
What I am missing is the process of how you would handle the claims that should be assigned to a user when they register, what claims should a Moderator get etc. and how would you add / remove privileges. It doesn't seem right to me to have this in the code as adding a new claim in the system would require a rebuild and new deployment.
Also, if I add new functionality which requires new claims for different types of user, how would I make sure that the next time an existing user logs in they get the new claims as well as the ones they were assigned when the first registered.
I hope I am making sense, I may be mixing up some of the Role-based thinking with some of the Claims-based thinking which could be the source of my confusion. I just haven't seen any examples of how you would manage an application with many, many claims in the real world.
Thanks again!
That's exactly the same question and issue i'm running into. All I found is info on how to create a claim using the manager classes but nothing on where to manage these claims.
There can be different combination of access to give to a user and if my UI is a disconnected UI from my API, I don't think i would want the ui to manage these claims for me.
Other than mucking and creating a claims manager class with a claims table did you figure anything built in that can be used?

Not handling authentication, but need claims and cookie

I am creating a new asp.net MVC 5 application. Authentication is handled by a third party using smart cards. Once a user is authenticated by the third party, I am sent the user's unique ID (inside the http header) which I match up against my database in order to find relevant information about said user (roles, display name, etc.).
Currently, on every page request, the sent user ID is compared against the database, and checks are performed to ensure the user has the proper permissions to view the requested page. While this works, it sure seems like a bunch of needless database hits when all the user information could just be stored in a cookie.
If I was using Individual User Accounts for authentication, what I am looking to do would simply be built in using Identity and OWIN. But since I am not handling the authentication, but merely the authorization, is there a way to use all the nice features of Identity and OWIN (claims and cookies specifically)? If not, how might one go about this?
Also, of particular interest to me is when a role is added or removed. Using OWIN with Individual User Accounts, updating the cookie is as simple as logging the user out, and then back in immediately in the background. That functionality would also be desired for any solution presented.
Any insight would be extremely helpful. Thanks for reading!
You could do what you're asking by directly storing values in a custom cookie, but for your purposes it sounds to me like you might be more interested in utilizing sessions to track that info. This will keep all of your actual data stored server-side, which is more secure as it isn't vulnerable to cookie modification and it allows you more freedom to control the state (for your role example, you wouldn't have to "update" the cookie at all, just update the session variable on the server side to add or remove the role as needed).
Figured it out. Found a great article that really helped:
http://www.khalidabuhakmeh.com/asp-net-mvc-5-authentication-breakdown-part-deux

Strategy for managing user actions in java web application

Context: Web Application - Java, Spring MVC, Spring Security
What is not transparent to me is what information to store/how to perform certain actions in web application(don't take passwords in consideration of course), for example I can:
Retrieve user(db request) and store user details in a session.
Just retrieve user id(db request) and store it in a session and fetch it to DAOs when needed. Is it safe to store user ids in sessions?
Request-scoped. Not to store anything in session.(of course spring still stores security details in there) If User requested action - determine if authenticated(?+role), determine its id(db request), fetch it to DAOs. If user requests this action again steps will have to be repeated.
Assuming if my db tables always have int id as a primary key. Login name is just unique. And please don't be confined to my 3 approaches, these are really simple examples, I am talking about data storing/persisting(please don't associate ORM with this word in this context) which is combination of db requests and is used for DTO on server-side in web application.
What I think is that the more details I store in a session(or across requests), the easier for me to manage it plus less requests to database. If I keep these details in a form not identifying particular user, then there should be no problems? For example if I store "id = 5 ; fruit_id[]=1,4,7;(sorry if syntax is wrong) say in session", it doesnt really sound identifying if security is breached?
Your question is a bit vague and can only be properly answered in light of exact details. However in general it is fine to store user details, including user id, in the session. Probably a User object mirroring whatever fields/details you have in your db's user table. It's also OK to store authentication levels or roles. Of course you shouldn't store too much data in the session.

ASP.NET MVC Authorization: Permissions in Place of Roles

I know this is a question that has been asked over and over but I'm attempting to implement permission based rather than role based authorization in an ASP.NET MVC application. So instead of just having high level roles like Manager, Admin, or User, I need to have permissions like ViewTask, AddTask, DeleteTask. I have read a ton of comments on this and it seems like the easiest solution is to just treat roles as permissions and define "roles" of ViewTask, AddTask, and DeleteTask.
Is such an approach really a good idea? Some of my concerns are that you could end up with over 100 roles depending on the size of the application which would then rule out the ability to do role caching in cookies and thus every call to User.IsInRole hits the database. If every action method is going to be decorated with [Authorize(Roles="XXXX")] am I going to see serious performance issues?
My other issue is that I still want to keep the concept of a role around so that an administrator can simply associate a user with a role that has a predefined set of permissions. Using the approach above my thought was to create a separate entity in my application named Group and that Group would be responsible for keeping track of the ASP.NET roles that are assigned to that Group. So, when a user is associated with a Group, I can retrieve the ASP.NET roles that need to be assigned to the user and add all the roles.
Has anyone implemented a system in such a way? Any opinions or thoughts on this approach would be appreciated.
Thanks
I agree with #jlew about caching the user's data and when the cache expires - just reload it. There's no use trying to force this data to stay persistent. Additionally, if you want to move away from the ASP.net role providers, you could roll your own security as I've described in this reply. This has the advantage of allowing very custom security solutions for roles/individual permissions.
The following is just an idea that I've been toying around with lately (just some food for thought). Why not use the RESTful urls of MVC to define "permissions". For example:
/tasks/add could define the permission for adding tasks. These could somehow be hierarchical so that giving a user permissions on /tasks/add also gives them permissions on /tasks. Then, you could use a global action filter that would build the URL given the route values. This would also allow really interesting approach for individual item security configurable via runtime. For example, /tasks/edit/23 could somehow grant edit permissions on task with id 23. Anyway, this might not even be helpful at at all... but it's just thought I thought you'd like to maybe consider.
Cheers!
We solve the problem by caching the principal on the server side, so that the "permission roles" do not need to be in the cookie and we do not have to re-load on every request. You can actually get around the cookie size limitation by chunking your cookie data into multiple cookies (Windows Identity Framework does this.) But, you may have bandwidth or other concerns with big cookies.

secure way to authenticate administrator in ASP.NET site using OpenID with DotNetOpenID

Encouraged by SO, I'm trying to write an ASP.NET site that uses OpenID for user authentication. It's a regular WinForms site (not MVC.NET), using the DotNetOpenId library for authentication.
Is it safe for me to permit/deny administrative functions on the site by simply comparing the current session's "ClaimedID" (as returned in the OpenIdLogin_LoggedIn event, as member DotNetOpenId.RelyingParty,OpenIdEventArgs.Response.ClaimedIdentifier) to a known administrator's OpenID (i.e. mine)?
If so, is it safe for this ID to be visible (e.g. in open source code), or should it be "hidden" in a configuration file or a database row? (I know it's better design to make it configurable, my question is just about safety.)
My solution is to follow the same idea of the Roles table. After you've authenticated the user, look up that user's roles. If the user has role "Administrator" in the UserRoles table, then they can do whatever the Administrator can do.
I don't broadcast open ID's in my app. They're stored in the table. On every action result, I'm hitting the Users table, since I have also modified mine to store various user state information. With the exception of the home page, there is going to be some user information that I need from that table. I'm using LINQ, so I include the .LoadWith() to load the User with his list of roles when it serializes.
Jarrett makes some good comments about using database tables.
Just to answer another one of your questions, no, it's not a confidentiality thing to put your OpenID in your code generally. If setting up roles seems overkill for your site, a simple equality check against your ClaimedIdentifier is just perfect.

Resources