How to add SAML token to SOAP Request in C# - c#

I try to call a SOAP service by authenticating myself with a SAML token.
First I get a SAML token for the target by calling the ADFS:
var stsEndpoint = "https://ADFS.EXAMPLE/adfs/services/trust/13/kerberosmixed";
var reliantPartyUri = "http://reliant-party.com";
var binding = new CustomBinding();
var ssbe = SecurityBindingElement.CreateKerberosOverTransportBindingElement();
ssbe.DefaultAlgorithmSuite = SecurityAlgorithmSuite.Basic128;
ssbe.MessageSecurityVersion = MessageSecurityVersion.WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10;
binding.Elements.Add(ssbe);
binding.Elements.Add(new TextMessageEncodingBindingElement());
binding.Elements.Add(new HttpsTransportBindingElement());
var factory = new WSTrustChannelFactory(binding, new EndpointAddress(stsEndpoint));
factory.TrustVersion = TrustVersion.WSTrust13;
var rst = new RequestSecurityToken
{
RequestType = RequestTypes.Issue,
AppliesTo = new EndpointReference(reliantPartyUri)
};
var channel = factory.CreateChannel();
var token = channel.Issue(rst);
Now I want to use the SAML token to call a secured SOAP webservice. How is it possible to add the token? I've tried the following without success (the soap request does not contain any token):
//Service was created by an imported WSDL File - Methods and Types renamed for StackOverflow
var request = new Service.WsdlCreatedRequest();
[...]
var wsdlClient = new Service.WsdlCreatedService("HTTPS_Port");
var wsdlChannel = wsdlClient.ChannelFactory.CreateChannelWithIssuedToken(token);
wsdlChannel.WsdlCreatedMethod(request);
Any idea how to use the token in the request?

Related

Unable to update graph application based subscription with C#

I am trying to update the subscription expiry for my graph token. This is an application based subscription.
This is what I have tried:
var tokenExpiry = DateTime.UtcNow.AddMinutes(4230).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.0Z");
Lookup lp = new Lookup();
string access_token = "{MYACCESSTOKEN}";
_CreateRequestBody requestBody = new _CreateRequestBody
{
expirationDateTime = tokenExpiry
};
RestClient rc = new RestClient();
rc.EndPoint = "https://graph.microsoft.com/v1.0/subscriptions/" + subscriptionId;
rc.AccessToken = access_token;
rc.Method = HttpVerbs.PATCH;
rc.PostData = JsonConvert.SerializeObject(requestBody);
Error message is Invalid: expirationDateTime and its value must be included in the payload.

C# Consuming web service wsdl with access token

I'm trying to consume a WSDL web service and it requires an access token to be sent in the header. However, I keep getting a 401 error and I'm not sure if I am injecting the token correctly.
Heres a snippet of the code:
var client = new WsldClient();
var operationContext = new OperationContext(client.InnerChannel);
using (new OperationContextScope(operationContext))
{
var httpRequestProperty = new HttpRequestMessageProperty();
httpRequestProperty.Headers[HttpRequestHeader.Authorization] = "Bearer " + accessToken
operationContext.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;
client.SomeMethod();
}
This returns a 401 error.
You can try the following code:
var client = new MyClient();
client.ClientCredentials.UserName.UserName = "username";
client.ClientCredentials.UserName.Password = "password";
var httpRequestProperty = new HttpRequestMessageProperty();
httpRequestProperty.Headers[HttpRequestHeader.Authorization] = "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes(client.ClientCredentials.UserName.UserName + ":" + client.ClientCredentials.UserName.Password));
var context = new OperationContext(ormClient.InnerChannel);
using (new OperationContextScope(context))
{
context.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;
return await client.SomeMethod();
}
Authorization Header is missing in Http request using WCF
http://plainoldstan.blogspot.com/2008/07/avoid-http-401-roundtrip-with-adding.html

Not able to get certificate from HttpContext which was send from HttpClient

