Using Active Directory for Authentication locally and on Azure - asp.net-mvc

I'm developing an application for my company's internal use. We wish the application to live on Azure and to utilize windows accounts for authentication. We are working on enabling Active Directory Federation Servers (ADFS) in order to synchronize our organizational AD to Azure AD. While that is being done, I am working on code responsible for determining who a user is. My main goal is to restrict the Admin controller to those users who belong to an active directory group. My impression is that ADFS should allow me to query this in Azure.
I have created a service that utilizes LDAP to determine whether or not the current user is in a particular group, and it works great locally. However, through some reading, I've determined that LDAP is not supported by Azure AD. Darn!
The preferred route to communicate with the Azure AD seems to be the Graph API. However, the graph API does not seem to be support by an enterprise/organizational AD.
My first thought solve this is to utilize dependency inject to switch the service being used based on the environment, but I'm thinking there has to be a better way.
What technology should I be using to interact with both on-premise Active Directory, as well as Azure Active Directory?

We faced this same issue in our Azure implementation and discussed it at length with Microsoft. Currently there is no common method for directory queries. I believe Microsoft's plan is to eventually add GraphAPI to AD DS.
Another option, if you're using a claims-based authentication protocol like OpenID Connect, is to have the Identity Provider issue claims with the values needed for your authorization logic.

ADFS is a tool for identity federation and not directory sync. For directory sync you would use AADSync - http://www.microsoft.com/en-us/download/details.aspx?id=44225
The simplest way to achieve this is to use federation with ADFS and have ADFS populate the assertion with Role information. Set up a new relying party in ADFS and add the a new Issuance Transform Rule
Template: Send Group Membership as a claim
Name: Admin claim
Users Group: Choose your domain local group
Outgoing claim type: Role
Value: MyAdminRole
You can set up the federation very easily with Visual Studio 2012 or later or add an OWIN startup class such as the following:
public void ConfigureAuth(IAppBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseWsFederationAuthentication(new WsFederationAuthenticationOptions()
{
MetadataAddress = "https://adfs.domain.com/federationmetadata/2007-06/federationmetadata.xml",
Wtrealm = "urn:appid"
// SignInAsAuthenticationType = // This is picked up automatically from the default set above
});
AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;
}
Then all you need to do is add the Authorise attribute to your controllers:
[Authorize(Roles = "MyAdminRole")]
public class AdminController : Controller
{
...
}
For completeness, I will also add that once AADSync is configured and running, you can also use Graph API to obtain information about your users once it has been synced to Azure AD. User and Group updates can be delayed by upto 3 hours though.
HTH

Related

What is a required Oauth2 or SSO for our usecase

Our business use case is that we have four to five services deployed as java spring web applications. These services have user/customers derived from either registration process or some existing running applications exposed as rest services. We intend to make a single portal which provides users to be able to use a single account / credential to log into many services directly.
With internal approach we assume having individual customer table for each services. And a common Login table for all services whose id is tagged/mapped as foreign key in individual customer table of each services.
Also some services can be accessed without registration , in that case we fetch the data via customers account id from some third rest service and store it in individual services/application customer table and in common Login Table if not already present.
For services which require registration we store the customer credentials in login table if not present; and also in service/applications customer table with a common login table mapping.
But we need a secure portal with session tracking , session timeout just like Single Sign On
With some research we have narrowed the approach to implement the above scenario with either SSO or Oauth2 which her is applicable.
Refer the link (https://stormpath.com/blog/oauth-is-not-sso ) for more insight.
Can someone suggest which approach SSO or Oauth2 is applicable for our business usecase ?
if SSO , which is the best opensource simple SSO for java Spring applications?
if OAuth2 , what will act as Client application, Authorization Server , Resource Owner and Resource Server? As we have services(Java applications) as client application hosted in Common Application/Portal? will the common login table act as resource owner ?
You will likely want SpingSAML. If the applications are hosted on separate paths, like example.org/app1 and example.org/app2 then you could use a Shibboleth Service Provider as the SAML SP for the applications.
You'll still need an Identity Provider of some sort, which SpingSAML can't do, but there are innumerable IdP implementations out there: i.e. Shibboleth Identity Provider, ADFS, or a commercial IdP like Okta, OneLogin, Ping, etc.

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

Adding custom attributes to Azure AD Graph applications created in PowerShell

I am developing a Web API that talks to Azure AD Graph to get and update user and group information. So I have implemented a service application/service principal according to the article at https://learn.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-devquickstarts-graph-dotnet, using Windows PowerShell.
I now want to add some custom attributes to my application so that groups can have extra fields. However I can only see it in the Azure Portal when I refer to it by its specific application id and also I can't get to it using the AD Graph RESTful API at https://graph.windows.net/{mytenant}.onmicrosoft.com/applications or /{mytenant}.onmicrosoft.com/applications/{objectId}/extensionProperties and thus can't add any new custom attributes by using the corresponding POST endpoint.
Comparing my service application with other enterprise applications in my tenant, it also doesn't have a publisher showing in the enterprise applications blade.
Please can anyone advise whether this is supposed to work, and if so what am I missing by way of configuration?
thanks
Simon
The issue you are seeing here is due to the fact that the tutorial you followed had you create a Service Principal using AAD PowerShell, however the properties you are looking for are on the Application Object.
You can read more about the differences here.
Application object
An Azure AD application is defined by its one and only application
object, which resides in the Azure AD tenant where the application was
registered, known as the application's "home" tenant. The application
object provides identity-related information for an application, and
is the template from which its corresponding service principal
object(s) are derived for use at run-time.
Consider the application object as the global representation of your
application (for use across all tenants), and the service principal as
the local representation (for use in a specific tenant). The Azure AD
Graph Application entity defines the schema for an application object.
An application object therefore has a 1:1 relationship with the
software application, and a 1:n relationship with its corresponding n
service principal object(s).
Service principal object
The service principal object defines the policy and permissions for an
application, providing the basis for a security principal to represent
the application when accessing resources at run-time. The Azure AD
Graph ServicePrincipal entity defines the schema for a service
principal object.
Before an Azure AD tenant will allow an application to access the
resources it is securing, a service principal must be created in the
given tenant. The service principal provides the basis for Azure AD to
secure the application's access to resources owned by users from that
tenant. A single-tenant application will have only one service
principal (in its home tenant). A multi-tenant Web application will
also have a service principal in each tenant where an administrator or
user(s) from that tenant have given consent, allowing it to access
their resources. Following consent, the service principal object will
be consulted for future authorization requests.
My suggestion is to use the Graph API/Portal UX/PowerShell to create an Application Object first, and then follow the tutorial by updating the service principal of the application you created.
Let me know if this helps!

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 :-)

How can I get roles from AD with MVC Azure AD Authentication?

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.

Resources