Using AssertionConsumerServiceIndex instead of assertionConsumerServiceUrl with itfoxtec - itfoxtec-identity-saml2

Is it possible to set a AssertionConsumerServiceIndex in a AuthnRequest like this SAML example below with ITfoxtec SAML 2.0
I want to have somethings like this:
<?xml version="1.0" encoding="UTF-8"?>
<samlp:AuthnRequest
xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
ID="_1330416073" Version="2.0" IssueInstant="2012-02-28T09:01:13Z"
AssertionConsumerServiceIndex="0" ProviderName="provider name">
<saml:Issuer>http://sp.example.com</saml:Issuer>
<samlp:RequestedAuthnContext Comparison="minimum">
<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef>
</samlp:RequestedAuthnContext>
</samlp:AuthnRequest>
Code:
var binding = new Saml2RedirectBinding();
return binding.Bind(new Saml2AuthnRequest(config)
{
RequestedAuthnContext = new RequestedAuthnContext
{
Comparison = AuthnContextComparisonTypes.Minimum,
AuthnContextClassRef = new string[] { AuthnContextClassTypes.PasswordProtectedTransport.OriginalString },
},
}).ToActionResult();

I'm afraid the ITfoxtec Identity SAML 2.0 component does not support the AssertionConsumerServiceIndex attribute.

Related

IDP Initiated Login

I'm trying to implement an IDP Initiated login in my company, we hire a platform that generates a SAML XML response for me and posts it to my backend (.NET Core 3.1).
This SAML Response is a Base64 hash and has already been converted to XML. The lib has some specific method to deal with SAML response in this scenario?
Thanks!
It is more or less the samme as the TestWebAppCore sample expect to recive in the AssertionConsumerService method. The code show a post binding, you can change it to redirect if the authn response is send as a query parameter.
var binding = new Saml2PostBinding();
var saml2AuthnResponse = new Saml2AuthnResponse(config);
binding.ReadSamlResponse(Request.ToGenericHttpRequest(), saml2AuthnResponse);
if (saml2AuthnResponse.Status != Saml2StatusCodes.Success)
{
throw new AuthenticationException($"SAML Response status: {saml2AuthnResponse.Status}");
}
binding.Unbind(Request.ToGenericHttpRequest(), saml2AuthnResponse);
await saml2AuthnResponse.CreateSession(HttpContext, claimsTransform: (claimsPrincipal) => ClaimsTransform.Transform(claimsPrincipal));
var relayStateQuery = binding.GetRelayStateQuery();
//var some_value = relayStateQuery.ContainsKey("some_key");
return Redirect("...some_url...");

Authenticating WEB API 2 .net framework 4.x in identity server 4 using OIDC

