.NET Core/6.0 MVC + Windows Authentication + Microsoft Graph - .net-core

I have built a web-based MVC application in .Net 6.0 that has been in use for years within my company (upgraded recently to 6.0, of course). One of the functions of the app has allowed internal users to send emails and this was working through the Office 365 SMTP until recently. Our parent company introduced MFA and since then, the email function is broken and alternative methods I have implemented are only half working. Based on my research, Microsoft Graph seems to be a good way to replace this email functionality, however I'm lost on how to implement it with my current app.
The application is hosted on our own server with IIS and uses Windows Authentication. What I have not been able to find is a step-by-step guide on how to implement Microsoft Graph API with this setup. I'm completely self-taught and maintain this app on the side, rather than as my main job. All of the examples I've found aren't particularly helpful on the "here's how".
What I do know is that I need to have the app registered in Azure AD. I've spoken with our admin, and that won't be a problem once I know what I need to do. With .NET Core (.NET 6.0), MVC, Windows Authentication, hosted on an internal server with IIS:
Is it possible to implement the Microsoft Graph API? (I believe the answer is yes)
Is there a good step-by-step guide on exactly what I would need to do?
The closest thing I've found is this: https://learn.microsoft.com/en-us/samples/azure-samples/active-directory-dotnet-iwa-v2/active-directory-dotnet-iwa-v2/
Unfortunately, I'm mostly just staring at the code, not able to figure out how I can make use of most of it. I'd appreciate any guidance or recommendations.

