Create SAML response from assertion in C# 4.5 (WIF) - c#

I need a way to POST a <samlp:response> message to a certain URL, its fairly simple and .NET helps me with Saml2Assertion class but I can't seem to find a way to wrap that assertion in a response and have it serialized (or even send without manual post)?
Saml2Assertion assert = new Saml2Assertion(new Saml2NameIdentifier("SAMLIssuer"));
assert.Subject = new Saml2Subject(new Saml2NameIdentifier("10001", new Uri("urn:oasis:names:tc:SAML:2.0:nameid-format:persistent")));
Saml2AuthenticationContext context = new Saml2AuthenticationContext(new Uri("urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport"));
assert.Statements.Add(new Saml2AuthenticationStatement(context, DateTime.Now));
string assertion;
using (var sw = new StringWriter())
{
var xws = new XmlWriterSettings();
using (var xw = XmlWriter.Create(sw, xws))
{
var handler = new Saml2SecurityTokenHandler();
handler.WriteToken(xw, new Saml2SecurityToken(assert));
}
assertion = sw.ToString();
}
And the XML I get for assert seems fine:
<?xml version="1.0" encoding="utf-16"?>
<Assertion ID="_fc348927-c0bf-4955-b98f-483043d8dedd" IssueInstant="2017-04-19T11:29:38.464Z" Version="2.0" xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
<Issuer>SAMLIssuer</Issuer>
<Subject>
<NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent">10001</NameID>
</Subject>
<AuthnStatement AuthnInstant="2017-04-19T11:29:39.040Z">
<AuthnContext>
<AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</AuthnContextClassRef>
</AuthnContext>
</AuthnStatement>
</Assertion>
So, what now? How do I get from my code to getting:
<samlp:Response
xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
ID="new id"
InResponseTo="old id"
Version="2.0"
IssueInstant="2017-04-19T11:29:39.040Z"
Destination="some url">
<saml:Issuer>SAMLIssuer</saml:Issuer>
<samlp:Status>
<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
</samlp:Status>
<saml:Assertion ....
without using external libraries or making my own wrappers/string concatenations? I can't seem to find anything in .NET 4.5 implementation of WIF that can help me.

AFAIK .NET has no built-in support for the SAMLp protocol. It only supports WsFederation. Also have a look here : How should I implement SAMLP 2.0 in an ASP.NET MVC 4 service provider?

Related

how to get all open issue from easy redmine using api c#

var baseAddress = new Uri("http://www.easyredmine.com/");
using (var httpClient = new HttpClient { BaseAddress = baseAddress })
{
using (var response = await httpClient.GetAsync("issues/{id}.xml{?include}"))
{
string responseData = await response.Content.ReadAsStringAsync();
}
}
in this link you can found the API documentation of Redmine:
https://easyredmine.docs.apiary.io/
However, you can take all issue list with this url:
http://www.easyredmine.com/issues.xml
You have to create the model to map the result of the call and then with linq you can filter the list of objects obtained.
The model of reponse is this:
<issues total_count="1" offset="0" limit="25" type="array">
<issue>
<id>765</id>
<project id="71" name="Administration"/>
<tracker id="13" name="Other"/>
<status id="1" name="Planned"/>
<priority id="12" name="High"/>
<author id="5" name="Andrew Smith"/>
<assigned_to id="5" name="Andrew Smith"/>
<subject>issue subject</subject>
<description>
issue description
</description>
<start_date>2014-04-11</start_date>
<due_date>2014-04-11</due_date>
<done_ratio>0</done_ratio>
<estimated_hours>1.0</estimated_hours>
<easy_email_to>test#test.com</easy_email_to>
<easy_email_cc>test#test.com</easy_email_cc>
<created_on>2014-04-11T08:24:47Z</created_on>
<updated_on>2014-04-11T08:24:47Z</updated_on>
<closed_on/>
<sprint id="1" name="Sprint" due_date="2014-04-11"></sprint>
</issue>
</issues>
I think you’ll have to filter through the 'status' field

Web Service dll behaving differently in Xamarin from Framework and Core versions

