-
Notifications
You must be signed in to change notification settings - Fork 219
v2.0
Whether you are building an ASP.NET or OWIN web app or web API, or a daemon application running on .NET Framework, or .NET Core, you can now use the same interface to acquire tokens to call (downstream) web APIs:
- GraphServiceClient to call Microsoft graph
- IDownstreamRestApi to call a REST downstream API other than Microsoft Graph, having Microsoft Identity Web taking care of the details about authentication tokens and protocols.
- IAuthorizationHeaderProvider to compute the authorization header to call a downstream API, if you can't use IDownstreamRestApi.
- ITokenAcquirer to acquire a token, if you need to use an SDK that needs a token (usually this SDK would only support bearer tokens)
You can use one configuration for all the platforms, in JSON, and inspired from the ASP.NET Core configuration.
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com",
"TenantId": "common",
"ClientId": "GUID", // from app registration
"EnablePiiLogging": false, // set to true to enable PII
// Computed. but overridable (and also to support other IdPs than AAD)
"Authority": "https://login.microsoftonline.com/common/v2.0",
// If the app calls downstream APIs
"ClientCredentials": [
{
"SourceType": "SignedAssertionFromManagedIdentity",
"ManagedIdentityClientId": "GUID of user assigned Managed identity"
},
{
"SourceType": "KeyVault",
"KeyVaultUrl": "https://webappsapistests.vault.azure.net",
"KeyVaultCertificateName": "Self-Signed-5-5-22"
},
{
"SourceType": "ClientSecret",
"ClientSecret": "***"
}
],
"SendX5C": false, // Can we omit?
// If the app is a web API
"TokenDecryptionCredentials": [
{
"SourceType": "KeyVault",
"KeyVaultUrl": "https://webappsapistests.vault.azure.net",
"KeyVaultCertificateName": "Self-Signed-5-5-22"
}
],
"AllowWebApiToBeAuthorizedByACL": false,
// If the app is a web app:
"ResetPasswordPath": "/MicrosoftIdentity/Account/ResetPassword",
"ErrorPath": "/MicrosoftIdentity/Account/Error",
"WithSpaAuthCode": false,
"Audience": "GUID",
"Audiences": [],
"AzureRegion" : "TryAutoDetect",
// B2C Specific
"Domain": "microsoft.com",
"EditProfilePolicyId": null,
"SignUpSignInPolicyId": null,
"ResetPasswordPolicyId": null,
"DefaultUserFlow": null
},
// Downstream APIs
"DownstreamApis": [
{
"GraphBeta": {
"BaseUrl": "https://graph.microsoft.com/beta",
"Scopes": "user.read"
}
}
],
"Logging": {
}
}
For ASP.NET Core, see web apps and web APIs
IAppBuilder now has extension methods:
- AddMicrosoftIdentityWebApp (which supports guest accounts)
- AddMicrosoftIdentityWebApi
From the Controllers, it's possible to get an instance of GraphServiceClient, ITokenAcquirer, and IAuthorizationHeaderProvider
The full code is available from tests\aspnet-mvc\OwinWebApp
The Startup.auth.cs can now be:
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Cookies;
using Owin;
using Microsoft.Identity.Web;
using Microsoft.Identity.Web.TokenCacheProviders.InMemory;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Identity.Client;
namespace OwinWebApp
{
public partial class Startup
{
public void ConfigureAuth(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.AddMicrosoftIdentityWebApp(configureServices: services =>
{
services.Configure<ConfidentialClientApplicationOptions>(options =>
{ options.RedirectUri = "https://localhost:44386/"; });
services.AddMicrosoftGraph();
services.AddInMemoryTokenCaches();
});
}
}
}
The full code is available from tests\aspnet-mvc\OwinWebApi
using Owin;
using Microsoft.Identity.Web;
using Microsoft.IdentityModel.Logging;
using Microsoft.Identity.Web.TokenCacheProviders.InMemory;
using System.Diagnostics.Tracing;
using System.IO;
using System;
namespace OwinWebApi
{
public partial class Startup
{
// For more information on configuring authentication, please visit https://go.microsoft.com/fwlink/?LinkId=301864
public void ConfigureAuth(IAppBuilder app)
{
app.AddMicrosoftIdentityWebApi(configureServices: services =>
{
services.AddMicrosoftGraph();
services.AddInMemoryTokenCaches();
});
}
}
}
[Authorize]
public class TodoListController : ApiController
{
private static readonly Dictionary<int, Todo> todoStore = new Dictionary<int, Todo>();
// GET api/values
public async Task<IEnumerable<Todo>> Get()
{
// Example calling Graph
GraphServiceClient? graphServiceClient = this.GetGraphServiceClient();
var me = await graphServiceClient?.Me?.Request()?.GetAsync();
// Example getting a token to call a downstream web API
ITokenAcquirer tokenAcquirer = this.GetTokenAcquirer();
var result = await tokenAcquirer.GetTokenForUserAsync(new[] { "user.read" });
The full code is available from tests/daemon-app/Daemon-app/Program.cs
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Graph;
using Microsoft.Identity.Web;
using Microsoft.Identity.Web.TokenCacheProviders.Distributed;
namespace daemon_console
{
/// <summary>
/// This sample shows how to query the Microsoft Graph from a daemon application
/// which uses application permissions.
/// For more information see https://aka.ms/msal-net-client-credentials
/// </summary>
class Program
{
static async Task Main(string[] args)
{
TokenAcquirerFactory tokenAcquirerFactory = TokenAcquirerFactory.GetDefaultInstance();
IConfiguration configuration = tokenAcquirerFactory.Configuration;
IServiceCollection services = tokenAcquirerFactory.Services;
services.Configure<MicrosoftAuthenticationOptions>(option => configuration.Bind(option));
services.AddMicrosoftGraph(); // or services.AddTokenAcquisition() if you don't need graph
// Add a cache
services.AddDistributedTokenCaches();
var serviceProvider = tokenAcquirerFactory.Build();
// Example of usage of Microsoft Graph
GraphServiceClient graphServiceClient = serviceProvider.GetRequiredService<GraphServiceClient>();
var users = await graphServiceClient.Users
.Request()
.WithAppOnly()
.WithAuthenticationOptions(options => options.ProtocolScheme = "Bearer")
.GetAsync();
Console.WriteLine($"{users.Count} users");
// Get the authorization request creator service
IAuthorizationHeaderProvider authorizationHeaderProvider = serviceProvider.GetRequiredService<IAuthorizationHeaderProvider>();
string authorizationHeader = await authorizationHeaderProvider.CreateAuthorizationHeaderForAppAsync("https://graph.microsoft.com/.default");
Console.WriteLine(authorizationHeader.Substring(0, authorizationHeader.IndexOf(" ")+4)+"...");
// Example of getting a token to call a dowstream web API
ITokenAcquirer tokenAcquirer = tokenAcquirerFactory.GetTokenAcquirer();
var result = await tokenAcquirer.GetTokenForAppAsync("https://graph.microsoft.com/.default");
Console.WriteLine($"Token expires on {result.ExpiresOn}");
}
}
}
When you use the Graph, you can now augment the request with WithAuthenticationOptions, which provides you with all the control you need.
var users = await graphServiceClient.Users
.Request()
.WithAppOnly()
.WithAuthenticationOptions(options => options.ProtocolScheme = "Bearer")
.GetAsync();
In the past, Microsoft.Identity.Web was exposing the MicrosoftAuthenticationOptions, but this was:
- only on ASP.NET Core
- and it inherited from OpenIdConnectOptions.
In v2.0, Microsoft.Identity.Web proposes the notion of MicrosoftAuthenticationOptions (specific to AAD), inheriting from AuthenticationOptions (standard compliant), and makes these available in OWIN and SDK/daemon scenarios as well as in ASP.NET Core
Between x3 and x6 for an end to end call to web API calling graph.
In Microsoft.Identity.Web 1.x, you could specify the ClientCertificates, in many different ways.
From Microsoft.Identity.Web 2.x, you can now specify ClientCredentials. In addition to certificates, (and client secrets), you'll be able to specify signed assertions generated by Managed identity, for instance when the app is hosted in Kubernates, leveraging the identity federation for Kubernates based on PodIdentity.
Microsoft.Identity.Web will try the credentials in the order you specify them, which means you can try things out locally, or deployed, seamlessly.
More credentials will be available as Azure AD supports them.
You can also now provide the UserAssignedManagedIdentityClientId per credential, instead of providing it statically for the application.
If you have specific ways to load your certificates, not supported by Microsoft.Identity.Web, you can add your own credential loader to the _credentialLoaders property of DefaultCertificateLoader
. For this, implement the ICredentialLoader
interface, and assign a value other than the enumerations in CredentialSource
.
/// <summary>
/// Interface to implement loading of credentials.
/// </summary>
public interface ICredentialLoader
{
/// <summary>
/// Load the credential from the description, if needed.
/// </summary>
/// <param name="credentialDescription">Description of the credential.</param>
void LoadIfNeeded(CredentialDescription credentialDescription);
/// <summary>
/// Loadable CredentialSource.
/// </summary>
CredentialSource CredentialSource { get; }
}
- The code is distributed in different assemblies
- You won't have any breaking change if you were already doing the right thing with the authentication schemes (that is when you configure options you are already specifying an authentication scheme)
- Home
- Why use Microsoft Identity Web?
- Web apps
- Web APIs
- Using certificates
- Minimal support for .NET FW Classic
- Logging
- Azure AD B2C limitations
- Samples
- Web apps
- Web app samples
- Web app template
- Call an API from a web app
- Managing incremental consent and conditional access
- Web app troubleshooting
- Deploy to App Services Linux containers or with proxies
- SameSite cookies
- Hybrid SPA
- Web APIs
- Web API samples
- Web API template
- Call an API from a web API
- Token Decryption
- Web API troubleshooting
- web API protected by ACLs instead of app roles
- gRPC apps
- Azure Functions
- Long running processes in web APIs
- Authorization policies
- Generic API
- Customization
- Logging
- Calling graph with specific scopes/tenant
- Multiple Authentication Schemes
- Utility classes
- Setting FIC+MSI
- Mixing web app and web API
- Deploying to Azure App Services
- Azure AD B2C issuer claim support
- Performance
- specify Microsoft Graph scopes and app-permissions
- Integrate with Azure App Services authentication
- Ajax calls and incremental consent and conditional access
- Back channel proxys
- Client capabilities