ADFS ignores my claim request - single-sign-on

I get ADFS details of user via wsfed, via:
https://github.com/auth0/passport-wsfed-saml2
and I only get nameID.
metadata.xml (my server address was replaced with http://localhost/app/, it is ran in https):
<?xml version="1.0" encoding="utf-8"?>
<EntityDescriptor ID="_5b6cd05c-a5e3-470d-a2fc-6c6f66633d1b" entityID="http://localhost/app/" xmlns="urn:oasis:names:tc:SAML:2.0:metadata">
<RoleDescriptor xsi:type="fed:ApplicationServiceType" xmlns:fed="http://docs.oasis-open.org/wsfed/federation/200706" protocolSupportEnumeration="http://docs.oasis-open.org/wsfed/federation/200706" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<fed:ClaimTypesRequested>
<auth:ClaimType Uri="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name" Optional="true" xmlns:auth="http://docs.oasis-open.org/wsfed/authorization/200706" />
<auth:ClaimType Uri="http://schemas.microsoft.com/ws/2008/06/identity/claims/role" Optional="true" xmlns:auth="http://docs.oasis-open.org/wsfed/authorization/200706" />
</fed:ClaimTypesRequested>
<fed:TargetScopes>
<EndpointReference xmlns="http://www.w3.org/2005/08/addressing">
<Address>http://localhost/app/</Address>
</EndpointReference>
</fed:TargetScopes>
<fed:PassiveRequestorEndpoint>
<EndpointReference xmlns="http://www.w3.org/2005/08/addressing">
<Address>http://localhost/app/</Address>
</EndpointReference>
</fed:PassiveRequestorEndpoint>
</RoleDescriptor>
</EntityDescriptor>
even whenever I replace "optional" to false it doesn't return any claims.
does anyone why ADFS ignores my claims?

Are you expecting ADFS to derive the claims from "ClaimTypesRequested"?
The way ADFS works is that the claims are derived from claims rules that are configured in ADFS.
What claims rules have you got configured?

Related

Configure SiteMinder as AWS Cognito userpool identityProvider using SAML2

When cognito sends the SAMLREQUEST to the IDP the request does not have all the information that the IDP is expecting.
SP is sending the following request:
<?xml version="1.0" encoding="UTF-8"?>
<saml2p:AuthnRequest AssertionConsumerServiceURL="assertionURL" Destination="destinaUrl" ID="_a4b38e68-8e69-4a5d-927b-01e16da92ca7" IssueInstant="2019-10-23T15:14:36.339Z" Version="2.0" xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol"><saml2:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">urn:blah:blah</saml2:Issuer>
</saml2p:AuthnRequest>
However through manual testing the following SAMLREQUEST works:
<?xml version="1.0" encoding="UTF-8"?>
<saml2p:AuthnRequest AssertionConsumerServiceURL="https://uat-marley.auth.us-east-1.amazoncognito.com/saml2/idpresponse" Destination="https://ssofed-qa.metlife.com/affwebservices/public/saml2sso?SPID=urn:amazon:cognito:sp:us-east-1_k4dn6EP6k" ID="_a4b38e68-8e69-4a5d-927b-01e16da92ca7" IssueInstant="2019-10-23T15:14:36.339Z" Version="2.0" xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol"><saml2:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">urn:amazon:cognito:sp:us-east-1_k4dn6EP6k</saml2:Issuer>
<saml2p:NameIDPolicy AllowCreate="true" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity"/>
</saml2p:AuthnRequest>
The only difference is this line:
<saml2p:NameIDPolicy AllowCreate="true" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity"/>
Because AWS userpools identity federation config only needs IDP metadata in order to integrate with IDPS, I'm assuming I need to tweak the metadata in order to change the SAMLREQUEST to include the NamePolicyId element.
I have been using this doc to try different elements:
http://www.datypic.com/sc/saml2/s-saml-schema-metadata-2.0.xsd.html
I've also been using this website to build metadata: https://www.samltool.com/idp_metadata.php
Also:
https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-integrating-3rd-party-saml-providers.html
Idps sample metadata:
<EntityDescriptor ID="SM172d8336f5cde29cebbfed3478bc49c5ee3f72a813a3" entityID="urn:entity:id" xmlns="urn:oasis:names:tc:SAML:2.0:metadata">
<IDPSSODescriptor WantAuthnRequestsSigned="true" ID="SM1d149b29837b56846f0e9a85ae92be6449ffd58ef1e" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<KeyDescriptor use="signing">
<KeyInfo Id="myid" xmlns:ns1="http://www.w3.org/2000/09/xmldsig#">
<X509Data>
<X509IssuerSerial>
<X509IssuerName>
issuer info
</X509IssuerName>
<X509SerialNumber>
number
</X509SerialNumber>
</X509IssuerSerial>
<X509Certificate>
some cert
</X509Certificate>
<X509SubjectName>
relevant info
</X509SubjectName>
</X509Data>
</KeyInfo>
</KeyDescriptor>
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="redirect url" />
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="post url" />
</IDPSSODescriptor>
</EntityDescriptor>
I want to know how I can tweak the idps metadata such that cognito knows to send this <saml2p:NameIDPolicy AllowCreate="true" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity"/>
in the SAMLREQUEST.
Thank you for any help in advance, I've been struggling with this for a while.

Setting up Zendesk as a remote Service Provider in OpenAm

Am trying to register Zendesk as a remote service provider in OpenAm server.
I have a problem with finding a metadata file or a url for Zendesk. Is it even needed, if so how can I fill that field.
You could construct the SAML metadata manually, something like this should work:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<EntityDescriptor entityID="myorganization.zendesk.com" xmlns="urn:oasis:names:tc:SAML:2.0:metadata">
<SPSSODescriptor AuthnRequestsSigned="false" WantAssertionsSigned="true" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</NameIDFormat>
<AssertionConsumerService index="1" Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://myorganization.zendesk.com/access/saml"/>
</SPSSODescriptor>
</EntityDescriptor>

SAML LogOutRequest processing failed on ADFS server

I have ADFS server as an IdP. I have separate SP application. These are defined in circle of trust. SSO over SAML protocol is working fine. When I try SP initated log out request I got error on ADFS side :
MSIS7000: The sign in request is not compliant to the WS-Federation language for web browser clients or the SAML 2.0 protocol WebSSO profile.
EDIT More detail message from ADFS Event Trace :
MSIS7015: This request does not contain the expected protocol message or incorrect protocol parameters were found according to the HTTP SAML protocol bindings.
I have reviewed mu log out SAML message and looks correct. Just to mention that same SP is loging out properly with ForgeRocks IdP (ex Sun OpenSSO).
Saml loout request message :
<samlp:LogoutRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
ID="b00b3f55-f3e3-4935-9e91-da6bf8b62efd"
Version="2.0"
IssueInstant="2013-08-27T09:45:08Z"
Destination="https://00.00.00.00/adfs/ls/"
Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified"
NotOnOrAfter="2013-08-27T09:50:08Z"
>
<saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">SPEntityId/</saml:Issuer>
<saml:NameID xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">jsmith#company.com</saml:NameID>
<samlp:SessionIndex>_ea853497-c58a-408a-bc23-c849752d9741</samlp:SessionIndex>
EDIT
Lan suggested to me that signing of the logout request messages is mandatory. He was right. In OASIS specification (http://docs.oasis-open.org/security/saml/v2.0/saml-profiles-2.0-os.pdf) section 4.4.3.1. it is described. According with that I am sending now signed messages but I am having the same issue.
Signed message :
<samlp:LogoutRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
ID="aed640c0-9455-49ea-9450-4ad7c08d98e7"
Version="2.0"
IssueInstant="2013-08-29T15:22:45Z"
Destination="https://server/adfs/ls/"
Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified"
NotOnOrAfter="2013-08-29T03:27:45Z"
>
<saml:NameID xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">user</saml:NameID>
<samlp:SessionIndex>_677952a2-7fb3-4e7a-b439-326366e677db</samlp:SessionIndex>
<saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">SPIssuer</saml:Issuer>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
<Reference URI="#aed640c0-9455-49ea-9450-4ad7c08d98e7">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<DigestValue>53jjPvQ2Ty1Z+VikwrUwW4Erj3k=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>signed value</SignatureValue>
<KeyInfo>
<X509Data>
<X509Certificate>certificate</X509Certificate>
</X509Data>
</KeyInfo>
</Signature>
What I am doing wrong ? Should be specified some other endpoint on ADFS ? As I got is should be used same as for sign on requests (that are working perfectly on my side).
Thanks,
Rastko
Finlay I can do SLO :)
Previously I have worked with ForgeRock's IDP and it worked perfectly, but with ADFS did not. It is obvious that Microsoft has restricted rules related with SAML message formatting. Conclusions that I have found :
LogoutRequest message MUST be signed (SAML 2.0 Profiles doc, Sect 4.4.3.1). Thank you Ian for this.
Order of the XML elements and attributes is important. On the bottom of this message is final version of my log out request.
NameId must be in the same format as one received from AuthenticationResponse. It should contains elements expected by ADFS. These links helped me : Name Identifier (Name ID) claim in the SAML subject and SAML LogoutRequest
LogoutRequest signature must me transformed with XmlDsigExcC14NTransform, that should be added after XmlDsigEnvelopedSignatureTransform
Canonization method for signing should be http://www.w3.org/2001/10/xml-exc-c14n#
Issuer, NameID and SessionIndex are mandatory XML elements
Namespaces are mandatory : xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" and xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
Final LogoutRequest message that is working :
<samlp:LogoutRequest ID="f8a62847-92f2-4f0c-936a-df9efe0cc42f"
Version="2.0"
IssueInstant="2013-08-29T20:53:50Z"
Destination="https://server/adfs/ls/"
Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified"
xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
>
<saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">https://sp.com/</saml:Issuer>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
<Reference URI="#f8a62847-92f2-4f0c-936a-df9efe0cc42f">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<DigestValue>W7F1E2U1OAHRXn/ItbnsYZyXw/8=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue></SignatureValue>
<KeyInfo>
<X509Data>
<X509Certificate></X509Certificate>
</X509Data>
</KeyInfo>
</Signature>
<saml:NameID xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
Format="http://schemas.xmlsoap.org/claims/UPN"
>user</saml:NameID>
<samlp:SessionIndex>_2537f94b-a150-415e-9a45-3c6fa2b6dd60</samlp:SessionIndex>
IIRC SAML 2.0 SP-Initiated SLO requires the use of Digital Signatures on the LogoutRequest? This ensures that no one spoofs the LogoutRequest and logs a user out of all their existing sessions.
Assuming you are using the POST binding and not Redirect since I can't see the Signature in the XML. With Redirect the Signature info is passed as a query parameter.

Add User and Pass to SOAP Header in Mule

It seems this should be simple but the solution has been eluding me. My flow is XML -> XSLT translation -> consume web service (IBM Web Sphere Web Service to be specific). I have the pieces working individually but I am having trouble figuring out how to add user/pass to the SOAP header. I would think that I should be able to add them to the keys in the security tab on the Mule SOAP Component (I have the operation set to Proxy Client). Unfortunately, I cannot figure out what the valid keys are. Maybe I am way off base even attempting to use the security tab. So ultimately I need my outgoing XML to contain:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<soapenv:Header>
<wsse:Security soapenv:mustUnderstand="1">
<wsse:UsernameToken>
<wsse:Username>
myUserName
</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">
myPa33W0rd
</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
Currently my Mule flow is putting out:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
Do I need to add the security information manually (maybe in the XSLT translation)? That doesn't feel right but I can't figure out how to add it.
Here are the relevant lines from my flow:
<mulexml:xslt-transformer maxIdleTransformers="2" maxActiveTransformers="5" xsl-file="src\main\resources\MappingMapToChangeCatalogEntry.xslt" outputEncoding="US-ASCII" doc:name="XSLT"/>
<cxf:proxy-client payload="body" enableMuleSoapHeaders="true" doc:name="SOAP"/>
<byte-array-to-string-transformer doc:name="Byte Array to String"/>
In order to add WS-Sec you need to configure the CXF WSS4J interceptors and inject them into Mule's CXF message processors.
Pre 3.3 =
<spring:bean name="wss4jOutConfiguration"
class="org.springframework.beans.factory.config.MapFactoryBean">
<spring:property name="sourceMap">
<spring:map>
<spring:entry key="action" value="Signature" />
<spring:entry key="user" value="joe" />
<spring:entry key="signaturePropFile" value="org/mule/module/cxf/wssec/wssecurity.properties" />
<spring:entry key="passwordCallbackClass" value="org.mule.module.cxf.wssec.ClientPasswordCallback" />
</spring:map>
</spring:property>
</spring:bean>
...
<cxf:proxy-client payload="body" enableMuleSoapHeaders="true" doc:name="SOAP">
<cxf:outInterceptors>
<spring:bean class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
<spring:property name="properties" ref="wss4jOutConfiguration"/>
</spring:bean>
</cxf:outInterceptors>
</cxf:proxy-client>
Rough Sample Password Callback class:
public class ClientPasswordCallback implements CallbackHandler{
#Override
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
WSPasswordCallback callback = (WSPasswordCallback) callbacks[0];
if(callback.getIdentifier().equals("joe")){
callback.setPassword("pass");
}
}
See more here: http://www.mulesoft.org/documentation/display/current/WS-Security+Usability+Improvement
3.3.+ :
There is a new cxf:ws-security element availble in 3.3+ Here is an example flow here: https://svn.codehaus.org/mule/tags/mule-3.4-M2/modules/cxf/src/test/resources/org/mule/module/cxf/wssec/cxf-secure-proxy-flow.xml
<cxf:proxy-client payload="body"
enableMuleSoapHeaders="true" doc:name="SOAP">
<cxf:ws-security>
<cxf:ws-config>
<cxf:property key="action"
value="UsernameToken
Timestamp" />
<cxf:property key="user" value="joe" />
<cxf:property key="passwordCallbackClass"
value="com.mulesoft.mule.example.security.PasswordCallback" />
<cxf:property key="mustUnderstand" value="false" />
</cxf:ws-config>
</cxf:ws-security>
</cxf:proxy-client>
Previously I have also just handled he entire envelope myself when using XSLT. I have then passed the user and pass into the XSLT via context params
<xm:xslt-transformer xsl-file="xslt/ToSomethingSOAPY.xsl">
<xm:context-property key="user" value="${my.user}" />
<xm:context-property key="password" value="${my.pass}" />
</xm:xslt-transformer>
And then reieived them via xsl params like so:
<xsl:param name="user" />
....
<wsse:UsernameToken
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
wsu:Id="UsernameToken-1018444980">
<wsse:Username><xsl:value-of select="$user" /></wsse:Username>

How can I set the Secure flag on an ASP.NET Session Cookie?

How can I set the Secure flag on an ASP.NET Session Cookie, so that it will only be transmitted over HTTPS and never over plain HTTP?
In the <system.web> element, add the following element:
<httpCookies requireSSL="true" />
However, if you have a <forms> element in your system.web\authentication block, then this will override the setting in httpCookies, setting it back to the default false.
In that case, you need to add the requireSSL="true" attribute to the forms element as well.
So you will end up with:
<system.web>
<authentication mode="Forms">
<forms requireSSL="true">
<!-- forms content -->
</forms>
</authentication>
</system.web>
See here and here for MSDN documentation of these elements.
There are two ways, one httpCookies element in web.config allows you to turn on requireSSL which only transmit all cookies including session in SSL only and also inside forms authentication, but if you turn on SSL on httpcookies you must also turn it on inside forms configuration too.
Edit for clarity:
Put this in <system.web>
<httpCookies requireSSL="true" />
Things get messy quickly if you are talking about checked-in code in an enterprise environment. We've found that the best approach is to have the web.Release.config contain the following:
<system.web>
<compilation xdt:Transform="RemoveAttributes(debug)" />
<authentication>
<forms xdt:Transform="Replace" timeout="20" requireSSL="true" />
</authentication>
</system.web>
That way, developers are not affected (running in Debug), and only servers that get Release builds are requiring cookies to be SSL.
Building upon #Mark D's answer I would use web.config transforms to set all the various cookies to Secure. This includes setting anonymousIdentification cookieRequireSSL and httpCookies requireSSL.
To that end you'd setup your web.Release.config as:
<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<system.web>
<httpCookies xdt:Transform="SetAttributes(httpOnlyCookies)" httpOnlyCookies="true" />
<httpCookies xdt:Transform="SetAttributes(requireSSL)" requireSSL="true" />
<anonymousIdentification xdt:Transform="SetAttributes(cookieRequireSSL)" cookieRequireSSL="true" />
</system.web>
</configuration>
If you're using Roles and Forms Authentication with the ASP.NET Membership Provider (I know, it's ancient) you'll also want to set the roleManager cookieRequireSSL and the forms requireSSL attributes as secure too. If so, your web.release.config might look like this (included above plus new tags for membership API):
<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<system.web>
<httpCookies xdt:Transform="SetAttributes(httpOnlyCookies)" httpOnlyCookies="true" />
<httpCookies xdt:Transform="SetAttributes(requireSSL)" requireSSL="true" />
<anonymousIdentification xdt:Transform="SetAttributes(cookieRequireSSL)" cookieRequireSSL="true" />
<roleManager xdt:Transform="SetAttributes(cookieRequireSSL)" cookieRequireSSL="true" />
<authentication>
<forms xdt:Transform="SetAttributes(requireSSL)" requireSSL="true" />
</authentication>
</system.web>
</configuration>
Background on web.config transforms here: http://go.microsoft.com/fwlink/?LinkId=125889
Obviously this goes beyond the original question of the OP but if you don't set them all to secure you can expect that a security scanning tool will notice and you'll see red flags appear on the report. Ask me how I know. :)
secure - This attribute tells the browser to only send the cookie if the request is being sent over a secure channel such as HTTPS. This will help protect the cookie from being passed over unencrypted requests. If the application can be accessed over both HTTP and HTTPS, then there is the potential that the cookie can be sent in clear text.