Let's tidy up the ideas first.
You have realized windows authentication, that means you can know who is signed in now, or in other words, your sending-email funtion knows who is the sender. Then you also need a page to let users set receive and CC list, subject and email content.
Then you want to use graph api to send email. This required you to have an azure ad application which has Mail.Send permission which permission type is Application(I think using this kind of permission is a good choice in your scenario). By the way, you also need to make sure email senders has their corresponding accounts in azure ad. Because graph api need to know who is the sender, and sender is required to be a member in the tenant which the azure ad application is registered(users outside the tenant can't use the resource in the tenant, right?). For example, users' account information are stored in your local database, and your app linked to your localbase, so your app knows who is the user, but when you try to use graph api/azure ad, you also make sure azure ad know who is the user, so azure ad can authenticate and graph api can know who is the user than allow the user call api.
Normally, in our application, we try to integrate azure ad so that users in azure ad can use their azure ad accounts to sign in, then use the authentication by azure ad, they can call graph api to do some actions. In you scenario, you didn't integrate azure ad authentication, so that using client credential flow to authenticate your app to call graph api is better, so I said give "Application" permission is better. You may refer to this answer and try the sample code in it.
In the code sample, it requires you to set user id as one of the input parameter. If the user passed windows authentication, I trust you can get the user id, but you need to make sure the user id is the same in azure ad. If not, you may also need to set up a matching relationship.

Related

Change from (local) windows authentication to ADFS

At least I think I mean ADFS?!
ok so I have created and deployed a simple asp.net web app that staff use.
It uses windows authentication. The windows account is local to the server as this server is in the DMZ.
This works fine but has become more popular that I thought and is now being used across the Organisation.
Obviously I now have an issue whereby any staff that leave the organisation will still have access to this web app. Not good! Rather than have a whole new forms based account management system I though ADFS may be the answer. This is not my area of expertise so bear with me if I go up the wrong road or use nonsense jargon. Our AD is on premise but we sync this to the MS cloud so we can use NT accounts for 365 apps and SSO for a 3rd party web based product. I would like my web app to do the same as the 3rd party web based app.
I have Googled plenty but soon get lost among the ADFS/OWIN/OAuth speak.
If I knew the exact search term to fit my scenario I could go back to my research... If someone could point me to an article that shows how to do exactly what I need without me having to do a crash course on SAML etc that would be awesome too.
Firstly, agree on on/off-boarding policy, ADFS will not fix that since ADFS authenticates against AD. Neither will Azure AD.
You can go two ways:
Install ADFS. Then you get SSO across all apps. But rather go with Azure AD.
Use Azure AD. Your users are already synched up to Azure AD for O365.
You can use OpenID Connect rather than SAML.
There are a number of samples to guide you here.
Think you want to still use windows authentication but instead of local accounts create and use domain user accounts. The DC will be able to validate accordingly. As far as staff leaving and still having access you need a policy in place which disables/deletes the user account object in the AD when they leave the company so the account no longer exists or is enabled.

How to create new .NET application with Individual User Accounts using Active Directory?

I want to create a new .NET application with implemented Individual User Accounts.
Actually, there is no more possible to create it with users stored in local DB so Active Directory is necessary.
I created AD on Azure but have no clue how to fill this form.
I have a problem with all three inputs.
I have 3 question:
How to fill this form?
Is there any reason why I should implement Authentication by myself.
Is there other solution to get authentication out of the box? (like template with already implemented authentication)
To answer your first question, filling out the form, you will need to get these details from the Azure AD you setup. The Domain Name is the domain you created in Azure Ad. The Application ID is the guid you got when you registered your application in your Azure AD. The last field, Sign-up or sign-in policy, is the Azure AD policy you want to use to manage people signing up for your service as well as signing into your service.
The problem is, setting up your Azure AD is only one step out of many. What you should be learning how to do is setting up Single Sign On (SSO) using Azure AD. For that, I suggest looking at Authentication Scenarios for Azure AD, What is application access and single sign-on with Azure Active Directory? and Azure Active Directory B2C: Built-in policies. These series of articles should put you on the right path to get started with using Azure AD.
Your second question can be subjective, so I'll simply point things you will need to concern yourself with if you try to implement your own authentication. The biggest problem with doing it your self is making sure you have addressed the necessary security concerns. You will need to have your passwords stored securely which means salting and hashing them (I suggest Googling if you aren't aware of those term). You will also need to handle scenarios like password reset, forgetting user name and/or handling inactive or disabled user accounts. Many organizations and developers like using third party providers for SSO so they don't have to deal with such issues.
For your last question, yes there are. Microsoft does include a basic one with their web project templates (if you choose) and there are other providers out there such as Google or Facebook. There are many other options out there that are open source. A quick search on NuGet yielded over 2k results (https://www.nuget.org/packages?q=user+authentication).

Authorization method for REST API utilising Active Directory

What is the best method of securing a REST Web API with the following requirements. The system has an Angular JS frontend with the REST APIs implemented in ASP.net.
There are two "roles" in the system, users will have one of the
roles. One role should allows access to some APIs (call it "VIEW"),
the other role allows access to other APIs
All users are in Active Directory, so if I have a username, I can check what role they are in- Some clients are on Windows boxes, the others are on Linux
I would like to persist the session so I don't have to look up AD for every API call
I would like single sign on. On the Windows machines, I don't require them to enter user and pass as I already can retrieve their username using Windows Authentication.
I believe that Oauth would be my best option.
There are two "roles" in the system, users will have one of the roles.
One role should allows access to some APIs (call it "VIEW"), the other
role allows access to other APIs
For role based authentication, you can use [Authorize("Role" = "Manager")]. The token will be provided by the identity server and will contain the claim as Role.
All users are in Active Directory, so if I have a username, I can
check what role they are in- Some clients are on Windows boxes, the
others are on Linux
If you have ADFS then you can have an Identity server that trusts the ADFS. The ADFS will provide a token which will have the claim for role and your Identity Server will do the claims transformation and will return the same Role claim back to angular app.
I would like to persist the session so I don't have to look up AD for
every API call
For this while requesting the token, you can ask for offline scope so the Identity server will provide the Refresh Token with Access Token so you don't need to ask for AD again and again.
I would like single sign on. On the Windows machines, I don't require
them to enter user and pass as I already can retrieve their username
using Windows Authentication.
For this one, you can have your Identity sever trust the WSFederation for windows Authentication.
So basically you need to setup Identity server that will provide you with the token and the REST API will use that token to verify claims to return the correct information back to the user.
I am not sure what you expect exactly. Anyway, first I'm gonna reformulate your question with requirements:
you accounts and role are in active directory
you want to manage roles based on an active directory group
you want anybody whatever the system (windows, linux, mac, mobile...) to connect on your application using the same authentication
you want to avoid your AD to be hit constantly (not at any call for example)
if the user is connected on an application that uses the authentication system, he doesn't have to do it so again on another application that uses the same authentication system
If these requirements are yours. I believe the only standard (and clean) solution is to use OAuth. I'm not gonna go in detailed description of OAuth, but this authentication protocol is the most standard one on the net (facebook, google, twitter...). Of course as you don't want to use facebook, google or twitter accounts in your business applications but your active directory accounts you'll have to install/setup/develop your OAuth identity provider using accounts of your active active directory server. Your choice will depend on how well you know ADFS protocol and its different flows (code, implicit, assersion) You have two solutions for it:
Use ADFS: install ADFS; it provides a OAuth portal that will work out of the box with asp.net mvc. This uses the code flow of OAuth that is the only OAuth flow supported by ADFS. For roles and its related AD groups, you'll have to map role claims with AD groups. (it's in the setup of adfs, you'll find many tutos on the net). You'll find lot of tutos as well about how to use ADFS with asp.net mvc/asp.net webapi. I mention .net here, but every technology has an implementation for OAuth authentication (nodeJs/express, php, java...).
Use thinktecture identity server (.net technology). This will provide all the foundation to implement a custom identity server with the least effort: http://www.thinktecture.com/identityserver / https://github.com/IdentityServer/IdentityServer3. It contains an addin to plug its accounts to active directory. With this, you can use implicit and assertion flows.
Use oauth2orize (for nodeJs): https://www.npmjs.com/package/oauth2orize. This will permit you to make the same than thinktecture identity server but in nodeJs. Apparently you'll have to make all the wirering with ad manually. With this, you can use implicit flows (not sure about assertion flows).
At application side, most of frameworks can authenticate easily using OAuth with a lot of existing frameworks. For example, even if you make a single page application, you can use adal.js or oidc.js for angular if you use angular. As I mentioned above, all this is taken in charge by asp.net mvc/webapi out of the box but I know it's the case for other server technologies. If you have more questions, don't hesitate as I'm not sure of what you expect exactly.

Retrieving all users and roles in a .NET Web Application through ADFS

We have a hosted .NET web application (Windows Server 2012 R2 environment) and we need to provide Single sign-on (SSO) to users from a corporate LAN environment. We have used ADFS to enable SSO and it is working as expected thus when a user hits our web application login page URL he is authenticated against ADFS and is automatically logged in to the application.
We have an additional requirement where we need to obtain a list of all users, their groups, email addresses some additional information periodically from their Active Directory so that this information can be bulk loaded into our web application however since ADFS is implemented we do not have direct access to the Active Directory.
Is it possible to connect to ADFS and obtain a list of all users, their email addresses etc. programmatically?
If the above is not possible then what is the recommended approach for this kind of a setup?
Thank you.
No, this is not possible. There is no such API because with SAML and WS-Federation, users can come from anywhere. This does not have to be AD, technically it's possible create a "Log in with Facebook" implementation.
What would you need the information for? The user's claims contain all information which you might need (user name, e-mail address, group memberships).
If you really need that information about all users in your application, perhaps ADFS is not the solution you are looking for.
As Alex mentioned above - the way it works, ADFS does not provide any way of importing data from the AD or other trust stores. It just gives you the information that are carried over with the token.
In case you need more information, you should extend the number of claims being issued by ADFS. You can then collect the information - when the user comes for the first time, use the data from the token and fill the profile. If it is returning user - update the information if necessary.
The other solution (but I wouldn't say it's recommended - rather a workaround) would be to implement custom solution for importing information from AD to your application. I'd say it's fair as long as you use your local AD for reading this data. In the moment you decide to extend the access to third party (e.g. partner company), which might be using different identity provider, which doesn't have to be backed by Active Directory any more - you find yourself in tough spot.

Azure users roles and user profile management

I have a windows azure application already running.(testing phase). Currently I use ACS authentication. users can log on with their windows live-ID. and this is all. no authorisation for now. I need to authorise users with different roles. plus I need also users to log on with different Identity providers like gmail and facebook. I have the idea to store profile information in a table (eg. Idp as partition key and User ID(which I get from the provider)as RowKey.)
Now I have have no idea how to give different roles and how to start? can any body give me a clear tutorial or just an idea how to begin with?
tnx
I suggest you take a look at the BlobShare application. This isn't a tutorial, but it's a complete application showing a few interesting concepts you could use:
The BlobShare Sample is a simple file sharing application that
demonstrates the storage services of the Windows Azure Platform,
together with the authentication and authorization capabilities of
Access Control Service (ACS).
http://blobshare.codeplex.com/

Resources