I'm using the Microsoft.Owin
middleware to authenticate users against Azure AD when they visit my page.
App_Start > Startup.cs
using Owin;
using System.Configuration;
using System.Globalization;
using Microsoft.Owin;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.OpenIdConnect;
using Microsoft.Owin.Extensions;
[assembly:OwinStartup(typeof(MyApp.App_Start.Startup))]
namespace MyApp.App_Start
{
public class Startup
{
private static string clientId = ConfigurationManager.AppSettings["ida:ClientId"];
private static string aadInstance = ConfigurationManager.AppSettings["ida:AADInstance"];
private static string tenant = ConfigurationManager.AppSettings["ida:Tenant"];
private static string postLogoutRedirectUri = ConfigurationManager.AppSettings["ida:PostLogoutRedirectUri"];
string authority = string.Format(CultureInfo.InvariantCulture, aadInstance, tenant);
public void Configuration(IAppBuilder app)
{
ConfigureAuth(app);
}
public void ConfigureAuth(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions() { });
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = clientId,
Authority = authority,
PostLogoutRedirectUri = postLogoutRedirectUri,
Notifications = new OpenIdConnectAuthenticationNotifications
{
AuthenticationFailed = (context) =>
{
context.HandleResponse();
context.Response.Redirect("/Error/message=" + context.Exception.Message);
return System.Threading.Tasks.Task.FromResult(0);
}
}
});
app.UseStageMarker(PipelineStage.Authenticate);
}
}
}
This is working fine, after they sign in I can use things like the ClaimsPrincipal
to get information about this user such as their ID:
string signedInUserID
= ClaimsPrincipal.Current.FindFirst(System.IdentityModel.Claims.ClaimTypes.NameIdentifier).Value;
string tenantID
= ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value;
string userObjectID
= ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;
I now want to silently authenticate against CRM Online as this user so I can pull data from the Web API. Is this possible, and if so, how?
I've been trying to follow the examples to acquire an access token via AuthenticationContext
which I seem to get successfully, but then I'm unable to query CRM Online, I get various errors about security. For the sake of brevity I won't list all the code here unless someone specifically needs to see it. Here's the MSDN article that gives the basics.
I can access CRM Online using the CrmConnection
class and a connection string with the username and password hard coded in as documented in this MSDN article but this isn't what I want. I want to authenticate as the currently logged in user.
Here are some of the samples I've been trying to follow in case they're useful to anyone else: https://github.com/azure-samples?query=active-directory
This is the closest post I've found to what I want but it still needs a username/password... Using ADAL C# as Confidential User /Daemon Server /Server-to-Server - 401 Unauthorized