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); }
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(); }
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 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 CanOSPerformDeviceAuth() { Assert.IsFalse(DeviceAuthHelper.CanOSPerformPKeyAuth()); }
public void CanOSPerformDeviceAuth() { Assert.IsFalse(DeviceAuthHelper.CanOSPerformPKeyAuth()); //Check one additinal time for cache Assert.IsFalse(DeviceAuthHelper.CanOSPerformPKeyAuth()); }