I know there are similar questions out there, but still it's not very clear,
after reading a bunch of posts related to the subject, this how i "understood" the code should look like, i am still dealing with all the concepts involved in oauth/openid/owin/katana/identityserver etc...
Big picture is: i have an angular application,
where the user register and log in, no consent is needed, once the user is logged in, the SPA will start comunicating with all the api's in the back and the api's should be able to authenticate against the auth server.
So basically,i need my web api to be able to authenticate in identity server 4, through client credentials grant type, with the issued token by the authentication server.
I got this client(web api 2 .net framework 4.5) defined in identiy server 4:
public static IEnumerable<Client> GetClients()
{
//client credentials client
return new List<Client>
{
new Client
{ ClientId = "client2",
AllowedGrantTypes = GrantTypes.ClientCredentials,
ClientSecrets =
{
new Secret("secret".Sha256())
},
AllowedScopes = { "api2" }
},
}
In the .net Api side i have this:
public void ConfigureAuth(IAppBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType =
CookieAuthenticationDefaults.AuthenticationType
});
app.UseOpenIdConnectAuthentication(new
OpenIdConnectAuthenticationOptions
{
ClientId = "client2",
Authority = "http://localhost:5000",
RequireHttpsMetadata = false,
ResponseType = "id_token",
Scope = "api2",
SignInAsAuthenticationType =
CookieAuthenticationDefaults.AuthenticationType,
}
});
And the controllers are decorated with the Autorize decorator.
These are the versions of the packages im using
id="Microsoft.Owin.Security.OpenIdConnect" version="4.0.0"
id="Microsoft.Owin.Security.OAuth" version="4.0.0"
id="Microsoft.Owin.Security" version="4.0.0"
id="Microsoft.Owin" version="4.0.0"
By the moment i am using one of the demo projects from the offical project site(https://github.com/IdentityServer/IdentityServer4.Samples), i added an extra call in the MVC demo app to call my api.
public async Task<IActionResult> CallApiUsingUserAccessToken2()
{
var accessToken = await HttpContext.GetTokenAsync("access_token");
var client = new HttpClient();
client.SetBearerToken(accessToken);
var content = await
client.GetStringAsync("http://localhost:17307/api
/Organization/GetOrganizationById/2007");
ViewBag.Json = JArray.Parse(content).ToString();
return View("Json");
}
According to the working demo, there are two ways to do this, but none have worked to me.
public async Task<IActionResult> CallApiUsingClientCredentials2()
{
var tokenClient = new TokenClient("http://localhost:5000/connect/token", "mvc", "secret");
var tokenResponse = await tokenClient.RequestClientCredentialsAsync("api1");
var client = new HttpClient();
client.SetBearerToken(tokenResponse.AccessToken);
var content = await client.GetStringAsync("http://localhost:17307/api/Organization/GetOrganizationById/2007");
ViewBag.Json = JArray.Parse(content).ToString();
return View("Json");
}
This is part of the response with the error, i am getting in both scenarios:
<div class="row">
<div class="col-sm-6">
<div class="alert alert-danger">
Sorry, there was an error
<strong>
<em>
: invalid_request
</em>
</strong>
<div>Invalid redirect_uri</div>
</div>
<div class="request-id">Request Id: 0HLIALF7L4N8J:00000001</div>
</div>
</div>
What is missing here or what is wrong, is the redirect_uri mandatory, why is not present in the configuration section for the .net core ?
This is how configuration of the api looks like in .net core and works fine.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvcCore()
.AddAuthorization()
.AddJsonFormatters();
services.AddAuthentication("Bearer")
.AddIdentityServerAuthentication(options =>
{
options.Authority = "http://localhost:5000";
options.RequireHttpsMetadata = false;
options.ApiName = "api1";
});
}
Thanks in advance.
Update
After some experimenting, i comfirming the issue i am having is in the api validating the access token using owin middleware.
public void ConfigureAuth(IAppBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = "Cookies",
});
JwtSecurityTokenHandler.InboundClaimTypeMap = new Dictionary<string,
string>
();
app.UseIdentityServerBearerTokenAuthentication
(new IdentityServerBearerTokenAuthenticationOptions
{
Authority = "http://localhost:5000",
RequiredScopes = new[] { "api2" },
});
}
I am using identityserver3.accesstokenvalidation to perform the validation, as it is recomended, but after getting the access token in the client application and pass it to the api request, i am getting a 401 unauthorized error, is this because it is expecting to operate under secure HTTPS ?, i notice for accesstokenvalidation v4 you can set "RequireHttpsMetadata = false" but i dont see this in v3, could be this the reason i am not getting the token validating ?
Try using the correct client_id first on this line from "mvc" to "client2"
var tokenClient = new TokenClient("http://localhost:5000/connect/token", "mvc", "secret");

how to call magento soap webservice in windows form application?

