MVC 5 Windows Authentication logic - asp.net-mvc

I am trying to understand how to create MVC5 website with Active Directory authentication. Also I want to manage users. So for this I created a simple project in VS2013 and selected "Windows Authentication". When I run the application I get authentication popup to enter AD username and password. After that it does says on top right "Hello AD/UserName!".
But I am not seeing logic where it actually calls for authentication. Also I want to save few AD users to database and allow only them to login to website. How can I do this? Also how will my other web pages know whether user is already authenticated. Thank You.

One Approach-
Instead of selecting 'Windows Authentication', you choose 'Anonymous' (doesn't remember exact word here)
Implement logic to Authenticate user against Active Directory. Once user is Authenticate, store that user object into 'User' property of Current Context. So that you can access it and authorised user in subsequent request.
As you are aware, AD can only authenticate user against it. Providing access to few of them is authorisation part which we need to handle as part of our application. Since you want to enable access to website for few people of AD, what you can do is add those users in your application's database and allow authorisation to those only.

Related

As administrator, get access token on behalf of another user

I'm trying to implement IdentityServer4. We need to functionality to login as another user, when we're administrators.
I've already setup the login functionality for regular users, but I'd like a specific endpoint where an administrator can enter the username/id of a regular user.
How would one go about implementing this in IdentityServer4, as well as regular oauth2?
This is outside the scope of OIDC/OAuth2 interactions but there are some conventions for how to respresent such a scenario in the result token/claims. Have a read of https://www.rfc-editor.org/rfc/rfc8693 (in particular the act claim bits) for some inspiration.
We did this via the sign in UI flow but the model was that users could grant other users impersonation permissions explicitly. If when signing in you had valid impersonation grants then you'd be prompted as part of the sign in flow to choose a different account or continue as yourself. In your case you can identify admin users and give them the option to impersonate anyone you like.
If the user choses an impersonatee then it would change the current session to respresent that user but also store claims relating to the original user/session in the actor claim (act) and also add an amr claim of imp. We then made these claims available to clients so that they'd be aware of the fact impersonation was used and could then for example add that info to audit logs etc. We also notify the impersonated user via email and restrict access to account settings - i.e. impersonators can only sign into clients as other users, they cannot change their account settings.

Via the api, can I force the user to login to reddit?

I am writing a Reddit client that uses OAuth to authenticate the user. One of the features I would like to implement is the ability to use multiple accounts simultaneously. This requires the user to authorize my client on each account they want to use. The problem I'm running into is that if the user is already logged into Reddit in their browser, when I pop a browser to perform the auth, it will have them authenticate my client against their currently logged in user.
Is there a way to force the user to re-enter their credentials? I would rather not have to put some kind of disclaimer on my Add Account screen that says "Please log out of Reddit in any open browser windows".
I tried opening the Reddit login page in a WebView so the request is sandboxed, and while that worked, it gives the user access to the entire login page (including all the links that navigate to elsewhere on the site). I don't mind that experience when I'm popping an external browser, but in an embedded WebView I really just want to present a username and password box along with the OAuth validation prompt.
Note: I do kind of prefer the embedded experience because it doesn't interfere with the users existing browser cookies, I just don't like how cluttered the login page is this way and I'm not sure how to prevent the user from navigating away from login. Also, for completeness, this is a UWP app, though this problem is largely technology independent.
The problem I'm running into is that if the user is already logged into Reddit in their browser, when I pop a browser to perform the auth, it will have them authenticate my client against their currently logged in user.
It may be caused by the authorization server. If so, we can not do anything in our client app.
But if it is not the server issue, in UWP, there is a WebAuthenticationBroker class witch can help you to authorize your app to access the user info from Resource server by getting a token. You can try to use the class to implement OAuth authorization. You don't need to use the in a WebView so that you can authorize your app with multiple users if you can manage all the user with the token properly in your code logic.
See the Web authentication broker topic and the sample to learn more details.

How do I test a Azure AD protected Web API in with Visual Studio Test Adapter?

I've created a multi tenant Web API that works just fine. Now I want to build a native client for testing. The Web API app is defined in one tenant. The test app is defined in another tenant that has given admin consent to the Web API.
I want to use the native app to authenticate with username and password in my (non-interactive) integration tests. I cannot use certificate/app-only authentication because I need a real user context.
Getting a token
var userCredential = new UserCredential("admin#clienttenant.onmicrosoft.com", "password");
var context = new AuthenticationContext("https://login.windows.net/common");
return context.AcquireToken("https://webapitenant.onmicrosoft.com/webApiResourceUri", testClientId, userCredential).AccessToken;
The problem with this code is that it doesn't work until I've given admin consent to the native app, even if the user is in the same tenant as the app registration.
Exception thrown:
'Microsoft.IdentityModel.Clients.ActiveDirectory.AdalServiceException' in Microsoft.IdentityModel.Clients.ActiveDirectory.dll
Additional information:
AADSTS65001: The user or administrator has not consented to use the application with ID 'nativeclientid'. Send an interactive authorization request for this user and resource.
Since tests aren't interactive I have to create a console application that uses the above code but with PromptBehaviour.Always. This will prompt me for username and password and show a consent form. After I give consent the tests that is using the same native app registration starts working.
Is there a way to accept the consent form without a interactive GUI?
At the moment there is no other way to write user consent without some sort of user experience. (Which makes sense right?)
If you use the Azure Management Portal, as an administrator of your tenant, all the apps you create should automatically be consented for the resources you selected. This is because the Azure Management Portal specifically will write those consent links as you save your client application.
If you use other portals or APIs to create your application, then you will need to consent to the application at least one time. You do not need to necessarily put prompt behavior on your application to get the consent screen. You can just generate the URL for signing into your application, which will also take you through the consent experience:
https://login.microsoftonline.com/<TenantID>/oauth2/authorize?client_id=<AppID>&response_type=code&redirect_uri=<RedirectURI>&resource=<ResourceURI>&prompt=admin_consent
Note that we added a "prompt=admin_consent" at the end which will consent to the application on-behalf of the whole tenant. With this kind of consent, you will only need to do it once per application to get it working.
I hope this helps!

Shared authentication with devise

I have two Rails 4 sites, auth.example.com and app.example.com. Eventually there are going to be multiple app-type sites, maybe a dozen or two, but let's start with the one. Auth has devise set up so we can do basic user management (user creation and deactivation, password and SSH key management, etc.), with users logging into auth so they can do basic stuff themselves like update their address or phone number.
I want to set up app so that it uses the same authentication as auth. If a user tries to access app without being logged in, I want to redirect them to auth so they can log in, then go back to the page they were trying to access on app. Basically, I want to do devise actions on app, but with devise residing on auth. This, of course, is so that when we have multiple sites running, we can implement devise once instead of having to put it on every one of our sites individually.
I found this but it doesn't look like it's quite what I want:
http://4trabes.com/2012/10/31/remote-authentication-with-devise/
Anybody have a pointer to a resource that can walk me through how to do this?
Thanks.
What I would do is create a small API simply for user management. Then allow your other apps to make calls to that API to log a user in, create a user, etc. So keeping them on whatever site they're on, but in the background you're talking to the auth API.

Using OAuth but store extra information in my own DB

I've been looking into OAuth for a while, but haven't implemented it in any of my applications yet. I'm having trouble really understanding the full concept, so I still have a few questions that I haven't found an answer to, so I hope that anyone can help me.
I want a user to be able to start my application (WP8), login to facebook / twitter / microsoft / ... .
When he gets authenticated, I want to actually save this user to my own DB so I can add some user specific stuff like preferences, posts, ... .
What do I need to save in my own DB to specify a user?
Do I need to save the token itself or is this something that will be invalidated after a while? Or do I need to specify the user's name? With other words: What can I use as a unique identifier?
And what happens when a user would authenticate with for example facebook and he deletes his account?
And one more question, would you ever allow a user to connect to an application with 2 different service providers? If so, how would you make the coupling of these 2 providers to 1 user in your own DB?
I hope my questions are clear enough!
If not, don't hesitate to ask for more information!
Kind regards,
Gert
I assume that you have your own back-end where you authenticate your own users and your WP8 application is just a client.
First, let me distinguish between a user credential and a user profile. User credential is something that validates who the user is, e.g. username/password, facebook user id supplied with a valid auth token. User profile, is what you store in your own database about the user.
You also need to distinguish between a token you use to authenticate the user and the AccessToken Facebook needs to grant you access to user's data.
So... to answer your questions:
What do I need to save in my own DB to specify a user?
Create a record with user data (like preferences, and your unique user ID), and user's login method (e.g. Facebook) and credential (e.g. Facebook's user ID). This is your user's profile.
Do I need to save the token itself or is this something that will be invalidated after a while?
You can also store the Facebook AccessToken here if you've been granted "offline access" privileges by Facebook, but that is used for Facebook's access by you... not by the user's access to your app/back-end. For user's access you could just use a mechanism similar to cookie-based authentication - it's up to you. You could use the AccessToken as a kind of a "cookie", but you would need to always check against Facebook that it's valid.
With other words: What can I use as a unique identifier?
You could treat Facebook's ID as unique (so long as you never allow another account in your user profile DB to link with the same Facebook account)
And what happens when a user would authenticate with for example facebook and he deletes his account?
It's a good idea to have users still create a username/password combination that works with you site and only rely on Facebook login for convenience. In any case, Facebook provides a "Deauthorize Callback URL" when you create an app profile on Facebook. This is called when a user deactivates your app or deletes an account with Facebook. When you receive this call, you could send your user an email when an auth link to setup a different credential so as to not lose access.
would you ever allow a user to connect to an application with 2 different service providers? If so, how would you make the coupling of these 2 providers to 1 user in your own DB?
Sure, you could do that. Say you'd want to allow a Twitter account as well. You'd need to add a Twitter user ID field to your user profile database.
Here's another tip: create an ASP.NET MVC4 project in Visual Studio - the template includes an example of how to set up a user profile database with OAuth login.
Hope it gives you the high-level overview to investigate further.

Resources