Web API Authenticate user and check if has access to a resource - c#

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.

Related

Allow supporter to sign in as another user

We currently have an Identity server 4 application. Using entity framework core and asp .net identity.
We have a group of supporters who need to be able to access our users accounts in order to help them with issues over the phone. Our users are not able to figure out how to use team viewer. As most of them are mobile and will only have a cellphone at the time.
I know all the security ramifications of allowing other people to sign into your account however there is really no way around this. Our customers have accepted that our supporters can connect to their account when they request it. We trust that our supporters only do this when its requested.
Current solution and its issues
The current hack creates an api endpoint which only our supporters can use as it has been locked down so that only those with supporter permission can use it. They send the users email and we hack create them an access token which is then used by the application (Web version) to act like its the user who is having issues.
This solution was created by my predecessor basically by taking the supporters access token and replacing all of the claims with this supporters id to the users id and returning it to the application. I hate this solution on a number of levels and its very unstable every time i look at this method it breaks. currently its not working because audience clams are incorrect for some reason.
What i want to do
I would really like to do this in a less hack way. So is there a way to sign in a user to the application without it actually being them thats doing the signing in and return an access token?
I have tried doing
await _signInManager.SignInAsync(user, false, null);
But i cant seam to figure out how to get that to return an access token.
What i would really like to do is have the ability for supporters to login to any ones account but do it securely somehow.
The problem with the user account is that it's not bound to one application. So by allowing others to login using the account, you give them also access to other applications. As a workaround you could use 'public' accounts, like engineer_01, engineer_02, etc.
But, this may not be necessary at all. What you really want IMO is to impersonate the user, instead of 'hacking' the account.
One way to do this, is to extend IdentityServer with a custom grant type using extension grants.
How this could work:
A signed-in user, who is allowed to impersonate users for the particular client/resource, requests an access token at the new impersonation endpoint.
The user sends the sub from the user to impersonate to the endpoint, where the user and (combination of ) sub are verified.
When access is granted a new (short-lived) access token is returned which can be used to impersonate the user, without having to know the credentials of the user.
The access token should contain information of the endpoint so it can be determined whether the user is impersonated.
We implemented an impersonation feature that is integrated into the browser-based sign in flow. If a user with permission chooses to sign in as another user then we add additional claims to their IDS4 authentication cookie which then supports issuing extra claims in the resulting token that reflect that it's an impersonation session and who the original actor is.
Navigate to client application
Sign in using whatever credentials
Check if any impersonation permissions exist (how these are defined is entirely up to you)
Prompt for impersonation account selection (or just continue as self)
Sign in as the selected account (with record of original actor)
Redirect to authorize endpoint
Issue tokens and redirect back to client application

How To: Active Directory authentication / aspnet identity authorization

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!

Giving an application its own user id/session to access a google drive

I have a C# MVC web application that needs to make a copy of a google sheet (template) and set the copy to read/only for the current user while the template owner gets read/write to the copy.
Normally you would give the application itself an ID to do this type of function. I haven't figured out how to give an application its own ID and session ("User-1") independent from the current user ("User-2"). I don't want to give the read/only user the read/write password to make the copy of the template and I'd really prefer the copy happen outside of the current user's google login.
Your application is bound to a specific user by virtue of the OAuth Access Token it submits. So provided your app can retrieve an Access Token for User-2 (with an appropriate scope), then you're good to go.
Getting an access token for User-1
There are number of ways you can do this, depending on the volatility and security requirements of your app. Fundamentally it requires your web app to have a stored Refresh Token for User-1, which it can use at any time to silently fetch an Access Token. See How do I authorise an app (web or installed) without user intervention? (canonical ?) for more details.
.
Some of the terminology in your question needs a bit of straightening out.
"ID" - each application has its own ID when you register it on the developer console. It's refered to as a Client-ID which confused some people into thinking the ID is somehow related to the end user; it isn't.
"Session" - there is no session to Google Drive. There may be a session to Google, within which the OAuth flow will seek to identify the Google user in order to generate an access token for that user. But there is no "session" to Drive, which is why a Drive app can access as many Drive accounts as it likes, provided it has an access token for each one.

Access multiple users inbox/events on facebook / gmail on one browser session- possible from javascript?

Say I have 3 google accounts and 3 facebook accounts and want to an webapp for viewing the inbox / events for all 3 accounts together. Would that be possible?
I can think of the following options:
Using the javascript api's only. (Don't know if it would be possible to have multiple users authenticated at same browse session or switch between the users without reentering passwords?)
Merge the inboxes / events on server using some c# api for gmail and facebook. Would those api require a browser session, or would it be possible to store some sort of a authentication token?
Thanks a lot for any suggestion!
Larsi
It is definietly possible to do that with Facebook by using its OAuth authenitcation and corresponding service calls to retrive data. I don't know if gmail supports something like this.
Facebook API/Auth reference: http://developers.facebook.com/docs/authentication/. Note that you'll either have to call services yourself or have one application Id per account you want to pull data for as library provided by Facebook stores user information in cookies named with application Id as prefix.
You need two separate browser sessions, possibly storing cookies in different places (if you want to remember who's logged in) to be logged in to these websites as two users at the same time. Some of them will even free up sessions by examining the IP address; if the same IP has two or more open sessions, all but the youngest are discarded.
The idea is, a computer is used by one person, and that person is supposed to be one user and interact with the web app in one session. That allows for the best overall use of resources. There are very simple ways to enforce this server-side, that are hard to "game" client-side.

Best way to implement multiple roles and permissions in c# web app?

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.

Categories

Resources