How can I get roles from AD with MVC Azure AD Authentication? - asp.net-mvc

I setup and MVC 4 application and added authentication against our Azure AD server as outlined here: http://msdn.microsoft.com/en-us/library/windowsazure/dn151790.aspx
Authentication works as expected. However, I'm not getting any roles back by default. There should be several AD groups created and I would like to use them to role restrict the application via the [Authorize] attribute in MVC.
I can't really find a good place to even start figuring this out. Can anyone give me an outline or point me to a good tutorial?
I should mention that I'm not the administrator for our Azure account, so I need to be able to tell our admin what to do if any setup is required on that side.

First, tokens returned by Azure AD do not currently contain claims for roles or groups, so you need to get them from the Graph API. Second, roles in Azure AD that are returned by the Graph API are not necessarily intended for use in an ISV/LoB app, and in general you should use security groups for authorization instead. To perform authorization, you should use the checkMemberGroups or getMemberGroups operations in the Graph API, which are transitive and valid for this purpose.
If you check out the following resources in order, I think your questions will be answered. You'll learn how to authenticate to the Graph, call it, and configure your application to use the result of the group operations to perform authorization:
Using the Graph API to Query Windows Azure AD -- This is the second walkthrough to complete now that you've done the web SSO one.
Authorization with Windows Azure Active Directory
MVC Sample App for Azure AD Graph
Blog post describing checkMemberGroups and getMemberGroups
How do I get role and group membership claims for users signing in via Windows Azure AD? -- This one is out of date in regards to the methodology for authentication and the UI for managing users/groups, but it's still useful. Pay special attention to the section on the custom ClaimsAuthenticationManager, which gives you an idea of how to inject role/group data into the ClaimsPrincipal object early so that it can be used in the [Authorize] attribute or other authorization logic.