I have a SOAP web service that I need to call in a wide array applications, so I created a service DLL that targets both .net standard 2.0 and .net framework 4.6.1.
The DLL seems to work fine with on Desktop Framework applications, and on Desktop Core applications. However, the behavior on a Xamarin Android project is just slightly off of what the other two are.
A correctly sent message from the other two applications looks like this:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ZBAPI_GOODSMVT_CREATE xmlns="urn:sap-com:document:sap:rfc:functions">
<CODE xmlns="">
<GM_CODE>03</GM_CODE>
</CODE>
<HEADER xmlns="">
<PSTNG_DATE>2019-12-08</PSTNG_DATE>
<DOC_DATE>2019-12-08</DOC_DATE>
</HEADER>
<ITEM xmlns="">
... data here ...
</ITEM>
<RETURN xmlns="">
... data here ...
</RETURN>
</ZBAPI_GOODSMVT_CREATE>
</s:Body>
And the a successfully sent(but not processed) message from the android device is so:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ZBAPI_GOODSMVT_CREATE>
<CODE>
<GM_CODE>03</GM_CODE>
</CODE>
<HEADER>
<PSTNG_DATE>2019-12-08</PSTNG_DATE>
<DOC_DATE>2019-12-08</DOC_DATE>
</HEADER>
<ITEM>
... data here ...
</ITEM>
<RETURN>
... data here ...
</RETURN>
</ZBAPI_GOODSMVT_CREATE>
</s:Body>
So nearly identical, except every namespace inside the body element has been stripped out.
I've confirmed with SOAPUI that All the namespaces are needed, even the blank ones.
The DLL in question is, as stated, a .net standard 2.0, and the service was imported using the vendor provided wsdl file.
inside the DLL code I am calling the service like so:
private void RunRequest(ServiceData payload)
{
var binding = new BasicHttpBinding();
binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
binding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.Basic;
var address = new EndpointAddress("https:\\serviceaddress.com\service");
new ChannelFactory<ServiceChannel>(binding, address).Using(factory =>
{
factory.Credentials.UserName.UserName = "Uset";
factory.Credentials.UserName.Password = "Pass";
var proxy = factory.CreateChannel();
proxy.Open();
var context = new OperationContext((IClientChannel)proxy);
var prevOpContext = OperationContext.Current;
OperationContext.Current = context;
try
{
var results = proxy.ServiceChannel_CREATEAsync(payload).ConfigureAwait(false).GetAwaiter().GetResult().SerivceChannelResponse;
System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(ServiceChannelResponse));
using StringWriter text = new StringWriter();
serializer.Serialize(text, results);
Message = text.ToString();
}
catch
{
throw;
}
});
how can I force the xmlns namespaces inclusion across all platforms?

How to add info to sofort API XML using C#

I am going to use sofort payment API in ASP.Net MVC, but I am having issue to add info in following XML format in C#.
<?xml version="1.0" encoding="UTF-8" ?>
<multipay>
<project_id>53245</project_id>
<interface_version>pn_test_1</interface_version>
<amount>2.20</amount>
<currency_code>EUR</currency_code>
<reasons>
<reason>Testueberweisung</reason>
<reason>-TRANSACTION-</reason>
</reasons>
<user_variables>
<user_variable>test</user_variable>
</user_variables>
<success_url>xyz</success_url>
<success_link_redirect>1</success_link_redirect>
<abort_url>xyz</abort_url>
<notification_urls>
<notification_url>xyz</notification_url>
<notification_url notify_on="received,loss">xyz</notification_url>
</notification_urls>
<su />
</multipay>
var xmlRequest = new XElement("multipay",
new XElement("project_id", "53245"),
new XElement("interface_version", "pn_test_1"),
new XElement("amount", "2.20"),
new XElement("currency_code", "EUR"),
new XElement("reasons", new XElement("reason", "Testueberweisung"), new XElement("reason", "-TRANSACTION-"))
);
string xmlreq = xmlRequest.ToString();

Update Merchant Order ID in Amazon Marketplace

