< Summary

Class:Microsoft.Azure.KeyVault.HttpBearerChallenge
Assembly:Microsoft.Azure.KeyVault
File(s):C:\Git\azure-sdk-for-net\sdk\keyvault\Microsoft.Azure.KeyVault\src\Customized\Authentication\HttpBearerChallenge.cs
Covered lines:45
Uncovered lines:15
Coverable lines:60
Total lines:225
Line coverage:75% (45 of 60)
Covered branches:35
Total branches:50
Branch coverage:70% (35 of 50)

Metrics

MethodCyclomatic complexity Line coverage Branch coverage
IsBearerChallenge(...)-80%75%
GetBearerChallengeFromResponse(...)-80%80%
.ctor(...)-90%81.25%
TryGetValue(...)-0%100%
get_AuthorizationServer()-66.67%50%
get_Resource()-75%50%
get_Scope()-75%50%
get_SourceAuthority()-100%100%
get_SourceUri()-0%100%
ValidateChallenge(...)-66.67%50%
ValidateRequestURI(...)-57.14%62.5%

File(s)

C:\Git\azure-sdk-for-net\sdk\keyvault\Microsoft.Azure.KeyVault\src\Customized\Authentication\HttpBearerChallenge.cs

#LineLine coverage
 1// Copyright (c) Microsoft Corporation. All rights reserved.
 2// Licensed under the MIT License. See License.txt in the project root for
 3// license information.
 4
 5using System;
 6using System.Collections.Generic;
 7using System.Net.Http;
 8using System.Linq;
 9
 10namespace Microsoft.Azure.KeyVault
 11{
 12    /// <summary>
 13    /// Handles http bearer challenge operations
 14    /// </summary>
 15    public sealed class HttpBearerChallenge
 16    {
 17        private const string Authorization = "authorization";
 18        private const string AuthorizationUri = "authorization_uri";
 19        private const string Bearer = "Bearer";
 20
 21        /// <summary>
 22        /// Tests whether an authentication header is a Bearer challenge
 23        /// </summary>
 24        /// <remarks>
 25        /// This method is forgiving: if the parameter is null, or the scheme
 26        /// in the header is missing, then it will simply return false.
 27        /// </remarks>
 28        /// <param name="challenge">The AuthenticationHeaderValue to test</param>
 29        /// <returns>True if the header is a Bearer challenge</returns>
 30        public static bool IsBearerChallenge(string challenge)
 31        {
 632            if (string.IsNullOrEmpty(challenge))
 033                return false;
 34
 635            if (!challenge.Trim().StartsWith(Bearer + " "))
 236                return false;
 37
 438            return true;
 39        }
 40
 41        internal static HttpBearerChallenge GetBearerChallengeFromResponse(HttpResponseMessage response)
 42        {
 043            if (response == null) return null;
 44
 845            string challenge = response?.Headers.WwwAuthenticate.FirstOrDefault()?.ToString();
 46
 847            if (!string.IsNullOrEmpty(challenge) && IsBearerChallenge(challenge))
 48            {
 449                return new HttpBearerChallenge(response.RequestMessage.RequestUri, challenge);
 50            }
 51
 452            return null;
 53        }
 54
 55        private Dictionary<string, string> _parameters = null;
 56        private string _sourceAuthority = null;
 57        private Uri _sourceUri = null;
 58
 59        /// <summary>
 60        /// Parses an HTTP WWW-Authentication Bearer challenge from a server.
 61        /// </summary>
 62        /// <param name="challenge">The AuthenticationHeaderValue to parse</param>
 663        public HttpBearerChallenge(Uri requestUri, string challenge)
 64        {
 665            string authority = ValidateRequestURI(requestUri);
 666            string trimmedChallenge = ValidateChallenge(challenge);
 67
 668            _sourceAuthority = authority;
 669            _sourceUri = requestUri;
 70
 671            _parameters = new Dictionary<string, string>();
 72
 73            // Split the trimmed challenge into a set of name=value strings that
 74            // are comma separated. The value fields are expected to be within
 75            // quotation characters that are stripped here.
 676            String[] pairs = trimmedChallenge.Split(new String[] { "," }, StringSplitOptions.RemoveEmptyEntries);
 77
 678            if (pairs != null && pairs.Length > 0)
 79            {
 80                // Process the name=value strings
 4881                for (int i = 0; i < pairs.Length; i++)
 82                {
 1883                    String[] pair = pairs[i].Split('=');
 84
 1885                    if (pair.Length == 2)
 86                    {
 87                        // We have a key and a value, now need to trim and decode
 1888                        String key = pair[0].Trim().Trim(new char[] { '\"' });
 1889                        String value = pair[1].Trim().Trim(new char[] { '\"' });
 90
 1891                        if (!string.IsNullOrEmpty(key))
 92                        {
 1893                            _parameters[key] = value;
 94                        }
 95                    }
 96                }
 97            }
 98
 99            // Minimum set of parameters
 6100            if (_parameters.Count < 1)
 0101                throw new ArgumentException("Invalid challenge parameters", "challenge");
 102
 103            // Must specify authorization or authorization_uri
 6104            if (!_parameters.ContainsKey(Authorization) && !_parameters.ContainsKey(AuthorizationUri))
 0105                throw new ArgumentException("Invalid challenge parameters", "challenge");
 6106        }
 107
 108        /// <summary>
 109        /// Returns the value stored at the specified key.
 110        /// </summary>
 111        /// <remarks>
 112        /// If the key does not exist, will return false and the
 113        /// content of value will not be changed
 114        /// </remarks>
 115        /// <param name="key">The key to be retrieved</param>
 116        /// <param name="value">The value for the specified key</param>
 117        /// <returns>True when the key is found, false when it is not</returns>
 118        public bool TryGetValue(string key, out string value)
 119        {
 0120            return _parameters.TryGetValue(key, out value);
 121        }
 122
 123        /// <summary>
 124        /// Returns the URI for the Authorization server if present,
 125        /// otherwise string.Empty
 126        /// </summary>
 127        public string AuthorizationServer
 128        {
 129            get
 130            {
 6131                string value = string.Empty;
 132
 6133                if (_parameters.TryGetValue("authorization_uri", out value))
 0134                    return value;
 135
 6136                if (_parameters.TryGetValue("authorization", out value))
 6137                    return value;
 138
 0139                return string.Empty;
 140            }
 141        }
 142
 143        /// <summary>
 144        /// Returns the Realm value if present, otherwise the Authority
 145        /// of the request URI given in the ctor
 146        /// </summary>
 147        public string Resource
 148        {
 149            get
 150            {
 6151                string value = string.Empty;
 152
 6153                if (_parameters.TryGetValue("resource", out value))
 6154                    return value;
 155
 0156                return _sourceAuthority;
 157            }
 158        }
 159
 160        /// <summary>
 161        /// Returns the Scope value if present, otherwise string.Empty
 162        /// </summary>
 163        public string Scope
 164        {
 165            get
 166            {
 6167                string value = string.Empty;
 168
 6169                if (_parameters.TryGetValue("scope", out value))
 6170                    return value;
 171
 0172                return string.Empty;
 173            }
 174        }
 175
 176        /// <summary>
 177        /// The Authority of the request URI
 178        /// </summary>
 179        public string SourceAuthority
 180        {
 181            get
 182            {
 6183                return _sourceAuthority;
 184            }
 185        }
 186
 187        /// <summary>
 188        /// The source URI
 189        /// </summary>
 190        public Uri SourceUri
 191        {
 192            get
 193            {
 0194                return _sourceUri;
 195            }
 196        }
 197
 198        private static string ValidateChallenge(string challenge)
 199        {
 6200            if (string.IsNullOrEmpty(challenge))
 0201                throw new ArgumentNullException("challenge");
 202
 6203            string trimmedChallenge = challenge.Trim();
 204
 6205            if (!trimmedChallenge.StartsWith(Bearer + " "))
 0206                throw new ArgumentException("Challenge is not Bearer", "challenge");
 207
 6208            return trimmedChallenge.Substring(Bearer.Length + 1);
 209        }
 210
 211        private static string ValidateRequestURI(Uri requestUri)
 212        {
 6213            if (null == requestUri)
 0214                throw new ArgumentNullException("requestUri");
 215
 6216            if (!requestUri.IsAbsoluteUri)
 0217                throw new ArgumentException("The requestUri must be an absolute URI", "requestUri");
 218
 6219            if (!requestUri.Scheme.Equals("http", StringComparison.CurrentCultureIgnoreCase) && !requestUri.Scheme.Equal
 0220                throw new ArgumentException("The requestUri must be HTTP or HTTPS", "requestUri");
 221
 6222            return requestUri.FullAuthority();
 223        }
 224    }
 225}