< Summary

Class:Azure.Identity.AuthorizationCodeCredential
Assembly:Azure.Identity
File(s):C:\Git\azure-sdk-for-net\sdk\identity\Azure.Identity\src\AuthorizationCodeCredential.cs
Covered lines:23
Uncovered lines:6
Coverable lines:29
Total lines:128
Line coverage:79.3% (23 of 29)
Covered branches:7
Total branches:12
Branch coverage:58.3% (7 of 12)

Metrics

MethodCyclomatic complexity Line coverage Branch coverage
.ctor()-100%100%
.ctor(...)-0%100%
.ctor(...)-80%50%
GetToken(...)-100%100%
GetTokenAsync()-100%100%
GetTokenImplAsync()-83.33%100%

File(s)

C:\Git\azure-sdk-for-net\sdk\identity\Azure.Identity\src\AuthorizationCodeCredential.cs

#LineLine coverage
 1// Copyright (c) Microsoft Corporation. All rights reserved.
 2// Licensed under the MIT License.
 3
 4using System;
 5using System.Threading;
 6using System.Threading.Tasks;
 7using Azure.Core;
 8using Azure.Core.Diagnostics;
 9using Azure.Core.Pipeline;
 10using Microsoft.Identity.Client;
 11
 12namespace Azure.Identity
 13{
 14    /// <summary>
 15    /// Authenticates by redeeming and authorization code previously obtained from Azure Active Directory.  See
 16    /// https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow for more information
 17    /// about the autorization code authentication flow.
 18    /// </summary>
 19    public class AuthorizationCodeCredential : TokenCredential
 20    {
 21        private readonly IConfidentialClientApplication _confidentialClient;
 22        private readonly ClientDiagnostics _clientDiagnostics;
 23        private readonly string _authCode;
 24        private readonly string _clientId;
 25        private readonly CredentialPipeline _pipeline;
 26        private AuthenticationRecord _record;
 27
 28        /// <summary>
 29        /// Protected constructor for mocking.
 30        /// </summary>
 431        protected AuthorizationCodeCredential()
 32        {
 433        }
 34
 35        /// <summary>
 36        /// Creates an instance of the ClientSecretCredential with the details needed to authenticate against Azure Acti
 37        /// </summary>
 38        /// <param name="tenantId">The Azure Active Directory tenant (directory) Id of the service principal.</param>
 39        /// <param name="clientId">The client (application) ID of the service principal</param>
 40        /// <param name="clientSecret">A client secret that was generated for the App Registration used to authenticate 
 41        /// <param name="authorizationCode">The authorization code obtained from a call to authorize. The code should be
 42        /// See https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow for more inform
 43        public AuthorizationCodeCredential(string tenantId, string clientId, string clientSecret, string authorizationCo
 044            : this(tenantId, clientId, clientSecret, authorizationCode, null)
 45        {
 046        }
 47
 48        /// <summary>
 49        /// Creates an instance of the ClientSecretCredential with the details needed to authenticate against Azure Acti
 50        /// </summary>
 51        /// <param name="tenantId">The Azure Active Directory tenant (directory) Id of the service principal.</param>
 52        /// <param name="clientId">The client (application) ID of the service principal</param>
 53        /// <param name="clientSecret">A client secret that was generated for the App Registration used to authenticate 
 54        /// <param name="authorizationCode">The authorization code obtained from a call to authorize. The code should be
 55        /// See https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow for more inform
 56        /// <param name="options">Options that allow to configure the management of the requests sent to the Azure Activ
 457        public AuthorizationCodeCredential(string tenantId, string clientId, string clientSecret, string authorizationCo
 58        {
 059            if (tenantId is null) throw new ArgumentNullException(nameof(tenantId));
 060            if (clientSecret is null) throw new ArgumentNullException(nameof(clientSecret));
 61
 462            _clientId = clientId ?? throw new ArgumentNullException(nameof(clientId));
 63
 464            _authCode = authorizationCode ?? throw new ArgumentNullException(nameof(authorizationCode));
 65
 466            options ??= new TokenCredentialOptions();
 67
 468            _pipeline = CredentialPipeline.GetInstance(options);
 69
 470            _confidentialClient = ConfidentialClientApplicationBuilder.Create(clientId).WithHttpClientFactory(new HttpPi
 71
 472            _clientDiagnostics = new ClientDiagnostics(options);
 473        }
 74
 75        /// <summary>
 76        /// Obtains a token from the Azure Active Directory service, using the specified authorization code authenticate
 77        /// </summary>
 78        /// <param name="requestContext">The details of the authentication request.</param>
 79        /// <param name="cancellationToken">A <see cref="CancellationToken"/> controlling the request lifetime.</param>
 80        /// <returns>An <see cref="AccessToken"/> which can be used to authenticate service client calls.</returns>
 81        public override AccessToken GetToken(TokenRequestContext requestContext, CancellationToken cancellationToken = d
 82        {
 483            return GetTokenImplAsync(false, requestContext, cancellationToken).EnsureCompleted();
 84        }
 85
 86        /// <summary>
 87        /// Obtains a token from the Azure Active Directory service, using the specified authorization code authenticate
 88        /// </summary>
 89        /// <param name="requestContext">The details of the authentication request.</param>
 90        /// <param name="cancellationToken">A <see cref="CancellationToken"/> controlling the request lifetime.</param>
 91        /// <returns>An <see cref="AccessToken"/> which can be used to authenticate service client calls.</returns>
 92        public override async ValueTask<AccessToken> GetTokenAsync(TokenRequestContext requestContext, CancellationToken
 93        {
 494            return await GetTokenImplAsync(true, requestContext, cancellationToken).ConfigureAwait(false);
 495        }
 96
 97        private async ValueTask<AccessToken> GetTokenImplAsync(bool async, TokenRequestContext requestContext, Cancellat
 98        {
 899            using CredentialDiagnosticScope scope = _pipeline.StartGetTokenScope($"{nameof(AuthorizationCodeCredential)}
 100
 101            try
 102            {
 8103                AccessToken token = default;
 104
 8105                if (_record is null)
 106                {
 4107                    AuthenticationResult result = await _confidentialClient.AcquireTokenByAuthorizationCode(requestConte
 108
 4109                    _record = new AuthenticationRecord(result, _clientId);
 110
 4111                    token = new AccessToken(result.AccessToken, result.ExpiresOn);
 112                }
 113                else
 114                {
 4115                    AuthenticationResult result = await _confidentialClient.AcquireTokenSilent(requestContext.Scopes, (A
 116
 4117                    token = new AccessToken(result.AccessToken, result.ExpiresOn);
 118                }
 119
 8120                return scope.Succeeded(token);
 121            }
 0122            catch (Exception e)
 123            {
 0124                throw scope.FailWrapAndThrow(e);
 125            }
 8126        }
 127    }
 128}