How to perform hybrid individual user account/aad authentication in ASP.NET MVC? - asp.net-mvc

I have an ASP.NET MVC application that is used by different customers. Currently the app is set up to use individual user accounts. I have built some authorization logic around that and would like to keep the logic unchanged.
I got a request that some of the customers would like to perform authentication for their users with their Azure Active Directory. I have uncommented the app.UseMicrosoftAccountAuthentication part from Startup.Auth.cs. I registered the app as multi-tenant in my AAD. I managed to get the whole thing running and users now have the possibility to link their accounts with AAD and use it for authentication.
However, I encountered a few problems I am struggling with:
In order for the user to link his account with AAD he needs to set up an individual login/pass account in the first place. How can I avoid that? I want to have the users either authenticating with login/pass or with AAD, not both at the same time.
I have no control over which account the user uses to authenticate. Let's assume I expect the user to use an account in domainx.com, but if they link domainy.com account it will still work. I need to have some kind of way to compare the expected domain with the actual one that comes back from AAD. How can I do that?
One of the ideas to tackle the problem was to have a customer admin create the user accounts for them. The issue is that in AspNetUserLogins I need to store the user's AAD ID, not the email. How can I query AAD to check the UserID based on the email?

Related

Is there a way to search for federated Teams users in Microsoft graph?