I have soap link like this http://example.com/index.php/api/v2_soap/?wsdl (it is a magento website), the username password is abc , 123
I just added a service reference at solution explorer the name is ServiceReference1
I created a button (using vs2015, project name is printOrder) as the code is following:
private void button1_Click(object sender, EventArgs e)
{
}
the app.config is the following:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="Binding" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://example.com/index.php/api/v2_soap/index/"
binding="basicHttpBinding" bindingConfiguration="Binding"
contract="ServiceReference1.PortType" name="Port" />
</client>
</system.serviceModel>
</configuration>
So,
1) how to create a soap client object with username and password?
2) after created soap client object, how do i call the web service?
i've searched a lot of topics in google but seems there is small different from my case......
Anyone know how to to that?
The same thing i want to do is
$cs = getSesstion();
$result = $cs['client']->salesOrderShipmentInfo($cs['session'], '200001811');
$complexFilter = array(
'complex_filter' => array(
array(
'key' => 'orderIncrementId',
'value' => array('key' => 'in', 'value' => '100004496')
)
)
);
var_dump($cs);
//$result = $cs['client']->salesOrderInfo($cs['session'],'100004496');
//var_dump($result);
function getSesstion() {
$client = new SoapClient('http://example.com/index.php/api/v2_soap/?wsdl');
$username = 'vtec';
$apikey= 'Abcd1234';
$session = $client->login($username, $apikey);
$cs = array();
$cs['client'] = $client;
$cs['session'] = $session;
return $cs;
}
----------------------------answer-----------------------------
with Regie Baquero's help, the right code i found is
ServiceReference1.PortTypeClient client = new ServiceReference1.PortTypeClient();
string session = client.login("vtec","Abcd1234");
Console.WriteLine(session);
//client.(session, "product_stock.list", "qqaz");
var result = client.salesOrderInfo(session, "145000037");
//client.endSession(session);
Console.WriteLine(result.increment_id.ToString());
If you have already added your soap service what you need is to declare it in your code something like:
`ServiceReference1.Service service variable = new ServiceReference1.Service();`
in order for you to access method or function inside the soap service.
Sample code if you have written your soap service in visual studio c# your code should look like this:
[WebMethod]
public bool Password_Verification(string password)
{
if(password=="12345")
{
return true;
}
}
you can access it using
`ServiceReference1.Service service variable = new ServiceReference1.Service();`
bool verify = service variable.Password_Verification("12345");
Same goes with wsdl file. you just need to know what function/method is implemented in that soap service.
.........................

How to distinguish faked SAML Response?