Well, I tried many different solutions but none seems to be working.
I have created Self Signed Certificate from IIS Manager and also import this to cert store.(Current User\Personal\Certificates). I tried to send that cert using below code part:
var cert = new X509Certificate2(#"C:\\Test.pfx", "asdf");
var handler = new HttpClientHandler() { ClientCertificateOptions = ClientCertificateOption.Manual };
handler.ClientCertificates.Add(cert);
var client = new HttpClient(handler);
var request = new HttpRequestMessage()
{
RequestUri = new Uri("https://localhost:44351/helloworld"),
Method = HttpMethod.Get,
};
var response = client.SendAsync(request).GetAwaiter().GetResult();
if (response.IsSuccessStatusCode)
{
var responseContent = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
}
But I when tried to receive it, it consists of null.
var clientCertificate = httpContext.Connection.ClientCertificate;
I think there exist some underlying concepts which I am not able to find out.

JWT creation is missing the signature portion

I'm trying to generate a JWT to use as an Authorization header for a HTTP request.
This is happening in C#, using the System.IdentityModel.Tokens.Jwt package from Nuget. My code for it is as follows:
byte[] certByteArray = Convert.FromBase64String("CertificatePrivateKeyPlaceholder");
var certificate = new X509Certificate2(certByteArray, "MyPassword");
var tokenHandler = new JwtSecurityTokenHandler();
var descriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new[]
{
new Claim("Issuer", "MyIssuer"),
new Claim("Audience", "MyAudience")
}),
EncryptingCredentials = new X509EncryptingCredentials(certificate),
SigningCredentials = new X509SigningCredentials(certificate, SecurityAlgorithms.RsaSha256Signature, SecurityAlgorithms.Sha256Digest),
};
var token = tokenHandler.CreateToken();
string stringToken = "bearer " + tokenHandler.WriteToken(token)
At the end stringToken looks like a JWT, but it is of the format aaaa.bbbb. and it appears that the signature portion (after the second . is missing)
Any pointers as to what I might be doing wrong?
You need to pass the descriptor as a parameter to CreateToken:
var token = tokenHandler.CreateToken(descriptor);

C# ADFS SAML token with Windows Auth / Current logged in user

How do I generate a SAML token without using credentials again?
Scenario: I am trying to send a SAML token to SAP web service. Since multiple users will be using this application I do not want to ask them for credentials but instead get them from current machine windows credentials and generate a SAML token.
This is what is currently being used in my code.
factory.Credentials.UserName.UserName = "bob";
factory.Credentials.UserName.Password = "abc!123";
// create token request
var rst = new RequestSecurityToken
{
RequestType = RequestTypes.Issue,
KeyType = KeyTypes.Symmetric,
AppliesTo = new EndpointReference(_serviceAddress.AbsoluteUri)
};
I use this method in my code to pass through the credentials of the logged in user to our ADFS server for single-sign in to O365 from the applications I write; you might be able to adapt the code to suit your purposes:
private GenericXmlSecurityToken NewGetAdfsSamlTokenWinAuth()
{
try
{
WS2007HttpBinding binding = new WS2007HttpBinding(SecurityMode.Transport);
binding.Security.Message.EstablishSecurityContext = false;
binding.Security.Message.ClientCredentialType = MessageCredentialType.Windows;
WSTrustChannelFactory factory = new WSTrustChannelFactory((binding), new EndpointAddress(this.adfsIntegratedAuthUrl));
factory.TrustVersion = TrustVersion.WSTrustFeb2005;
factory.Credentials.SupportInteractive = false;
var rst = new RequestSecurityToken
{
RequestType = RequestTypes.Issue,
AppliesTo = new EndpointReference("urn:federation:MicrosoftOnline"),
KeyType = KeyTypes.Bearer
};
IWSTrustChannelContract channel = factory.CreateChannel();
return channel.Issue(rst) as GenericXmlSecurityToken;
}
catch (Exception ex)
{
// Do something with the exception
}
return null;
}
This will return a GenericXmlSecurityToken which has a TokenXml.OuterXml property that contains the SAML assertion.

Categories

Resources