using System; using System.Collections.Generic; using System.Configuration; using System.Linq; using System.Security.Claims; using System.Security.Cryptography.X509Certificates; using System.Threading.Tasks; using Microsoft.Identity.Client; using Microsoft.InformationProtection; namespace AipGateway.AIP { public class AuthDelegateImplementation : IAuthDelegate { private static string _clientId = ""; private static string thumbprint = ""; private static bool doCertAuth = false; private static string _clientSecret = ""; private ClaimsPrincipal _claimsPrincipal; public AuthDelegateImplementation(string clientId, string clientSecret, ClaimsPrincipal claimsPrincipal) { _clientId = clientId; _clientSecret = clientSecret; _claimsPrincipal = claimsPrincipal; } public string AcquireToken(Identity identity, string authority, string resource, string claim) { var authResult = Task.Run(async () => await GetAccessTokenOnBehalfOfUser(authority, resource)); return authResult.Result; } public async Task GetAccessTokenOnBehalfOfUser(string authority, string resource) { IConfidentialClientApplication _app; AuthenticationResult result; if (doCertAuth) { // Read X509 cert from local store and build ClientAssertionCertificate. X509Certificate2 cert = Utilities.ReadCertificateFromStore(thumbprint); // Create confidential client using certificate. _app = ConfidentialClientApplicationBuilder.Create(_clientId) .WithRedirectUri(resource) .WithAuthority(authority) .WithCertificate(cert) .Build(); } else { // Create confidential client using client secret. _app = ConfidentialClientApplicationBuilder.Create(_clientId) .WithRedirectUri(resource) .WithAuthority(authority) .WithClientSecret(_clientSecret) .Build(); } // Store user access token of authenticated user. var ci = (ClaimsIdentity)_claimsPrincipal.Identity; string userAccessToken = (string)ci.BootstrapContext; // Generate a user assertion with the UPN and access token. UserAssertion userAssertion = new UserAssertion(userAccessToken, "urn:ietf:params:oauth:grant-type:jwt-bearer"); // Append .default to the resource passed in to AcquireToken(). List scopes = new List() { resource[resource.Length - 1].Equals('/') ? $"{resource}.default" : $"{resource}/.default" }; result = await _app.AcquireTokenOnBehalfOf(scopes, userAssertion) .ExecuteAsync(); // Return the token to the API caller return (result.AccessToken); } } }