I need to update MerchantOrderID in Amazon Marketplace via Amazon MWS API using C#.
So, first I created XML file like:
<?xml version="1.0"?>
<AmazonEnvelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="amzn-envelope.xsd">
<Header>
<DocumentVersion>1.01</DocumentVersion>
<MerchantIdentifier>M_STORE_3918753</MerchantIdentifier>
</Header>
<MessageType>OrderAcknowledgement</MessageType>
<Message>
<MessageID>1</MessageID>
<OrderAcknowledgement>
<AmazonOrderID>104-9209939-0469021</AmazonOrderID>
<MerchantOrderID>100828163</MerchantOrderID>
<StatusCode>Success</StatusCode>
<Item>
<AmazonOrderItemCode>11111111111111</AmazonOrderItemCode>
<MerchantOrderItemID>111111</MerchantOrderItemID>
<AmazonOrderItemCode>22222222222222</AmazonOrderItemCode>
<MerchantOrderItemID>222222222</MerchantOrderItemID>
</Item>
</OrderAcknowledgement>
</Message>
</AmazonEnvelope>
then I try to call Amazon MWS SubmitFeed:
SubmitFeedRequest request = new SubmitFeedRequest();
request.Merchant = merchantId;
request.MarketplaceIdList = new IdList();
request.MarketplaceIdList.Id = new List<string>(new string[] { marketplaceId });
request.FeedContent = File.Open(path, FileMode.Open, FileAccess.Read);
request.ContentMD5 = MarketplaceWebServiceClient.CalculateContentMD5(request.FeedContent);
request.FeedContent.Position = 0;
request.FeedType = "_POST_ORDER_ACKNOWLEDGEMENT_DATA_";
MarketplaceWebService.MarketplaceWebService serviceFeed = new MarketplaceWebServiceClient(
accessKeyId,
secretAccessKey,
applicationName,
applicationVersion,
configFeed);
SubmitFeedResponse response = serviceFeed.SubmitFeed(request);
it succesfully submits but when I open my order in Amazon (sellercentral.amazon.com) it says "none saved":
Your Merchant Order ID: # none saved
Who can help me, what is wrong or what should I do?
Thanks!
For those who want to update merchant order id in multiple orders at once, here is example (also works in amazon mws scratchpad):
<?xml version="1.0"?>
<AmazonEnvelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="amzn-envelope.xsd">
<Header>
<DocumentVersion>1.01</DocumentVersion>
<MerchantIdentifier>ALVH0CYWPBFNA</MerchantIdentifier>
</Header>
<MessageType>OrderAcknowledgement</MessageType>
<Message>
<MessageID>1</MessageID>
<OrderAcknowledgement>
<AmazonOrderID>000-0000000-0000000</AmazonOrderID>
<MerchantOrderID>YOUR_MERCHANT_ORDER_ID</MerchantOrderID>
<StatusCode>Success</StatusCode>
</OrderAcknowledgement>
</Message>
<Message>
<MessageID>2</MessageID>
<OrderAcknowledgement>
<AmazonOrderID>000-0000000-0000000</AmazonOrderID>
<MerchantOrderID>YOUR_MERCHANT_ORDER_ID</MerchantOrderID>
<StatusCode>Success</StatusCode>
</OrderAcknowledgement>
</Message>
</AmazonEnvelope>
It's actually right code. Somehow amazon doesn't mark some special orders or marks them later.

Problem with Fedex Address Verification Web Reference