I have a HTTP POST servlet to receive SAML response and decode the response, then get the email from response. Suppose my IDP endpoint is https://myIdp.com. Following is an response example:
<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_8e8dc5f69a98cc4c1ff3427e5ce34606fd672f91e6" Version="2.0" IssueInstant="2014-07-17T01:01:48Z" Destination="http://sp.example.com/demo1/index.php?acs" InResponseTo="ONELOGIN_4fee3b046395c4e751011e97f8900b5273d56685">
<saml:Issuer>http://idp.example.com/metadata.php</saml:Issuer>
<samlp:Status>
<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
</samlp:Status>
<saml:Assertion xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" ID="pfx0e02f9bf-9d08-14ab-b927-4ab9b979e46b" Version="2.0" IssueInstant="2014-07-17T01:01:48Z">
<saml:Issuer>http://idp.example.com/metadata.php</saml:Issuer><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<ds:Reference URI="#pfx0e02f9bf-9d08-14ab-b927-4ab9b979e46b"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><ds:DigestValue>ckLpItzLtCvyEpzIMpBoOB4HQdU=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>VPa3SbxN6EzHKb3qg4Q8nh3eGok9rwifeZ3QPn784zOEqxxJcqttI8unOHiQJRjf5fepBvuWegPqAWSWi3vlAlSyHfVdofF1hthJJdDY94mT9jIc9rMKhm1zpn5b1LE3Pl6Bg0AMUlN7ajZP5v3lLSJPuGEAaptdQFHc1j5m0sU=</ds:SignatureValue>
<ds:KeyInfo><ds:X509Data><ds:X509Certificate>MIICajCCAdOgAwIBAgIBADANBgkqhkiG9w0BAQ0FADBSMQswCQYDVQQGEwJ1czETMBEGA1UECAwKQ2FsaWZvcm5pYTEVMBMGA1UECgwMT25lbG9naW4gSW5jMRcwFQYDVQQDDA5zcC5leGFtcGxlLmNvbTAeFw0xNDA3MTcxNDEyNTZaFw0xNTA3MTcxNDEyNTZaMFIxCzAJBgNVBAYTAnVzMRMwEQYDVQQIDApDYWxpZm9ybmlhMRUwEwYDVQQKDAxPbmVsb2dpbiBJbmMxFzAVBgNVBAMMDnNwLmV4YW1wbGUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDZx+ON4IUoIWxgukTb1tOiX3bMYzYQiwWPUNMp+Fq82xoNogso2bykZG0yiJm5o8zv/sd6pGouayMgkx/2FSOdc36T0jGbCHuRSbtia0PEzNIRtmViMrt3AeoWBidRXmZsxCNLwgIV6dn2WpuE5Az0bHgpZnQxTKFek0BMKU/d8wIDAQABo1AwTjAdBgNVHQ4EFgQUGHxYqZYyX7cTxKVODVgZwSTdCnwwHwYDVR0jBBgwFoAUGHxYqZYyX7cTxKVODVgZwSTdCnwwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQ0FAAOBgQByFOl+hMFICbd3DJfnp2Rgd/dqttsZG/tyhILWvErbio/DEe98mXpowhTkC04ENprOyXi7ZbUqiicF89uAGyt1oqgTUCD1VsLahqIcmrzgumNyTwLGWo17WDAa1/usDhetWAMhgzF/Cnf5ek0nK00m0YZGyc4LzgD0CROMASTWNg==</ds:X509Certificate></ds:X509Data></ds:KeyInfo></ds:Signature>
<saml:Subject>
<saml:NameID SPNameQualifier="http://sp.example.com/demo1/metadata.php" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">_ce3d2948b4cf20146dee0a0b3dd6f69b6cf86f62d7</saml:NameID>
<saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<saml:SubjectConfirmationData NotOnOrAfter="2024-01-18T06:21:48Z" Recipient="http://sp.example.com/demo1/index.php?acs" InResponseTo="ONELOGIN_4fee3b046395c4e751011e97f8900b5273d56685"/>
</saml:SubjectConfirmation>
</saml:Subject>
<saml:Conditions NotBefore="2014-07-17T01:01:18Z" NotOnOrAfter="2024-01-18T06:21:48Z">
<saml:AudienceRestriction>
<saml:Audience>http://sp.example.com/demo1/metadata.php</saml:Audience>
</saml:AudienceRestriction>
</saml:Conditions>
<saml:AuthnStatement AuthnInstant="2014-07-17T01:01:48Z" SessionNotOnOrAfter="2024-07-17T09:01:48Z" SessionIndex="_be9967abd904ddcae3c0eb4189adbe3f71e327cf93">
<saml:AuthnContext>
<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef>
</saml:AuthnContext>
</saml:AuthnStatement>
<saml:AttributeStatement>
<saml:Attribute Name="uid" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
<saml:AttributeValue xsi:type="xs:string">test</saml:AttributeValue>
</saml:Attribute>
<saml:Attribute Name="mail" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
<saml:AttributeValue xsi:type="xs:string">kliu#myIdp.com</saml:AttributeValue>
</saml:Attribute>
</saml:AttributeStatement>
</saml:Assertion>
</samlp:Response>
If someone knows the format of the response, he can use some post tools such as PostMan to send a post request to my SP post servlet. For example, he replaces the following attribute:
<saml:Attribute Name="mail" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
<saml:AttributeValue xsi:type="xs:string">kliu.fake#myIdp.com</saml:AttributeValue>
</saml:Attribute>
This request is not from myIdp.com. But my servlet could not validate if it is from myIdp.com. Is there a way to deny the fake request?
There is and I can get the signature using OpenSAML. I found some people using following code, but how to get the publicKey then get the publicCredential?
try {
BasicX509Credential publicCredential = new BasicX509Credential();
publicCredential.setPublicKey(publicKey);
SignatureValidator signatureValidator = new SignatureValidator(publicCredential);
signatureValidator.validate(signature);
} catch (ValidationException e) {
e.printStackTrace();
// throw new InvalidAssertionException("Assertion signature validation failed.");
}

