2-Factor Authentication on an MVC App using Windows Authentication - asp.net-mvc

Is there a good way to implement 2-Factor authentication on an MVC web application that is using Windows Authentication?
I see examples that show how to implement 2-Factor on a Forms-based MVC app, but couldn't find one for a Windows-based MVC app.
Any help would be appreciated!

2-factor doesn't make sense in the context of Windows Auth. The application is authorized by the user's domain account. The security aspect lies on the domain-end, not the application-end.
However, if you're dead set on doing this, you effectively can't use Windows Auth. That sounds a little contradictory, I know. How you would have to handle this is use application-based authentication, such as Identity, so the web application itself would hold the user accounts. Then, you can authenticate via connecting to LDAP directly. You'll have to set all this up yourself, in other words; no easy set it and forget like you get with Windows Auth. With something like Identity, you can implement 2-factor auth, so you're golden there. However, instead of validating the password via your application's database and users, you authenticate via LDAP.
This is actually pretty common among enterprise-class applications utilizing AD. Typically, they'll have a script that you can run, as a consumer of the app, to periodically update the application's user database from AD, so all the same users with the same details exist in both places, except for the password, which remains solely with AD. This way, the application can associate its own data with its copy of the user, but authentication and authorization still happens at the AD level.

Related

How to add the notion of "accounts" to Keycloak?

