private async Task AddBodyParamsAndHeadersAsync( IDictionary <string, string> additionalBodyParameters, string scopes, CancellationToken cancellationToken) { _oAuth2Client.AddBodyParameter(OAuth2Parameter.ClientId, _requestParams.AppConfig.ClientId); if (_serviceBundle.Config.ClientCredential != null) { await _serviceBundle.Config.ClientCredential.AddConfidentialClientParametersAsync( _oAuth2Client, _requestParams.RequestContext.Logger, _serviceBundle.PlatformProxy.CryptographyManager, _requestParams.AppConfig.ClientId, _requestParams.Authority.GetTokenEndpoint(), _requestParams.SendX5C, cancellationToken).ConfigureAwait(false); } _oAuth2Client.AddBodyParameter(OAuth2Parameter.Scope, scopes); // Add Kerberos Ticket claims if there's valid service principal name in Configuration. // Kerberos Ticket claim is only allowed at token request due to security issue. // It should not be included for authorize request. KerberosSupplementalTicketManager.AddKerberosTicketClaim(_oAuth2Client, _requestParams); foreach (var kvp in additionalBodyParameters) { _oAuth2Client.AddBodyParameter(kvp.Key, kvp.Value); } foreach (var kvp in _requestParams.AuthenticationScheme.GetTokenRequestParams()) { _oAuth2Client.AddBodyParameter(kvp.Key, kvp.Value); } _oAuth2Client.AddHeader( TelemetryConstants.XClientCurrentTelemetry, _serviceBundle.HttpTelemetryManager.GetCurrentRequestHeader( _requestParams.RequestContext.ApiEvent)); if (!_requestInProgress) { _requestInProgress = true; _oAuth2Client.AddHeader( TelemetryConstants.XClientLastTelemetry, _serviceBundle.HttpTelemetryManager.GetLastRequestHeader()); } //Signaling that the client can perform PKey Auth on supported platforms if (DeviceAuthHelper.CanOSPerformPKeyAuth()) { _oAuth2Client.AddHeader(PKeyAuthConstants.DeviceAuthHeaderName, PKeyAuthConstants.DeviceAuthHeaderValue); } AddExtraHttpHeaders(); }
public bool TryCreateDeviceAuthChallengeResponseAsync(HttpResponseHeaders responseHeaders, Uri endpointUri, out string responseHeader) { responseHeader = string.Empty; string authHeaderTemplate = "PKeyAuth {0}, Context=\"{1}\", Version=\"{2}\""; X509Certificate2 certificate = null; if (!DeviceAuthHelper.IsDeviceAuthChallenge(responseHeaders)) { return(false); } if (!DeviceAuthHelper.CanOSPerformPKeyAuth()) { responseHeader = DeviceAuthHelper.GetBypassChallengeResponse(responseHeaders); return(true); } IDictionary <string, string> challengeData = DeviceAuthHelper.ParseChallengeData(responseHeaders); if (!challengeData.ContainsKey("SubmitUrl")) { challengeData["SubmitUrl"] = endpointUri.AbsoluteUri; } try { certificate = FindCertificate(challengeData); } catch (MsalException ex) { if (ex.ErrorCode == MsalError.DeviceCertificateNotFound) { responseHeader = DeviceAuthHelper.GetBypassChallengeResponse(responseHeaders); return(true); } } DeviceAuthJWTResponse responseJWT = new DeviceAuthJWTResponse(challengeData["SubmitUrl"], challengeData["nonce"], Convert.ToBase64String(certificate.GetRawCertData())); CngKey key = NetDesktopCryptographyManager.GetCngPrivateKey(certificate); byte[] sig = null; using (Native.RSACng rsa = new Native.RSACng(key)) { rsa.SignatureHashAlgorithm = CngAlgorithm.Sha256; sig = rsa.SignData(responseJWT.GetResponseToSign().ToByteArray()); } string signedJwt = string.Format(CultureInfo.InvariantCulture, "{0}.{1}", responseJWT.GetResponseToSign(), Base64UrlHelpers.Encode(sig)); string authToken = string.Format(CultureInfo.InvariantCulture, " AuthToken=\"{0}\"", signedJwt); responseHeader = string.Format(CultureInfo.InvariantCulture, authHeaderTemplate, authToken, challengeData["Context"], challengeData["Version"]); return(true); }
public void CheckIfResponseIsDeviceAuthChallenge() { //Act bool successResponse = DeviceAuthHelper.IsDeviceAuthChallenge(s_httpResponse.Headers); bool failedResponse = DeviceAuthHelper.IsDeviceAuthChallenge((new HttpResponse()).Headers); //Assert Assert.IsTrue(successResponse); Assert.IsFalse(failedResponse); }
private void AddBodyParamsAndHeaders(IDictionary <string, string> additionalBodyParameters, string scopes) { _oAuth2Client.AddBodyParameter(OAuth2Parameter.ClientId, _requestParams.AppConfig.ClientId); _oAuth2Client.AddBodyParameter(OAuth2Parameter.ClientInfo, "1"); if (_requestParams.ClientCredential != null) { Dictionary <string, string> ccBodyParameters = ClientCredentialHelper.CreateClientCredentialBodyParameters( _requestParams.RequestContext.Logger, _serviceBundle.PlatformProxy.CryptographyManager, _requestParams.ClientCredential, _requestParams.AppConfig.ClientId, _requestParams.Endpoints, _requestParams.SendX5C); foreach (var entry in ccBodyParameters) { _oAuth2Client.AddBodyParameter(entry.Key, entry.Value); } } _oAuth2Client.AddBodyParameter(OAuth2Parameter.Scope, scopes); _oAuth2Client.AddBodyParameter(OAuth2Parameter.Claims, _requestParams.ClaimsAndClientCapabilities); foreach (var kvp in additionalBodyParameters) { _oAuth2Client.AddBodyParameter(kvp.Key, kvp.Value); } foreach (var kvp in _requestParams.AuthenticationScheme.GetTokenRequestParams()) { _oAuth2Client.AddBodyParameter(kvp.Key, kvp.Value); } _oAuth2Client.AddHeader( TelemetryConstants.XClientCurrentTelemetry, _serviceBundle.HttpTelemetryManager.GetCurrentRequestHeader( _requestParams.RequestContext.ApiEvent)); if (!_requestInProgress) { _requestInProgress = true; _oAuth2Client.AddHeader( TelemetryConstants.XClientLastTelemetry, _serviceBundle.HttpTelemetryManager.GetLastRequestHeader()); } //Signaling that the client can perform PKey Auth on supported platforms if (DeviceAuthHelper.CanOSPerformPKeyAuth()) { _oAuth2Client.AddHeader(PKeyAuthConstants.DeviceAuthHeaderName, PKeyAuthConstants.DeviceAuthHeaderValue); } }
public void ParsePKeyAuthChallengeData() { //Act var result = DeviceAuthHelper.ParseChallengeData(s_httpResponse.Headers); //Assert Assert.AreEqual(result["Version"], "1.0"); Assert.AreEqual(result["CertThumbprint"], "thumbprint"); Assert.AreEqual(result["Context"], "context"); Assert.AreEqual(result["Nonce"], "nonce"); }
public bool TryCreateDeviceAuthChallengeResponseAsync(HttpResponseHeaders headers, Uri endpointUri, out string responseHeader) { responseHeader = string.Empty; Certificate certificate = null; string authHeaderTemplate = "PKeyAuth {0}, Context=\"{1}\", Version=\"{2}\""; if (!DeviceAuthHelper.IsDeviceAuthChallenge(headers)) { return(false); } if (!DeviceAuthHelper.CanOSPerformPKeyAuth()) { responseHeader = DeviceAuthHelper.GetBypassChallengeResponse(headers); return(false); } IDictionary <string, string> challengeData = DeviceAuthHelper.ParseChallengeData(headers); if (!challengeData.ContainsKey("SubmitUrl")) { challengeData["SubmitUrl"] = endpointUri.AbsoluteUri; } try { certificate = Task.FromResult(FindCertificateAsync(challengeData)).Result.Result; } catch (MsalException ex) { if (ex.ErrorCode == MsalError.DeviceCertificateNotFound) { responseHeader = DeviceAuthHelper.GetBypassChallengeResponse(headers); return(true); } } DeviceAuthJWTResponse responseJWT = new DeviceAuthJWTResponse(challengeData["SubmitUrl"], challengeData["nonce"], Convert.ToBase64String(certificate.GetCertificateBlob().ToArray())); IBuffer input = CryptographicBuffer.ConvertStringToBinary(responseJWT.GetResponseToSign(), BinaryStringEncoding.Utf8); CryptographicKey keyPair = Task.FromResult(PersistedKeyProvider.OpenKeyPairFromCertificateAsync(certificate, HashAlgorithmNames.Sha256, CryptographicPadding.RsaPkcs1V15)).Result.GetResults(); IBuffer signed = Task.FromResult(CryptographicEngine.SignAsync(keyPair, input)).Result.GetResults(); string signedJwt = string.Format(CultureInfo.InvariantCulture, "{0}.{1}", responseJWT.GetResponseToSign(), Base64UrlHelpers.Encode(signed.ToArray())); string authToken = string.Format(CultureInfo.InvariantCulture, " AuthToken=\"{0}\"", signedJwt); responseHeader = string.Format(CultureInfo.InvariantCulture, authHeaderTemplate, authToken, challengeData["Context"], challengeData["Version"]); return(true); }
public void GetDeviceAuthBypassChallengeResponse() { //Arrange Dictionary <string, string> pKeyAuthHeaders = new Dictionary <string, string>(); pKeyAuthHeaders.Add("Context", "context"); pKeyAuthHeaders.Add("Version", "1.0"); //Act var result1 = DeviceAuthHelper.GetBypassChallengeResponse(s_httpResponse.Headers); var result2 = DeviceAuthHelper.GetBypassChallengeResponse(pKeyAuthHeaders); //Assert Assert.AreEqual(result1, TestConstants.PKeyAuthResponse); Assert.AreEqual(result2, TestConstants.PKeyAuthResponse); }
private async Task <T> HandleDeviceAuthChallenge <T>(IHttpWebResponse response) { IDictionary <string, string> responseDictionary = this.ParseChallengeData(response); if (!responseDictionary.ContainsKey("SubmitUrl")) { responseDictionary["SubmitUrl"] = RequestUri; } string responseHeader = await DeviceAuthHelper.CreateDeviceAuthChallengeResponse(responseDictionary) .ConfigureAwait(false); IRequestParameters rp = this.Client.BodyParameters; this.Client = new HttpClientWrapper(CheckForExtraQueryParameter(responseDictionary["SubmitUrl"]), this.CallState); this.Client.BodyParameters = rp; this.Client.Headers["Authorization"] = responseHeader; return(await this.GetResponseAsync <T>(false).ConfigureAwait(false)); }
void DecidePolicyForNavigation(WebView webView, NSDictionary actionInformation, NSUrlRequest request, WebFrame frame, NSObject decisionToken) { if (request == null) { WebView.DecideUse(decisionToken); return; } string requestUrlString = request.Url.ToString(); if (requestUrlString.StartsWith(BrokerConstants.BrowserExtPrefix, StringComparison.OrdinalIgnoreCase)) { var result = AuthorizationResult.FromStatus( AuthorizationStatus.ProtocolError, "Unsupported request", "Server is redirecting client to browser. This behavior is not yet defined on Mac OS X."); _callbackMethod(result); WebView.DecideIgnore(decisionToken); Close(); return; } if (requestUrlString.ToLower(CultureInfo.InvariantCulture).StartsWith(_callback.ToLower(CultureInfo.InvariantCulture), StringComparison.OrdinalIgnoreCase) || requestUrlString.StartsWith(BrokerConstants.BrowserExtInstallPrefix, StringComparison.OrdinalIgnoreCase)) { _callbackMethod(AuthorizationResult.FromUri(request.Url.ToString())); WebView.DecideIgnore(decisionToken); Close(); return; } if (requestUrlString.StartsWith(BrokerConstants.DeviceAuthChallengeRedirect, StringComparison.CurrentCultureIgnoreCase)) { var uri = new Uri(requestUrlString); string query = uri.Query; if (query.StartsWith("?", StringComparison.OrdinalIgnoreCase)) { query = query.Substring(1); } Dictionary <string, string> keyPair = CoreHelpers.ParseKeyValueList(query, '&', true, false, null); string responseHeader = DeviceAuthHelper.GetBypassChallengeResponse(keyPair); var newRequest = (NSMutableUrlRequest)request.MutableCopy(); newRequest.Url = new NSUrl(keyPair["SubmitUrl"]); newRequest[BrokerConstants.ChallengeResponseHeader] = responseHeader; webView.MainFrame.LoadRequest(newRequest); WebView.DecideIgnore(decisionToken); return; } if (!request.Url.AbsoluteString.Equals("about:blank", StringComparison.CurrentCultureIgnoreCase) && !request.Url.Scheme.Equals("https", StringComparison.CurrentCultureIgnoreCase)) { var result = AuthorizationResult.FromStatus( AuthorizationStatus.ErrorHttp, MsalError.NonHttpsRedirectNotSupported, MsalErrorMessage.NonHttpsRedirectNotSupported); _callbackMethod(result); WebView.DecideIgnore(decisionToken); Close(); } WebView.DecideUse(decisionToken); }
public void CanOSPerformDeviceAuth() { Assert.IsFalse(DeviceAuthHelper.CanOSPerformPKeyAuth()); }
public void CanOSPerformDeviceAuth() { Assert.IsFalse(DeviceAuthHelper.CanOSPerformPKeyAuth()); //Check one additinal time for cache Assert.IsFalse(DeviceAuthHelper.CanOSPerformPKeyAuth()); }