invalid Assertion for SAML 2.0 Bearer Assertion for SalesForce.com

I am trying to do "SAML 2.0 Bearer Assertion for SalesForce"
I am getting {"error":"invalid_grant","error_description":"invalid assertion"}
Is there any way to validate bearer assertion at salesforce?
I did following in my code
String environment = "https://login.salesforce.com/services/oauth2/token?saml=MgoTx78aEPRbRaz0CkRqjaqrhP3sCa7w7.Y5wbrpGMNT07zKRYwcNWf0zs";
Map<String, String> map = new HashMap<String, String>();
HttpClient httpclient = new HttpClient();
PostMethod post = new PostMethod(environment);
post.addParameter("grant_type", "urn:ietf:params:oauth:grant-type:saml2-bearer");
post.addParameter("client_assertion", Base64.encode(samlResponse.getBytes()));
post.addParameter("client_assertion_type","urn:ietf:params:oauth:client_assertion_type:saml2-bearer");
post.addParameter("format", "json");
String accessToken= null;
String instanceUrl = null;
try {
httpclient.executeMethod(post);
JSONObject authResponse = new JSONObject(new JSONTokener(new InputStreamReader(post.getResponseBodyAsStream())));
System.out.println(authResponse.toString());
} catch (Exception e) {
e.printStackTrace();
} finally {
post.releaseConnection();
}
I have generated following assertion
<saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
ID="s2d3a451cf30560ca819118cf5785e722ea6da7b64" IssueInstant="2012-03-06T12:34:13Z"
Version="2.0">
<saml:Issuer>http://localhost:8080/opensso
</saml:Issuer>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
<ds:Reference URI="#s2d3a451cf30560ca819118cf5785e722ea6da7b64">
<ds:Transforms>
<ds:Transform
Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<ds:DigestValue>seHyxsFzsHCs0GaY7usF0DfMV58=
</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue> signature.....</ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate> certificate.....</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
<saml:Subject>
<saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"
NameQualifier="http://localhost:8080/opensso" SPNameQualifier="https://saml.salesforce.com">deepakmule</saml:NameID>
<saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<saml:SubjectConfirmationData
NotOnOrAfter="2012-03-06T12:44:13Z"
Recipient="https://login.salesforce.com/?saml=MgoTx78aEPRbRaz0CkRqjaqrhP3sCa7w7.Y5wbrpGMNT07zKRYwcNWf0zs" />
</saml:SubjectConfirmation>
</saml:Subject>
<saml:Conditions NotBefore="2012-03-06T12:34:13Z"
NotOnOrAfter="2012-03-06T12:44:13Z">
<saml:AudienceRestriction>
<saml:Audience>https://saml.salesforce.com</saml:Audience>
</saml:AudienceRestriction>
</saml:Conditions>
<saml:AuthnStatement AuthnInstant="2012-03-06T12:34:13Z"
SessionIndex="s27fb03a2b73bd8dc6846851bed7885b85e1d9ed6f">
<saml:AuthnContext>
<saml:AuthnContextClassRef> urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
</saml:AuthnContextClassRef>
</saml:AuthnContext>
</saml:AuthnStatement>
<saml:AttributeStatement>
<saml:Attribute Name="userid">
<saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">deepakmule</saml:AttributeValue>
</saml:Attribute>
</saml:AttributeStatement>
</saml:Assertion>
Are you trying to use the same IDP as you have configured for SSO for your Org, or are you trying to use the certificate added to a Remote Access application?
If you're trying to use your SSO configuration, then this looks pretty good - I'd check the SAML assertion validator
If you're trying to use the Bearer flow with a Remote Access application, then I'd look at the following
1) The Issuer should be the your Consumer Key from the remote access app ( the oauth client_id )
2) Post to our regular token endpoint
3) Use the salesforce username as the subject
4) Shorten the lifetime of your assertion to a minute

Resources