In the Teams client, you can search for any open federated users using the top search box. It'll give an option to search externally, which will return a federated user if the address matches. I'm trying to find a way to replicate this in an application, and haven't come up with a way to get it yet. Here's what I've tried so far:
People Search (e.g. https://graph.microsoft.com/v1.0/me/people?$search="user#domain.com") doesn't return anything.
User search (e.g. https://graph.microsoft.com/v1.0/users) only returns users in the same AAD (as expected)
What I'm really interested in getting is the AzureAD guid (user's unique ID) and I can't find a way to get that without having an app to query the user's specific tenant. Is this something that's possible to get through graph, or will it need to be Tenant specific? Thought is that if the Teams client can do this for open federated users, then shouldn't an app have access to the same data?
So I sort of found an answer to this in creating a multitenant graph application. I never really understood how those worked, but it finally clicked. To set one up, in your home tenant create an AAD app as usual, set it as multitenant, and assign it the API permissions you need (User.Read.All, User.ReadBasic.All etc.). It'll show up in app registrations, and you can auth using secrets/certs etc. Then in a target tenant, have someone hit this URL: https://login.microsoftonline.com/TENANTID/adminconsent?client_id=APPID where TENANTID is the target tenant's ID, and APPID is the appid from your AAD. Once consented (user/admin depending on permissions), the app will show in the "Enterprise applications" section of the target tenant's AAD.
Once you have this, you'll be able to search users on that target tenant. The challenge here is that you'll need to know the tenant ID you're searching, and have a user specifically grant permission to do it, rather than it being a federated search. Not ideal, but that's about all you can do with graph.
What would be useful here would be to have the same capabilities as the Teams client to get federated user information as an application in any tenant. Since the client can do this interactively, any open federated organization should be searchable by a graph application (perhaps using an "include external" flag in the search). I wouldn't expect anything other than the user GUID and presence, but for my case (ACS/Teams interop) that would be enough.

Azure AD and Identity Framework in a single MVC APP

I have a MVC5 application which has authentication and authorization using ASP.net Identity. So all my roles, user profiles are stored in the application database. The application is managed by me. My company now wants to use Azure AD for authentication in the application. So the user will be able to login with their credentials. If the user is signing in for the first time then i want to create the user profile in my application database. I also want to use the the roles stored in my application database for authorization.
Can someone provide some guidelines on how I can achieve this?
Thanks for your help.
Here is the link where the step by step guide is available for using Azure AD to accept sign up and sign in.
https://learn.microsoft.com/en-us/azure/active-directory/develop/quickstart-v1-aspnet-webapp
Overall in summary below is the architecture diagram which you need to perform.
You could also use Azure AD B2C for allowing user to signup/sign through google, FB, Amazon and etc identity provider.
All the authentication login you could implement it in filter and later you can decorate your controller with the AUTH filter.
and then you can register your filter like below
GlobalFilters.Filters.Add(new AuthorizeAttribute());
I have not provided code samples here as it would be too long answer.
Coming back to your original question , i want to create the user profile in my application database , basically after successful login you can save the claims data which would act as a user profile in your DB.
However it is not recommened to save the entire profile in database if you are already maintaining it in Azure AD.
Azure AD B2C gives the flexibility to add custom attributes too.
Hope it helps.Let me know if you need any help.

Single sign-on flow using ASP.NET MVC + Active Directory

I'm looking into creating a single-sign-on portal built in ASP.NET MVC. This single sign on portal should give users the option to sign in with their individual account (which should be verified against AD) or their Facebook/Twitter account. What I'm still in the dark about is if the application/authentication flow I came up with is actually feasible. This is how it should work:
User logs into the SSOP with his AD account (using a custom form where he enters these credentials). The SSOP verifies these credentials against AD and logs the user into the SSOP accordingly. The SSOP then offers the user to start any of the applications he has access to (based on his group memberships in AD). These applications are built by various third parties and are not all .NET based. Clicking one of these applications in the SSOP should log the user into this application using the credentials authenticated against AD that were used to enter the SSOP. I currently do not know how this should be done, e.g. by using claims or some sort of auth token? Obviously the receiving application should support whatever option we choose, which means we're looking for a best practice of some sorts.
The social login part of the SSOP should work somewhere along the following lines: The user logs in using his social account. The first time he does, he also has to enter his AD account credentials so we can link his social account to a specific AD account. Every subsequent time the user logs in with his social account the SSOP should log in the linked AD user. That way the SSOP always uses a valid AD account to authenticate to the applications it offers the user. This also makes it easier to administrate the user base since these are all stored in AD. The social login links and any other SSOP specific data is stored in a custom data store (MS SQL db).
I've been looking into the ThinkTecture IdentityServer, but have yet to figure out how it can be used in this scenario or if this scenario is even feasible.
So, the question basically is: is this authentication flow even possible or remotely best practice? If so, where to begin? And if not, what is?

What is the standard with oAuth for remembering users?

Me and my colleagues developing an application (both web application and mobile app(iPhone & android)), which includes a login process.
Currently, we have our own login mechanism (where users have signed for an account on our app, and have stored their info in our Database). We are looking into integrating oAuth and allowing users to login with Facebook, Twitter, LinkedIn and Google.
Now, when the users logs with any of those, as I understand the login process occurs outside our application and basically only get permission to access their resources.
My question is this: through oAuth, how do we remember users? i.e., users who login have read /write privileges and have preferences. How do we remember those when they don't actually sign up through our app.. Can we store their email address in our "Users" table??
What are the best practices in such a scenario?
Thanks for any info you can provide.
Having built authentication databases for a few different OAuth-enabled web sites, I can say that I've learned a few things that you should keep in mind.
You should have a table of users for your site that is completely independent of which OAuth provider they used for sign-up/sign-in. This enables your site users to combine multiple accounts together under their primary identity on your site. (For example, associate both Facebook and Twitter with you.)
When you let a user sign up, you should get an email address from them. Whether you ask Facebook for it, or if you have to ask directly. This enables you to "upgrade" users later from depending purely on third party OAuth to setting their own password on your site. (You simply send them a link to your password reset page in order to get them started creating their first password.)
You don't want to use email address as your primary key. I'm not sure if that's what you're actually describing or not, but you really want them to have a local user ID that you use for maintaining their session, etc. You then associate their Facebook ID or their Twitter ID with that local ID, and use the correspondence between such identifiers to match up which of your site's users to consider logged in.

Company page needs Facebook profile

I've got a company web app. I have integrated it without much problems with Twitter.
This means, when a staff of our company creates a new product, it posts onto the company's profile on the Twitter web site as well.
However, Facebook is another story. Facebook encourages registrants to sign up as "individuals".
For example, on the registration page:
You are not allowed to put generic emails such as (support#company_email.com, sales#company_email.com)
You may not have the first and last name as a company entity. For example Foo Distribution or Foo Inc
Their automated system simply rejects any clever attempts to register as a "non-individual". With Twitter, it was a breeze. Since Twitter allows / encourages companies to register an account with them directly, and not as individuals.
Moving along on Facebook, I found out that I can create a 'page'. Which I can use for the company. It has the option of allowing other "individuals" to be admin of the page. However, this would mean that each staff would need a Facebook account.
I don't really like this approach, since some of our staff may be negligent with their Facebook passwords. I rather have our web app have one 'method' of accessing Facebook's API isntead, the way it is done with Twitter.
How else would you go about this?
I'd make yourself the admin of the page, install an app that you develop, and then let your users make posts to the page through that app. This way, you're controlling access to the page while letting your users still have access to it.
You'll need to use an offline_access-enabled access token for this to work continuously (permissions documentation), and if that token changes, you'll have to log in yourself and refresh that token (it can change when you change your password or uninstall/reinstall the app). Additionally you'll need a manage_pages permission, and you'll need to use the access_token for your page that you can find in /me/accounts to make posts to the page.

Resources