My code (C#):
HttpClientHandler httpClientHandler = new HttpClientHandler();
httpClientHandler.PreAuthenticate = true;
//httpClientHandler.UseDefaultCredentials = true;
httpClientHandler.Credentials = CredentialCache.DefaultNetworkCredentials;
//httpClientHandler.Credentials = new NetworkCredential("usr", "pw", "domain");
httpClientHandler.CookieContainer = new CookieContainer();
var httpcontent = new StringContent(content);
HttpClient httpClient = new HttpClient(httpClientHandler);
httpClient.DefaultRequestHeaders.ExpectContinue = false;
httpClient.BaseAddress = ews_url;
// var request = httpClient.PostAsync(ews_url, httpcontent);
var requestMessage = new HttpRequestMessage();
requestMessage.RequestUri = ews_url;
requestMessage.Content = httpcontent;
requestMessage.Method = HttpMethod.Post;
var request = httpClient.SendAsync(requestMessage);
HttpResponseMessage response = await request; // --> Error
the instance of HttpClient (httpClient) always runs into an exception in the line marked with the --> Error comment. I can not find any wrong code lines. The exception says: "the underlying connection closed", "Error on sending" but the connection is not closed as you see. I tried several options like "UseDefaultCredentials true/false", "new NetworkCredentials".
My scenario is an App sending soap messages to exchange web services (ews).
Do you have any ideas solving my problem?
Related
public virtual string GetPaymentStatus(HttpContext context, NGeniusConfiguration configuration)
{
var reference = context.Request.Query[NGeniusConstants.ApiQueryStringRef].ToString();
var token = GetAccessToken(configuration);
var url = new Uri(GetPaymentBaseUrl(configuration), string.Format(NGeniusConstants.ApiUrl.OrderStatus, configuration.OutletId, reference));
var client = new RestClient(url);
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", string.Format(NGeniusConstants.ApiauthorizationMode.Bearer, token));
request.AddHeader("accept", NGeniusConstants.ApiPaymentAcceptJson);
IRestResponse response =client.Execute(request);
if (response.StatusCode == HttpStatusCode.OK)
{
var status = JsonConvert.DeserializeObject<NGeniusOrderStatusResponse>(response.Content);
return status.Embedded.Payment.First().State;
}
else
{
throw new Exception("Error while getting the order status", response.ErrorException);
}
}
I am fairly new to .Net Core. Can someone tell me why I have errors in Method.GET, IRestResponse and Execute? I have already included "using RestSharp;" in the program as well.
for more reference the the project i am implementing is from GITHUB.
I have a client code implementation to consume a service with IEndpointBehavior to track request and response data.
everything was working fine till I implement bearer token using OperationContextScope.
var httpRequestProperty = new HttpRequestMessageProperty();
httpRequestProperty.Headers[System.Net.HttpRequestHeader.Authorization] = "Bearer " + accessToken;
var context = new OperationContext(client.InnerChannel);
context.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;
var operationContext = new OperationContextScope(context);
BeforeSendRequest, AfterReceiveReply stops calling since I implemented token-based authentication and it is working when I remove OperationContextScope code used for adding a token to the header.
I need help to understand how can I use both (token inserting using OperationContextScope and IEndpointBehavior for message interceptor) together.
According to your description, I did the test and successfully used OperationContextScope and IEndpointBehavior together.You may put the code of OperationContextScope in front of the code of IEndpointBehavior, which will cause the code of IEndpointBehavior to fail.
Service1Client service1Client = new Service1Client();
var httpRequestProperty = new HttpRequestMessageProperty();
httpRequestProperty.Headers[System.Net.HttpRequestHeader.Authorization] = "Bearer";
var context = new OperationContext(service1Client.InnerChannel);
context.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;
var operationContext = new OperationContextScope(context);
service1Client.Endpoint.Behaviors.Add(new Interceptor());
service1Client.GetUserData("Test");
The above code structure will cause this problem.
The correct code structure should look like this:
Service1Client service1Client = new Service1Client();
service1Client.Endpoint.Behaviors.Add(new Interceptor());
var httpRequestProperty = new HttpRequestMessageProperty();
httpRequestProperty.Headers[System.Net.HttpRequestHeader.Authorization] = "Bearer";
var context = new OperationContext(service1Client.InnerChannel);
context.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;
var operationContext = new OperationContextScope(context);
service1Client.GetUserData("Test");
I was trying to replace obsolete IdentityServer methods and types and as I had been warned about, I tried to replace DiscoveryClient() and TokenClient() with appropiate methods like in the examples of the latest identity server docs. When I try to get related endpoints by GetDiscoveryDocumentAsync it returns null even though I could read those values with current code and also get those values on browser.
Besides, when I by-pass the step of discovery and supplying the direct token endpoint RequestTokenAsync returns null because of Not Found exception.
For the sake of clearity of the question I should say that I have not changed anything (its settings or endpoints) in my Identity server project (from which I try to get access token).
Followings are my previous and updated code to achieve what I've described. Any help or suggestion is appreciated. Thanks in advance.
Previous Code (Working):
var testServer = new TestServer(builder);
var client = testServer.CreateClient();
client.BaseAddress = new Uri("http://localhost:5000");
var discoClient = new DiscoveryClient(AuthorityUrl) {Policy = {RequireHttps = false}};
var disco = discoClient.GetAsync().Result;
var tokenClient = new TokenClient(disco.TokenEndpoint, ClientId, ClientSecret);
var tokenResponse = tokenClient.RequestClientCredentialsAsync(Scope).Result;
client.SetBearerToken(tokenResponse.AccessToken);
Updated Code (Not Working):
var testServer = new TestServer(builder);
var client = testServer.CreateClient();
client.BaseAddress = new Uri("http://localhost:5000");
//var discoClient = new DiscoveryClient(AuthorityUrl) {Policy = {RequireHttps = false}};
var disco = client.GetDiscoveryDocumentAsync(new DiscoveryDocumentRequest()
{ Address = AuthorityUrl, Policy = new DiscoveryPolicy() { RequireHttps = false, Authority = AuthorityUrl} }).Result;
;
if (disco.IsError)
{
throw new Exception(disco.Error);
}
//var tokenClient = new TokenClient(disco.TokenEndpoint, ClientId, ClientSecret);
var tokenClient = client.RequestTokenAsync(new TokenRequest()
{ Address = disco.TokenEndpoint, ClientId = ClientId, ClientSecret = ClientSecret, GrantType = GrantType}).Result;
//var tokenResponse = tokenClient.RequestClientCredentialsAsync(Scope).Result;
client.SetBearerToken(tokenClient.AccessToken);
return client;
Edit:
Updated my code as shown below and still getting the same error.
var testServer = new TestServer(builder);
var client = testServer.CreateClient();
client.BaseAddress = new Uri("http://localhost:5000");
//var discoClient = new DiscoveryClient(AuthorityUrl) {Policy = {RequireHttps = false}};
var disco = await client.GetDiscoveryDocumentAsync(new DiscoveryDocumentRequest()
{ Address = AuthorityUrl, Policy = new DiscoveryPolicy() { RequireHttps = false, Authority = AuthorityUrl } });
;
if (disco.IsError)
{
throw new Exception(disco.Error);
}
//var tokenClient = new TokenClient(disco.TokenEndpoint, ClientId, ClientSecret);
var tokenClient =await client.RequestTokenAsync(new ClientCredentialsTokenRequest()
{ Address = disco.TokenEndpoint, ClientId = ClientId, ClientSecret = ClientSecret, GrantType = GrantType , Scope = Scope});
client.SetBearerToken(tokenClient.AccessToken);
return client;
Error:
"Error connecting to AuthorityUrl/.well-known/openid-configuration: Not Found"
I am able to succesfully request a SAML SecurityToken from ADFS with a user name and password using the following code:
private GenericXmlSecurityToken IssueToken(string userName, string password)
{
var relyingPartyIdentifier = new EndpointReference("https://mywebsite.net");
var stsAddress = "https://myadfs.com/adfs/services/trust/13/usernamemixed";
var wsBinding = new WS2007HttpBinding(SecurityMode.TransportWithMessageCredential);
wsBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm;
wsBinding.Security.Message.EstablishSecurityContext = false;
wsBinding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
var trustChannelFactory = new WSTrustChannelFactory(wsBinding, stsAddress);
trustChannelFactory.Credentials.SupportInteractive = false;
trustChannelFactory.TrustVersion = TrustVersion.WSTrust13;
trustChannelFactory.Credentials.UserName.Password = password;
trustChannelFactory.Credentials.UserName.UserName = userName;
var tokenRequest = new RequestSecurityToken()
{
RequestType = RequestTypes.Issue,
AppliesTo = relyingPartyIdentifier,
KeyType = KeyTypes.Symmetric,
TokenType = "http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1"
};
tokenRequest.Claims.Add(new RequestClaim(ClaimTypes.Name));
tokenRequest.Claims.Add(new RequestClaim(ClaimTypes.Email));
var channel = trustChannelFactory.CreateChannel();
var token = (GenericXmlSecurityToken)channel.Issue(tokenRequest);
return token;
}
However, that token will expire in an hour. So my question is, how can I issue a new token based on the initial token, such that I don't need to remember the username and password?
I tried the following code:
public GenericXmlSecurityToken RenewToken(SecurityToken token)
{
var relyingPartyIdentifier = new EndpointReference("https://mywebsite.net");
var stsAddress = "https://myadfs.com/adfs/services/trust/13/usernamemixed";
var wsBinding = new WS2007FederationHttpBinding(WSFederationHttpSecurityMode.TransportWithMessageCredential);
wsBinding.Security.Message.EstablishSecurityContext = false;
wsBinding.Security.Message.IssuerAddress = new EndpointAddress(new Uri(stsAddress));
wsBinding.Security.Message.IssuerBinding = new WS2007HttpBinding(SecurityMode.TransportWithMessageCredential);
wsBinding.Security.Message.IssuerMetadataAddress = new EndpointAddress("https://myadfs.com/adfs/services/trust/mex");
var trustChannelFactory = new WSTrustChannelFactory(wsBinding, stsAddress);
trustChannelFactory.Credentials.SupportInteractive = false;
trustChannelFactory.Credentials.UserName.UserName = Settings.UserName;
trustChannelFactory.TrustVersion = TrustVersion.WSTrust13;
var tokenRequest = new RequestSecurityToken()
{
RequestType = RequestTypes.Renew,
RenewTarget = new SecurityTokenElement(token),
AppliesTo = relyingPartyIdentifier,
KeyType = KeyTypes.Symmetric,
TokenType = "http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1",
};
tokenRequest.Claims.Add(new RequestClaim(ClaimTypes.Name));
tokenRequest.Claims.Add(new RequestClaim(ClaimTypes.Email));
var channel = trustChannelFactory.CreateChannel();
// This call fails with:
// SecurityNegotiationException: Secure channel cannot be opened because security negotiation with the remote endpoint has failed. This may be due to absent or incorrectly specified EndpointIdentity in the EndpointAddress used to create the channel. Please verify the EndpointIdentity specified or implied by the EndpointAddress correctly identifies the remote endpoint. '
// Inner Exception: FaultException: An error occurred when verifying security for the message.
var newToken = (GenericXmlSecurityToken)channel.Issue(tokenRequest);
return newToken;
}
But the call to channel.Issue fails with the following exception:
SecurityNegotiationException: Secure channel cannot be opened because security negotiation with the remote endpoint has failed. This may be due to absent or incorrectly specified EndpointIdentity in the EndpointAddress used to create the channel. Please verify the EndpointIdentity specified or implied by the EndpointAddress correctly identifies the remote endpoint. '
Inner Exception: FaultException: An error occurred when verifying security for the message.
I am completely clueless as how to get a new token using the initial token.
I'm trying to talk to this service here:
https://dmrsit1gateway1.skat.dk/B2B/USImportoer/Service?WSDL
It's a Oracle Weblogic service using x509 certificates.
Whenever I send a request I receive a SecurityAccessDeniedException with the additional info:
{"Failed to derive subject from token.javax.security.auth.login.LoginException: javax.security.auth.callback.UnsupportedCallbackException: Unsupported callback class: NameCallback javax.security.auth.callback.NameCallback#15d38692"}
Somehow my requests does not seem to conform with what's expected.
This is my latest attempt:
var binding = new CustomBinding();
var sec = (AsymmetricSecurityBindingElement)SecurityBindingElement.CreateMutualCertificateBindingElement(MessageSecurityVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10);
var x509token = new X509SecurityTokenParameters();
sec.EnableUnsecuredResponse = true;
sec.EndpointSupportingTokenParameters.Signed.Add(x509token);
sec.IncludeTimestamp = true;
sec.SecurityHeaderLayout = SecurityHeaderLayout.LaxTimestampLast;
sec.AllowInsecureTransport = true;
binding.Elements.Add(sec);
binding.Elements.Add(new TextMessageEncodingBindingElement(MessageVersion.Soap11, Encoding.UTF8));
HttpsTransportBindingElement httpsBindingElement = new HttpsTransportBindingElement();
httpsBindingElement.RequireClientCertificate = true;
binding.Elements.Add(httpsBindingElement);
string endpoint = "https://dmrsit1gateway1.skat.dk:443/B2B/USImportoer/Service?WSDL";
var client = new USImportoerServiceTypeClient(binding, new EndpointAddress(new Uri(endpoint), new DnsEndpointIdentity("REDACTED"), new AddressHeaderCollection()));
client.ClientCredentials.ServiceCertificate.SetDefaultCertificate(StoreLocation.CurrentUser, StoreName.My, X509FindType.FindByThumbprint, "REDACTED");
client.ClientCredentials.ClientCertificate.SetCertificate(StoreLocation.CurrentUser, StoreName.My, X509FindType.FindByThumbprint, "REDACTED");
var response = client.getUSDispensationTypeListeHent(input);
Any input how to troubleshoot this would be highly appreciated.