public async Task <String> GetOnBehalfOfAccessToken(string resourceId, string replyUrl)
        {
            string accessToken          = null;
            AuthenticationResult result = null;

            //      The Resource ID of the service we want to call.
            //      The current user's access token, from the current request's authorization header.
            //      The credentials of this application.
            //      The username (UPN or email) of the user calling the API
            //
            ClientCredential clientCred = new ClientCredential(ConfigHelper.ClientId, ConfigHelper.AppKey);

            if (ClaimsPrincipal.Current.Identities.First().BootstrapContext == null)
            {
                throw new Exception("BootstrapContext is null. Please modify the config 'saveSignInToken = true' to ensure that the original token is preserved.");
            }

            System.IdentityModel.Tokens.BootstrapContext bootstrapContext = new System.IdentityModel.Tokens.BootstrapContext(ClaimsPrincipal.Current.Identities.First().BootstrapContext.ToString());
            if (bootstrapContext == null || string.IsNullOrWhiteSpace(bootstrapContext.Token))
            {
                throw new Exception("Failed to obtain the BootstrapContext token. Please modify the config 'saveSignInToken = true' to ensure that the original token is preserved.");
            }

            string userAccessToken = bootstrapContext.Token;

            // The username (UPN or email) of the user calling the API
            string userName = ClaimsPrincipal.Current.FindFirst(ClaimTypes.Upn) != null?ClaimsPrincipal.Current.FindFirst(ClaimTypes.Upn).Value : ClaimsPrincipal.Current.FindFirst(ClaimTypes.Email).Value;

            if (string.IsNullOrWhiteSpace(userName))
            {
                throw new Exception("Failed to obtain the signed-in user's name or upn in the ClaimsPrincipal.Current.Claims collection.");
            }

            UserAssertion userAssertion = new UserAssertion(userAccessToken, OAuth2GrantTypeJwtBearer, userName);

            string userId = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value;
            AuthenticationContext authContext = new AuthenticationContext(this.Authority, this.TokenCache);

            try
            {
                result = await authContext.AcquireTokenSilentAsync(resourceId, clientCred, new UserIdentifier(Util.GetSignedInUsersObjectIdFromClaims(), UserIdentifierType.UniqueId));
            }
            catch (AdalException ex)
            {
                result = await authContext.AcquireTokenAsync(resourceId, clientCred, userAssertion);
            }

            accessToken = result.AccessToken;
            return(accessToken);
        }
        public async Task <TokenResultModel> GetTokenForAsync(string resource, IEnumerable <string> scopes = null)
        {
            ClientCredential clientCred = new ClientCredential(_aadClientId, _appSecret);
            ClaimsPrincipal  current    = ClaimsPrincipal.Current;

            if (current == null)
            {
                throw new AuthenticationException("Missing claims principal.");
            }

            System.IdentityModel.Tokens.BootstrapContext bootstrapContext = new System.IdentityModel.Tokens.BootstrapContext(current.Identities.First().BootstrapContext.ToString());

            if (bootstrapContext == null)
            {
                throw new AuthenticationException("bootstrapContext is null.");
            }

            string userName = current.FindFirst(ClaimTypes.Upn) != null
                ? current.FindFirst(ClaimTypes.Upn).Value
                : current.FindFirst(ClaimTypes.Email).Value;

            string        userAccessToken = bootstrapContext.Token;
            UserAssertion userAssertion   = new UserAssertion(userAccessToken, kGrantType, userName);

            string authority = String.Format(CultureInfo.InvariantCulture, _aadInstance, _aadTenant);
            string userId    = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value;
            AuthenticationContext authContext = new AuthenticationContext(authority);

            string userObjectID = (ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier"))?.Value;
            var    user         = new UserIdentifier(userObjectID, UserIdentifierType.UniqueId);

            try
            {
                _result = await authContext.AcquireTokenAsync(resource, clientCred, userAssertion);

                return(_result.ToTokenResult());
            }
            catch (AdalException ex)
            {
                throw new AuthenticationException(
                          $"Failed to authenticate on behalf of {userName}", ex);
            }
        }
Esempio n. 3
0
        public static async Task <object> CallApiOnBehalfOfUser()
        {
            if (!ClaimsPrincipal.Current.FindAll("https://schemas.microsoft.com/identity/claims/scope").Any(x => x.Value.Contains("user_impersonation")))
            {
                throw new HttpResponseException(new HttpResponseMessage {
                    StatusCode = HttpStatusCode.Unauthorized, ReasonPhrase = "The Scope claim does not contain 'user_impersonation' or scope claim not found"
                });
            }

            var authContext = new AuthenticationContext(Authority, false);

            // ClientId needs to be audience/target resource, can't be guid?!
            // See https://docs.microsoft.com/sv-se/windows-server/identity/ad-fs/development/ad-fs-on-behalf-of-authentication-in-windows-server
            // It is very important that the ida:Audience and ida:ClientID match each other
            var credential = new ClientCredential(ClientId, ClientSecret);

            var bootstrapContext = new System.IdentityModel.Tokens.BootstrapContext(ClaimsPrincipal.Current.Identities.First().BootstrapContext.ToString());
            var userName         = ClaimsPrincipal.Current.FindFirst(ClaimTypes.Upn) != null?ClaimsPrincipal.Current.FindFirst(ClaimTypes.Upn).Value : ClaimsPrincipal.Current.FindFirst(ClaimTypes.Email).Value;

            var userAccessToken = bootstrapContext.Token;
            var userAssertion   = new UserAssertion(userAccessToken, "urn:ietf:params:oauth:grant-type:jwt-bearer", userName);

            var tokenResult = await authContext.AcquireTokenAsync(Resource, credential, userAssertion);

            var client = new HttpClient();

            var requestUri = $"{Resource}api/identity";
            var request    = new HttpRequestMessage(HttpMethod.Get, requestUri);

            request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", tokenResult.AccessToken);
            var response = await client.SendAsync(request);

            if (response.IsSuccessStatusCode)
            {
                var content = await response.Content.ReadAsStringAsync();

                var claimsIdentity = JsonConvert.DeserializeObject <object>(content);
                return(claimsIdentity);
            }

            return("Unsuccessful OBO operation : " + response.ReasonPhrase);
        }