How do I best configure Keycloak so that a user needs to have an account for a client to be able to login into that client?
I have to replace a proprietory SSO-Impl. It deals with users, roles and clients much like Keycloak. However, it also knows about accounts. A user is only allowed to login to a client if he has an account for that client.
In Keycloak, if a user simply exists in a realm he may login to a client of that realm. Nothing else is needed. So no "account" is needed. In the old application, he needs an account as well.
What functionality in Keycloak is best suited to overcome this difference?
I have one idea:
Create a client-role in each client namend "HasAccount" and assign it to users. Then, restrict access if that role is missing.
This is discussed here: "Restrict client access in a single realm with keycloak"
It has at least two drawbacks:
It mixes authentication and authorization in the legacy app. I can understand that. But creating a role was already a workaround. That is why I described my initial problem here.
I have clients in 3+ languages/technologies. Adding functionality there seems like more work than in Keycloak.
Last remark:
Before you ask "This is not single sign on" anymore. It is only for administrative purposes. The admin can allow users to login into a client or not by creating an account or not. The user does not have to login a second time. If he is logged in in App A and has an account for App B, accessing App B works without logging in there.
A user is only allowed to login to a client if he has an account for that client. is really not a task for Identity Provider (IdP). It provides only identity and not authorization.
Of course you can ignore that and implement authorization as well. See: User attribute based web service access control by Keycloak
From the design perspective I would add auth reverse proxy in front of legacy app (but it isn't a best solution for SPA apps). Auth proxy will provide authentication via OIDC protocol and also authorization. Legacy apps may keep own OIDC authentication - it will be seamless auth from the user perspective, because SSO will be used.
Account entity - you can use group entity in the Keycloak instead of original account.

Using app's identity (Azure AD) in ASP.NET web app to call Microsoft Graph

My ASP.NET MVC web application is currently using on-premise SMTP server to send mails.
To understand, here is the classic scenario:
Users have to sign-in in the web app with a user/password (encrypted and stored in SQL DB)
Users fill in a form
When form is posted 2 mails are sent (one for the user and one for the team)
We have to migrate to an Azure VM (Virtual Machine) based solution. I am asked to use Microsoft Graph to send mails as a replacement of using SMTP server. I found a lot of documentation and tutorials on this subject. The classic solution asks the user to sign in using Open ID Connect and Azure AD is used for the authentication (MSAL). So a new authentication page is showed to the user where he should authorise the application to perform specific actions like sending mails (for example). See picture below.
In my situation, I prefer not force user to authenticate a second time. As explained in scenario above users already sign in with (basic) user/password not related to Azure AD.
So I thought I would use app's identity in place of user's identity. This way the user should not authenticate a second time. I found a quickstart on the Microsoft's website which seems to fit my needs.
Here is the link: https://learn.microsoft.com/en-us/azure/active-directory/develop/quickstart-v2-netcore-daemon
Obviously I thought to integrate this concept in my ASP.NET web app and not in a console app but you get the idea.
So I would like to know if the solution of using app's identity in place of user's identity (authentication in Azure AD) to send mails in my ASP.NET web app is a good approach.
I think this is feasible.
In fact, Microsoft does not recommend users to log in to applications based on username/password, which requires a very high level of trust in the application and may bring certain risks.
In your question, you want to use the application to act as its own entity instead of performing operations on behalf of a specific user, so as to avoid repeated login authorization for users. I think this is a good method, but you have to pay attention, if you need to use the application's own identity request token to access MS graph api, then you must grant application permissions to the application, and then use the client credential flow as the authentication flow.
If you're using a VM you could enable managed identity and avoid dealing with credentials. Take a look to this article.

Retaining Forms Authentication with IdentityServer3

We currently have a typical forms authentication setup in our organisation; with a login page located at something like account/login. We want to retain this but also want to start securing some of our APIs with OAUTH2 ; essentially we are the provider.
From reading a fair bit about the subject Microsoft's OWIN OAUTH implementation moving forward isn't supported (e.g. vNext) and doesnt support all the flows with OAUTH2. Thinktecture's identityserver3 seems to be the "standard" and most complete solution there is currently.
I cant seem to find an example of using identityserver3 with an existing app that requires forms authentication.
We would be looking at using it in two different ways; one using the implicit flow using javascript where we allow a third party site to call our API once the user has logged in to us (using the forms auth) and the user has allowed the client to access specific scopes.
The other use case, I think , would use the authorisation code flow ; the client would be requesting this so it can auto login (much like a login with Facebook - but login with X company) or be already logged in if logged in our site.
Any help with these scenarios would be most appreciated.
I think it will not be possible to switch your app to OAuth without changing your existing login.
I would suggest you use Identity server with custom user store(https://identityserver.github.io/Documentation/docsv2/advanced/userService.html) to use your current user database. That way your existing login accounts will be used by the identity server.
You can then secure your APIs with OAuth using the Identity server. You might need to change the way your current app call the APIs too. This means users of the current app will be redirected to identity server's login page. You can brand your login pages using custom views to make it appear similar to the curent login page (https://identityserver.github.io/Documentation/docsv2/advanced/customizingViews.html)

Authenticate a web application user on Azure Active Directory using OAuth

Context
I'm building a web application deployed to Azure Webapps where users need to sign in. To accomplish this, I'm leveraging Azure AD with OAuth 2.0 Authorization Code Grant. Since I'm using Nancy (with the ASP.NET host) instead of MVC, I can't follow the official Azure AD MVC examples where all the OAuth handling seems to happen magically in the background.
Redirecting to the OAuth endpoint is straight-forward, and the user is also correctly redirected back to my application with an authorization code.
Problem
Now I need retrieve the user ID in order to match it to the user database in my application. I'm using ADAL for this, because this is basically step D & E of the authorization code grant flow, from what I understand.
Now what puzzles me is that this use case is not supported by Azure AD, stating that
The client '[ClientId]' and resource '[ResouceId]' identify the same application.
Also, as indicated by this answer, "ADAL is not meant to achieve web sign-on in a web application."
I've been able to work around this problem by creating two applications in Azure AD, as suggested by this blog, but it feels like I misunderstood something. This could very well be the case, as I am new to OAuth and Azure AD.
So my question is, what is the correct way to authenticate a user from a non-MVC web application using Azure AD?
the OWIN middleware should work with non-ASP.NET as well. See for example http://unlustrously55.rssing.com/browser.php?indx=24287735&item=13 - in your case you will have to use the OpenId Connect one or the ww-federation one.
Is this purely for users inside your organisation/tenant? It sounds like it.
Why don't you use an App Registration in Azure AD and grant it permissions to access the users profile? You should then be able to retrieve a user's UPN from the token. Please see here:
https://learn.microsoft.com/en-us/azure/app-service/scenario-secure-app-authentication-app-service

Implementing a login system for web apps and web API with DotNetOpenAuth

I'm looking for some guidance on what people think are the best set of technologies to use. We are looking to create a web portal to allow customers to register/login with standard credentials or their social accounts (Google, Twitter etc).
Once they are registered and logged in to the portal they can access our different web apps which will know who they are and what permissions they have based on a token. We will also need to secure a set of web APIs using some sort of OAuth mechanism, so the user would possibly create an account on the web app and then create an application which would give them the keys they need to access the API from their own app.
We have a basic portal app using MVC 4 and DotNetOpenAuth which allows a user to create an account and login with either a username and password or their Google, Facebook account etc.
The APIs would be MVC 4 Web APIs
Ideally the whole set up needs to be as simple as possible, I've briefly looked into using Windows Azure Access Control (ACS) as a way to cut out some of the heavy lifting but its hard to tell where exactly it all fits together.
Currently we run an ADFS 2.0 server and WIF to allow web login to our apps but it doesn't seem like it would be an ideal choice when integrating the social login and for securing the web APIs
I guess it could be two quite seperate parts, once they are logged into the portal, how would we go about providing some sort of claims token to the other apps they then access to understand who the user is and what they are allowed to do. And maybe the web API authentication/authorisation is its own entity?
Thanks for your time
We ended up using the built in MVC 4 login system and also added JWT token support, when a user is logged in a JWT token containing their claims is stored as a cookie. This is then automatically passed around our sites on the same domain by the browser, when the web API is called from javascript it checks for the token in the headers sent by the browser and either validates it and returns the correct data or returns an unauthorised response.
It doesn't cover all the bases, we can't give trusted third parties access to our web services yet

Resources