public static async Task <WsTrustResponse> SendRequestAsync(WsTrustAddress wsTrustAddress, UserCredential credential, CallState callState, string cloudAudience) { IHttpClient request = PlatformPlugin.HttpClientFactory.Create(wsTrustAddress.Uri.AbsoluteUri, callState); request.ContentType = "application/soap+xml"; if (credential.UserAuthType == UserAuthType.IntegratedAuth) { SetKerberosOption(request); } if (string.IsNullOrEmpty(cloudAudience)) { cloudAudience = defaultAppliesTo; } StringBuilder messageBuilder = BuildMessage(cloudAudience, wsTrustAddress, credential); string soapAction = XmlNamespace.Issue.ToString(); if (wsTrustAddress.Version == WsTrustVersion.WsTrust2005) { soapAction = XmlNamespace.Issue2005.ToString(); } WsTrustResponse wstResponse; try { request.BodyParameters = new StringRequestParameters(messageBuilder); request.Headers["SOAPAction"] = soapAction; IHttpWebResponse response = await request.GetResponseAsync().ConfigureAwait(false); wstResponse = WsTrustResponse.CreateFromResponse(EncodingHelper.GenerateStreamFromString(response.ResponseString), wsTrustAddress.Version); } catch (HttpRequestWrapperException ex) { string errorMessage; try { using (Stream stream = EncodingHelper.GenerateStreamFromString(ex.WebResponse.ResponseString)) { XDocument responseDocument = WsTrustResponse.ReadDocumentFromResponse(stream); errorMessage = WsTrustResponse.ReadErrorResponse(responseDocument, callState); } } catch (AdalException) { errorMessage = "See inner exception for detail."; } throw new AdalServiceException( AdalError.FederatedServiceReturnedError, string.Format(AdalErrorMessage.FederatedServiceReturnedErrorTemplate, wsTrustAddress.Uri, errorMessage), null, ex); } return(wstResponse); }
internal static WsTrustResponse CreateFromResponseDocument(XDocument responseDocument) { Dictionary <string, string> tokenResponseDictionary = new Dictionary <string, string>(); try { XElement requestSecurityTokenResponseCollection = responseDocument.Descendants(XmlNamespace.Trust + "RequestSecurityTokenResponseCollection").FirstOrDefault(); if (requestSecurityTokenResponseCollection != null) { IEnumerable <XElement> tokenResponses = responseDocument.Descendants(XmlNamespace.Trust + "RequestSecurityTokenResponse"); foreach (var tokenResponse in tokenResponses) { XElement tokenTypeElement = tokenResponse.Elements(XmlNamespace.Trust + "TokenType").FirstOrDefault(); if (tokenTypeElement == null) { continue; } XElement requestedSecurityToken = tokenResponse.Elements(XmlNamespace.Trust + "RequestedSecurityToken").FirstOrDefault(); if (requestedSecurityToken == null) { continue; } // TODO #123622: We need to disable formatting due to a potential service bug. Remove the ToString argument when problem is fixed. tokenResponseDictionary.Add(tokenTypeElement.Value, requestedSecurityToken.FirstNode.ToString(SaveOptions.DisableFormatting)); } } } catch (XmlException ex) { var adalEx = new AdalException(AdalError.ParsingWsTrustResponseFailed, ex); PlatformPlugin.Logger.LogException(null, adalEx); throw adalEx; } if (tokenResponseDictionary.Count == 0) { var ex = new AdalException(AdalError.ParsingWsTrustResponseFailed); PlatformPlugin.Logger.LogException(null, ex); throw ex; } string tokenType = tokenResponseDictionary.ContainsKey(Saml1Assertion) ? Saml1Assertion : tokenResponseDictionary.Keys.First(); WsTrustResponse wsTrustResponse = new WsTrustResponse { TokenType = tokenType, Token = tokenResponseDictionary[tokenType] }; return(wsTrustResponse); }
public static async Task <WsTrustResponse> SendRequestAsync(WsTrustAddress wsTrustAddress, UserCredential credential, CallState callState) { IHttpWebRequest request = NetworkPlugin.HttpWebRequestFactory.Create(wsTrustAddress.Uri.AbsoluteUri); request.ContentType = "application/soap+xml;"; if (credential.UserAuthType == UserAuthType.IntegratedAuth) { SetKerberosOption(request); } StringBuilder messageBuilder = BuildMessage(DefaultAppliesTo, wsTrustAddress, credential); string soapAction = XmlNamespace.Issue.ToString(); if (wsTrustAddress.Version == WsTrustVersion.WsTrust2005) { soapAction = XmlNamespace.Issue2005.ToString(); } Dictionary <string, string> headers = new Dictionary <string, string> { { "SOAPAction", soapAction } }; WsTrustResponse wstResponse; try { HttpHelper.SetPostRequest(request, new RequestParameters(messageBuilder), callState, headers); IHttpWebResponse response = await request.GetResponseSyncOrAsync(callState); wstResponse = WsTrustResponse.CreateFromResponse(response.GetResponseStream(), wsTrustAddress.Version); } catch (WebException ex) { string errorMessage; try { XDocument responseDocument = WsTrustResponse.ReadDocumentFromResponse(ex.Response.GetResponseStream()); errorMessage = WsTrustResponse.ReadErrorResponse(responseDocument, callState); } catch (AdalException) { errorMessage = "See inner exception for detail."; } throw new AdalServiceException( AdalError.FederatedServiceReturnedError, string.Format(AdalErrorMessage.FederatedServiceReturnedErrorTemplate, wsTrustAddress.Uri, errorMessage), null, ex); } return(wstResponse); }
protected override async Task PreTokenRequest() { await base.PreTokenRequest(); UserRealmDiscoveryResponse userRealmResponse = await UserRealmDiscoveryResponse.CreateByDiscoveryAsync(this.Authenticator.UserRealmUri, this.userCredential.UserName, this.CallState); Logger.Information(this.CallState, "User '{0}' detected as '{1}'", this.userCredential.UserName, userRealmResponse.AccountType); if (string.Compare(userRealmResponse.AccountType, "federated", StringComparison.OrdinalIgnoreCase) == 0) { if (string.IsNullOrWhiteSpace(userRealmResponse.FederationMetadataUrl)) { var ex = new AdalException(AdalError.MissingFederationMetadataUrl); Logger.LogException(this.CallState, ex); throw ex; } Uri wsTrustUrl = await MexParser.FetchWsTrustAddressFromMexAsync(userRealmResponse.FederationMetadataUrl, this.userCredential.UserAuthType, this.CallState); Logger.Information(this.CallState, "WS-Trust endpoint '{0}' fetched from MEX at '{1}'", wsTrustUrl, userRealmResponse.FederationMetadataUrl); WsTrustResponse wsTrustResponse = await WsTrustRequest.SendRequestAsync(wsTrustUrl, this.userCredential, this.CallState); Logger.Information(this.CallState, "Token of type '{0}' acquired from WS-Trust endpoint", wsTrustResponse.TokenType); // We assume that if the response token type is not SAML 1.1, it is SAML 2 this.samlAssertion = new UserAssertion(wsTrustResponse.Token, (wsTrustResponse.TokenType == WsTrustResponse.Saml1Assertion) ? OAuthGrantType.Saml11Bearer : OAuthGrantType.Saml20Bearer); } else if (string.Compare(userRealmResponse.AccountType, "managed", StringComparison.OrdinalIgnoreCase) == 0) { // handle password grant flow for the managed user if (this.userCredential.PasswordToCharArray() == null) { var ex = new AdalException(AdalError.PasswordRequiredForManagedUserError); Logger.LogException(this.CallState, ex); throw ex; } } else { var ex = new AdalException(AdalError.UnknownUserType); Logger.LogException(this.CallState, ex); throw ex; } }
protected override async Task PreTokenRequest() { await base.PreTokenRequest().ConfigureAwait(false); if (this.PerformUserRealmDiscovery()) { UserRealmDiscoveryResponse userRealmResponse = await UserRealmDiscoveryResponse.CreateByDiscoveryAsync(this.Authenticator.UserRealmUri, this.userCredential.UserName, this.CallState).ConfigureAwait(false); PlatformPlugin.Logger.Information(this.CallState, string.Format(CultureInfo.CurrentCulture, " User with hash '{0}' detected as '{1}'", PlatformPlugin.CryptographyHelper.CreateSha256Hash(this.userCredential.UserName), userRealmResponse.AccountType)); if (string.Compare(userRealmResponse.AccountType, "federated", StringComparison.OrdinalIgnoreCase) == 0) { if (string.IsNullOrWhiteSpace(userRealmResponse.FederationMetadataUrl)) { throw new AdalException(AdalError.MissingFederationMetadataUrl); } WsTrustAddress wsTrustAddress = await MexParser.FetchWsTrustAddressFromMexAsync(userRealmResponse.FederationMetadataUrl, this.userCredential.UserAuthType, this.CallState).ConfigureAwait(false); PlatformPlugin.Logger.Information(this.CallState, string.Format(CultureInfo.CurrentCulture, " WS-Trust endpoint '{0}' fetched from MEX at '{1}'", wsTrustAddress.Uri, userRealmResponse.FederationMetadataUrl)); WsTrustResponse wsTrustResponse = await WsTrustRequest.SendRequestAsync(wsTrustAddress, this.userCredential, this.CallState, userRealmResponse.CloudAudienceUrn).ConfigureAwait(false); PlatformPlugin.Logger.Information(this.CallState, string.Format(CultureInfo.CurrentCulture, " Token of type '{0}' acquired from WS-Trust endpoint", wsTrustResponse.TokenType)); // We assume that if the response token type is not SAML 1.1, it is SAML 2 this.userAssertion = new UserAssertion(wsTrustResponse.Token, (wsTrustResponse.TokenType == WsTrustResponse.Saml1Assertion) ? OAuthGrantType.Saml11Bearer : OAuthGrantType.Saml20Bearer); } else if (string.Compare(userRealmResponse.AccountType, "managed", StringComparison.OrdinalIgnoreCase) == 0) { // handle password grant flow for the managed user if (this.userCredential.PasswordToCharArray() == null) { throw new AdalException(AdalError.PasswordRequiredForManagedUserError); } } else { throw new AdalException(AdalError.UnknownUserType); } } }
internal static WsTrustResponse CreateFromResponseDocument(XDocument responseDocument) { Dictionary<string, string> tokenResponseDictionary = new Dictionary<string, string>(); try { XElement requestSecurityTokenResponseCollection = responseDocument.Descendants(XmlNamespace.Trust + "RequestSecurityTokenResponseCollection").FirstOrDefault(); if (requestSecurityTokenResponseCollection != null) { IEnumerable<XElement> tokenResponses = responseDocument.Descendants(XmlNamespace.Trust + "RequestSecurityTokenResponse"); foreach (var tokenResponse in tokenResponses) { XElement tokenTypeElement = tokenResponse.Elements(XmlNamespace.Trust + "TokenType").FirstOrDefault(); if (tokenTypeElement == null) { continue; } XElement requestedSecurityToken = tokenResponse.Elements(XmlNamespace.Trust + "RequestedSecurityToken").FirstOrDefault(); if (requestedSecurityToken == null) { continue; } // TODO #123622: We need to disable formatting due to a potential service bug. Remove the ToString argument when problem is fixed. tokenResponseDictionary.Add(tokenTypeElement.Value, requestedSecurityToken.FirstNode.ToString(SaveOptions.DisableFormatting)); } } } catch (XmlException ex) { throw new AdalException(AdalError.ParsingWsTrustResponseFailed, ex); } if (tokenResponseDictionary.Count == 0) { throw new AdalException(AdalError.ParsingWsTrustResponseFailed); } string tokenType = tokenResponseDictionary.ContainsKey(Saml1Assertion) ? Saml1Assertion : tokenResponseDictionary.Keys.First(); WsTrustResponse wsTrustResponse = new WsTrustResponse { TokenType = tokenType, Token = tokenResponseDictionary[tokenType] }; return wsTrustResponse; }