Sean answer is a bit outdated. You can now configure Azure AD so it will include groups or roles inside JWT token so it will be included into ClaimsPrincipal.Current.Claims so standard [Authorize(Roles = "yourRoleName")] attribute will work.
Here is introduction post. Which basically says you have two options:
Use groups claim - you need to change groupMembershipClaims value in app manifest and later in application you can check for ClaimsPrincipal.Current.FindFirst("groups").Value to see in what group user is (you only get group id). You can write you own Authorize attribute that use this. more info
Define roles for you application and then use normal code for testing if user is in role:
[PrincipalPermission(SecurityAction.Demand, Role = “yourRoleName”)]
[Authorize(Roles = “yourRoleName”)]
if (ClaimsPrincipal.Current.IsInRole(“yourRoleName”)) { //do something }
You need to edit roles in you app's manifest.
More info here and here. Values needed to be set in manifest are described here
What is really strange is that you can't assign more than one role to group from Azure web page. You need to use azure graph api for this.
If you can't see Users and Groups tab in Azure portal you probably need Azure AD Basic or Premium edition. If you are working on free azure subscription you can use free Azure AD Premium trial to test stuff.

Related

Using Azure AD to secure a aspnet webapi

I'm writing an application that will be the backend for a react website. The website is to be used by our customers, but we will fully control the permissions of the user. We have decided to use Azure AD to secure requests, but will also be exposing the API for end users to use directly if desired.
My understanding is in Azure AD I will have to create an application that will allow web based implicit authentication (for the react site), as well as a native application that will allow a dameon based application to authenticate to the API.
This I believe means I will have two audience ids in my application.
I'm trying to get claims to include groups, and I can see if I edit the meta data of both applicaitons in azure AD to include "groupMembershipClaims": "SecurityGroup" I can get claims with the group IDs in, but no names.
I think I can also use appRoles to set roles the application uses, but I've yet to get that to come through as claims in the JWT, but I'm assuming it can be done, however I'd need to setup the roles on each applicaiton, then add the user twice which isn't really ideal. I also think that because my app is multi-teanated that external users could use this to set their own permissions, which isn't what I want to do.
Sorry I'm just totally lost and the documentation is beyond confusing given how frequently this appears to change!
TLDR: Do I need two applicaitons configured in azure ad, and if so whats the best way to set permissions (claims). Also is oAuth 2 the right choice here, or should I look at open id?
Right away I gotta fix one misunderstanding.
Daemon apps usually have to be registered as Web/API, i.e. publicClient: false.
That's because a native app can't have client secrets.
Of course the daemon can't run on a user's device then.
Since that's what a native app. An app that runs on a user's device.
This I believe means I will have two audience ids in my application.
You will have two applications, at least. If you want, the back-end and React front can share one app (with implicit flow enabled). And the daemon will need another registration.
I'm trying to get claims to include groups, and I can see if I edit the meta data of both applicaitons in azure AD to include "groupMembershipClaims": "SecurityGroup" I can get claims with the group IDs in, but no names.
Yes, ids are included only. If you need names, you go to Graph API to get them. But why do you need them? For display? Otherwise, you need to be using the ids to setup permissions. Names always change and then your code breaks.
I think I can also use appRoles to set roles the application uses, but I've yet to get that to come through as claims in the JWT, but I'm assuming it can be done, however I'd need to setup the roles on each applicaiton, then add the user twice which isn't really ideal. I also think that because my app is multi-teanated that external users could use this to set their own permissions, which isn't what I want to do.
Your thoughts for multi-tenant scenarios are correct. If you did want to implement these though, I made an article on it: https://joonasw.net/view/defining-permissions-and-roles-in-aad.
Why would you need to setup the roles in multiple apps though? Wouldn't they only apply in the web app?
If the native app is a daemon, there is no user.
Overall, I can see your problem. You have people from other orgs, who want access to your app, but you want to control their access rights.
Honestly, the best way might be to make the app single-tenant in some tenant which you control. Then invite the external users there as guests (there's an API for this). Then you can assign them roles by using groups or appRoles.
If I misunderstood something, drop a comment and I'll fix up my answer.
Azure AD is of course a powerful system, though I also find the OAuth aspects confusing since these aspects are very mixed up:
Standards Based OAuth 2.0 and Open Id Connect
Microsoft Vendor Specific Behaviour
ROLE RELATED ANSWERS
This is not an area I know much about - Juunas seems like a great guy to help you with this.
OAUTH STANDARDS AND AZURE
I struggled through this a while back for a tutorial based OAuth blog I'm writing. Maybe some of the stuff I learned and wrote up is useful to you.
AZURE SPA AND API CODE SAMPLE
My sample shows how to use the Implicit Flow in an SPA to log the user in via Azure AD, then how to validate received tokens in a custom API:
Code Sample
Write Up
Not sure how much of this is relevant to your use case, but I hope it helps a little on the tech side of things...

ASP.NET Core OpenId Authentication

im developing a .net core mvc application with authentication against azure active Directory. My Problem is, that i have two different azure avtice directories which are undepentandend to eachother. Based on the user Input (mail or employenumber) i will decide which active Directory should used.
Any idea or reference?
Thank You!
You're describing a multi-tenant application where the AAD common endpoint is used as the entry point to the application rather than a specific AAD login page. You can configure your application to trust more than one AAD instance. It's rather involved, but MS had good documentation on how to adopt a single tenant app to multi-tenant. I'd also highly recommend Vittirio's blog as a place to learn about AAD auth, and while you're at it, his book titled 'Modern Authentication with Azure Active Directory for Web Applications'
Once you've turned on multitenancy for your application, you'll want to handle AAD validation yourself by checking the tenant id in the incoming SSO request. You do this by overriding SecurityTokenValidated in UseOpenIdConnectAuthentication. You can refer to this example where the code validates against a database.
There are other considerations such as admin consent where an AAD admin has to grant access to restricted permissions to your application. Good explaination here.
There is a very good reliable open-source project for that (Identity Server)
https://github.com/IdentityServer/IdentityServer4
And also you can check that (openiddict)
https://github.com/openiddict/openiddict-core

URL-based access management using Azure AD

I have simple ASP.NET MVC survey generator, that based on the URL displays various forms and persists data input from user:
http://survey.mydomain.com/ConferenceFeedback
http://survey.mydomain.com/DailyReport
etc.
Some of these subapps should be accessible by everyone, some by specific set of users. My user store is Azure AD. Is there is any Azure AD related feature that is a good match for my authorization scenario, where I could assign user rights on Azure side and just validate some claims or roles in my app per user request?
You might want to look into application roles. You can define roles representing the various subapps you want to model, and you can assign users to them accordingly. On the application side, you can examine the incoming claims set and decide whether the user has the necessary role claims for accessing the portion of the app they are requesting. See https://github.com/Azure-Samples/active-directory-dotnet-webapp-roleclaims for a sample app demonstrating the approach.

MVC5 Azure Active Directory Role-Based Authentication Visual Studio 2013

I have an MVC5 website that was created in Visual Studio 2013. It was set up from the start to use Organizational Authentication using a single-tenant single-sign on. There is no way to access any part of the site without logging in with an account that has the correct domain. This is the desired function.
However, I am looking to add role-based authentication using Azure Active Directory. The desired functionality is that some users in certain groups can see some pages, and people in other groups can see different pages, etc. This seems like the most relevant/updated tutorial https://github.com/AzureADSamples/WebApp-GraphAPI-DotNet. But since I already use WS-Federation to login with an organizational account, do I really have to use OpenID type authentication as stated in the tutorial? It seems like there should be an easy way to get the roles once I'm already logged in. I know I probably have to use the Graph API in some sense but I don't know how. Please advise.
At sign-in, when the user arrives at you app with an SSO token - your application can query the directory Graph API to determine the users group memberships. Per the group memberships you can either grant permissions to the user directly or map the group membership to a "role" in you application.
We have a topic that explains this in more detail and a sample application (that uses WSFed) to perform role-based authorization using Azure AD group memberships: http://msdn.microsoft.com/en-us/library/azure/dn195601.aspx
Enjoy :-)

Setting up an ASP.NET MVC 5 application to authenticate in my own Authentication Server

Context:
We have a monster ASP.NET MVC 5/Framework 4.5 application that is planned to be divided in several others, so each new application will deal with a specific business domain instead of many. All those applications together will provide the same functionalities and services that are provided today by the existing single application.
We plan to use our own OAuth server to provide authentication and authorization for all the new smaller applications, so the very same users that use the current large application will have the same rights in the same functionality.
Currently we use Windows Authentication mixed with a secondary custom structure to establish what a certain user can do. We have our own role provider to generate the roles assigned to the users. When a certain controller action asks for the list of roles af a certain user, our role provider search in our custom structure and provide those roles, following specific business rules that make sense in our application.
We understand that the same rules that establish the set of the roles assigned to a certain user will be moved to our OAuth server.
We understand that the role-based security will be replaced by a claim-based security.
We understand that we will stop testing for roles and start testing for claims.
We understand that the first step of this refactoring should be add external authentication in our current large application and then start to break it into parts so we will have our new ecosystem.
Question:
How to change my current large application so it authenticate and authorize requests by using the new OAuth server instead by itself?
Note:
I´ve read a lot of blog posts but so far I couldn´t find a simple code sample that shows me what to do to instruct my application to go for an authentication/authorization token in my OAuth server and use it to grant or deny the access to a given controller action.

Resources