I'm trying to get the sample FedEx Address Verification application to work in C#. After contacting my FedEx technical contact and having him activate Address Verification on my test account (apparently it is considered an advanced service that requires additional permissions) I was able to compile and run the example application.
However, I wasn't getting quite the results I expected given the settings...
request.Options.ConvertToUpperCase = true;
request.Options.CheckResidentialStatus = true;
Based on these flags, I expected to have the address come back in upper case, and to be able to check the Residential or ResidentialStatus properties to determine commercial vs residential. Neither were occuring.
So I installed Fiddler to see the exact SOAP exchange that was taking place and found that the outbound Options tag was not populating except for one property, MaximumNumberOfMatches.
Is there something I should check for in the Reference.cs file that is created by Visual Studio? I didn't see anything out of the norm, but something is happening that is preventing the serialization of some of the properties.
--Edit--
Updated my code as per the suggestion below. Unfortunately, it still only populates 2 of the options parameters. I've included the C# settings code and the outbound/inbound SOAP request below. Can anyone think of a reason the rest of the options are not being sent in the SOAP request?
AddressValidationRequest request = new AddressValidationRequest();
//
request.WebAuthenticationDetail = new WebAuthenticationDetail();
request.WebAuthenticationDetail.UserCredential = new WebAuthenticationCredential();
request.WebAuthenticationDetail.UserCredential.Key = "XXX-KEY-XXX"; // Replace "XXX" with the Key
request.WebAuthenticationDetail.UserCredential.Password = "XXX-PWD-XXX"; // Replace "XXX" with the Password
//
request.ClientDetail = new ClientDetail();
request.ClientDetail.AccountNumber = "XXX-ACCT#-XXX"; // Replace "XXX" with client's account number
request.ClientDetail.MeterNumber = "XXX-MTR#-XXX"; // Replace "XXX" with client's meter number
//
request.TransactionDetail = new TransactionDetail();
request.TransactionDetail.CustomerTransactionId = "***Address Validation v2 Request using VC#***"; // This is just an echo back
//
request.Version = new VersionId(); // Creates the Version element with all child elements populated
//
request.RequestTimestamp = DateTime.Now;
//
request.Options = new AddressValidationOptions();
request.Options.CheckResidentialStatus = true;
request.Options.CheckResidentialStatusSpecified = true;
request.Options.VerifyAddresses = true;
request.Options.MaximumNumberOfMatches = "5";
request.Options.StreetAccuracy = AddressValidationAccuracyType.MEDIUM;
request.Options.DirectionalAccuracy = AddressValidationAccuracyType.MEDIUM;
request.Options.CompanyNameAccuracy = AddressValidationAccuracyType.MEDIUM;
request.Options.ConvertToUpperCase = true;
request.Options.RecognizeAlternateCityNames = true;
request.Options.ReturnParsedElements = true;
//
request.AddressesToValidate = new AddressToValidate[2];
request.AddressesToValidate[0] = new AddressToValidate();
request.AddressesToValidate[0].AddressId = "Kimmel";
request.AddressesToValidate[0].Address = new Address();
request.AddressesToValidate[0].Address.StreetLines = new String[1] { "425 Morningside Dr" };
request.AddressesToValidate[0].Address.City = "Deerfield";
request.AddressesToValidate[0].Address.PostalCode = "53531";
request.AddressesToValidate[0].Address.CountryCode = "US";
//
request.AddressesToValidate[1] = new AddressToValidate();
request.AddressesToValidate[1].AddressId = "WD";
request.AddressesToValidate[1].Address = new Address();
request.AddressesToValidate[1].Address.StreetLines = new String[1] { "2830 Progress Rd" };
request.AddressesToValidate[1].Address.PostalCode = "53716";
request.AddressesToValidate[1].CompanyName = "Wingra Direct";
The outbound SOAP Request (obtained using Fiddler). Note the missing options:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<AddressValidationRequest xmlns="http://fedex.com/ws/addressvalidation/v2">
<WebAuthenticationDetail>
<UserCredential>
<Key>XXX-KEY-XXX</Key>
<Password>XXX-PWD-XXX</Password>
</UserCredential>
</WebAuthenticationDetail>
<ClientDetail>
<AccountNumber>XXX-ACCT#-XXX</AccountNumber>
<MeterNumber>XXX-MTR#-XXX</MeterNumber>
</ClientDetail>
<TransactionDetail>
<CustomerTransactionId>***Address Validation v2 Request using VC#***</CustomerTransactionId>
</TransactionDetail>
<Version>
<ServiceId>aval</ServiceId>
<Major>2</Major>
<Intermediate>0</Intermediate>
<Minor>0</Minor>
</Version>
<RequestTimestamp>2010-08-26T16:40:13.2026134-05:00</RequestTimestamp>
<Options>
<CheckResidentialStatus>true</CheckResidentialStatus>
<MaximumNumberOfMatches>5</MaximumNumberOfMatches>
</Options>
<AddressesToValidate>
<AddressId>Kimmel</AddressId>
<Address>
<StreetLines>425 Morningside Dr</StreetLines>
<City>Deerfield</City>
<PostalCode>53531</PostalCode>
<CountryCode>US</CountryCode>
<Residential>true</Residential>
</Address>
</AddressesToValidate>
<AddressesToValidate>
<AddressId>WD</AddressId>
<CompanyName>Wingra Direct</CompanyName>
<Address>
<StreetLines>2830 Progress Rd</StreetLines>
<PostalCode>53716</PostalCode>
</Address>
</AddressesToValidate>
</AddressValidationRequest>
</soap:Body>
</soap:Envelope>
The response I get back is:
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<env:Header xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"/>
<soapenv:Body>
<v2:AddressValidationReply xmlns:v2="http://fedex.com/ws/addressvalidation/v2">
<v2:HighestSeverity>SUCCESS</v2:HighestSeverity>
<v2:Notifications>
<v2:Severity>SUCCESS</v2:Severity>
<v2:Source>wsi</v2:Source>
</v2:Notifications>
<v2:TransactionDetail xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<v2:CustomerTransactionId>***Address Validation v2 Request using VC#***</v2:CustomerTransactionId>
</v2:TransactionDetail>
<v2:Version xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<v2:ServiceId>aval</v2:ServiceId>
<v2:Major>2</v2:Major>
<v2:Intermediate>0</v2:Intermediate>
<v2:Minor>0</v2:Minor>
</v2:Version>
<v2:ReplyTimestamp>2010-08-26T21:40:14.140Z</v2:ReplyTimestamp>
<v2:AddressResults>
<v2:AddressId>Kimmel</v2:AddressId>
<v2:ProposedAddressDetails>
<v2:Score>93</v2:Score>
<v2:Changes>MODIFIED_TO_ACHIEVE_MATCH</v2:Changes>
<v2:ResidentialStatus>UNAVAILABLE</v2:ResidentialStatus>
<v2:DeliveryPointValidation>CONFIRMED</v2:DeliveryPointValidation>
<v2:Address>
<v2:StreetLines>425 Morningside Dr</v2:StreetLines>
<v2:City>Deerfield</v2:City>
<v2:StateOrProvinceCode>WI</v2:StateOrProvinceCode>
<v2:PostalCode>53531-9492</v2:PostalCode>
<v2:CountryCode>US</v2:CountryCode>
</v2:Address>
<v2:RemovedNonAddressData/>
</v2:ProposedAddressDetails>
</v2:AddressResults>
<v2:AddressResults>
<v2:AddressId>WD</v2:AddressId>
<v2:ProposedAddressDetails>
<v2:Score>93</v2:Score>
<v2:Changes>MODIFIED_TO_ACHIEVE_MATCH</v2:Changes>
<v2:ResidentialStatus>UNAVAILABLE</v2:ResidentialStatus>
<v2:DeliveryPointValidation>CONFIRMED</v2:DeliveryPointValidation>
<v2:CompanyName>Wingra Direct</v2:CompanyName>
<v2:Address>
<v2:StreetLines>2830 Progress Rd</v2:StreetLines>
<v2:City>Madison</v2:City>
<v2:StateOrProvinceCode>WI</v2:StateOrProvinceCode>
<v2:PostalCode>53716-3338</v2:PostalCode>
<v2:CountryCode>US</v2:CountryCode>
</v2:Address>
<v2:RemovedNonAddressData/>
</v2:ProposedAddressDetails>
</v2:AddressResults>
</v2:AddressValidationReply>
</soapenv:Body>
</soapenv:Envelope>
It appears that on option is ignored unless you also set the optionSpecified flag to true also.
Here is my new options code that works - the key being that you need to add the Options.(property)specified = true for each one you want:
request.Options = New AddressValidationOptions()
request.Options.CheckResidentialStatus = True
request.Options.CheckResidentialStatusSpecified = True
request.Options.VerifyAddresses = True
request.Options.VerifyAddressesSpecified = True
request.Options.MaximumNumberOfMatches = 5
request.Options.StreetAccuracy = AddressValidationAccuracyType.MEDIUM
request.Options.DirectionalAccuracy = AddressValidationAccuracyType.MEDIUM
request.Options.CompanyNameAccuracy = AddressValidationAccuracyType.MEDIUM
request.Options.ConvertToUpperCase = True
request.Options.ConvertToUpperCaseSpecified = True
request.Options.RecognizeAlternateCityNames = True
request.Options.RecognizeAlternateCityNamesSpecified = True
request.Options.ReturnParsedElements = True
request.Options.ReturnParsedElementsSpecified = True
I was unable to get the API working so I ended up manually coding the handling of SOAP requests and responses. Aside from the API not properly setting all the flags, I also found out that the FedEx DEV server was not returning the Residential Status, regardless of what the options were (confirmed by our FedEx Web Services contact). When we gained access to the production servers the new code worked like a charm.
Here's another answer from FedEx tech support:
"The address verification API is not available from the test
environment".
So I'm not sure how you got your test account "activated" for address verification. Supposedly the FedEx system uses the USPS production address verification system which is why it's not accessible from the FedEx test environment.
I don't know if I believe this 100%, but I know that I'm hitting the FedEx test server with valid credentials and getting a "Authentication Failed" response.

Categories

Resources