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 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); }
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); }