Closed emidiotorre closed 4 years ago
Hi @emidiotorre I can help you with this.
I don't know yet if this is a bug on our end or not, but the exception is being caused because FusionAuth is expecting a NameIDPolicy
in the SAML request and it was not provided.
Taking a brief look at the Auth0 SAML docs... I see a few things regarding the name Id.
nameIdentifierFormat (string): Default is urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified.
https://auth0.com/docs/protocols/saml/saml-configuration/saml-assertions
That default value is correct, it is the default value for the the <NameIDPolicy>
.
http://docs.oasis-open.org/security/saml/v2.0/saml-core-2.0-os.pdf
Do you know if it is possible to get this policy in the SAML request from Auth0?
Thank you for the prompt response @robotdan !
I am trying to fix this with the help of the service provider, I don't think i have any settings available to bypass this check, right?
Probably it is not a bug, but it would be nice to handle the exeption with a clear error message, i saw other people opening issues for similar problems.
Again, thanks.
No way to bypass it on our end. Let us know what you find out, it is possible we need to be tolerant of this value missing in the request.
@emidiotorre were you able to get this working with changes to the SAML SP? Let us know if we can be of assistance.
No, it still doesnt work. they say that i need to define this "claims" correctly: "email" = "email" "given_name" = "given_name" "family_name" = "family_name"
as far as i know this values are already mapped correctly, the information about the user are already encoded this way when i check them on my application.
Do I have to define this mappings somewhere? Or could it be the fact that i'm accessing the IDP with a hostname, while the SP is redirecting the user on the ip directly?? Change any settings like the issuer, the audience maybe?? Could I do anything useful with a Lambda function, btw what are reconciliation lambdas used for?
Thank you for the help
Thanks for the update @emidiotorre .
To clarify, are you configuring FusionAuth as a SAML Identity Provider, or the SAML v2 Service Provider? In other words, do you have FusionAuth users logging into a 3rd party SAML v2 IdP such as Auth0, or is your your third party IdP trying to log into FusionAuth using SAML v2?
My initial assumption was you're configuring FusionAuth as the service provider, but perhaps I'm mistaken.
So the initial exception we saw was because the SAML response did not contain the Name Id Policy - or at least that is what I believe is occurring based upon the exception we observed.
they say that i need to define this "claims" correctly: "email" = "email" "given_name" = "given_name" "family_name" = "family_name"
So, if we are speaking about FusionAuth being the SAML v2 service provider (configuring SAML v2 through the Identity Providers Settings --> Identity Providers) - will look for some standard claims from the SAML IdP.
We attempt to find the given_name
and family_name
as follows:
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname
and fall back to first_name
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname
and fall back to last_name
After we try both of those, it is possible these values are still null in our User data model, we next call a lambda if defined.
The reconciliation lambda is used when FusionAuth is the SAML v2 service provider and it allows FusionAuth to map any claim returned by the SAML v2 IdP to the FusionAuth user. The lambda will be provided the user, and SAML response object. The lambda can then optionally be used to extract additional values from the SAML response. For example if the first name is provided as given_name
in the SAML response you can use a lambda to grab that value.
A rough example would be :
function reconcile(user, registration, samlResponse) {
// set firstName using the 'given_name' claim in the SAML response
user.firstName = samlResponse.assertion.attributes.given_name;
}
If we're talking about the SAML v2 IdP configuration - which is found in the Application configuration, then we'd be talking about the Populate Lambda which is used ensure the SAML response we send back to a service provided initiated login request contains the expected claims.
We are currently sending a response to the SAML v2 service provider that contains the following claims (not exhaustive, but these are the relevant claims based upon the ones you mentioned)
FA property Claim
--------------------------------------------
email email
firstName http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname
first_name
fullName http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name
name
full_name
lastName http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname
last_name
So if this is the problem area, then perhaps all we need to do is create a populate lambda and add the given_name
and family_name
claims to the response.
An example SAML v2 Populate lambda would be something like:
function populate(samlResponse, user, registration) {
samlResponse.assertion.attributes['given_name'] = user.firstName;
samlResponse.assertion.attributes['family_name'] = user.lastName;
}
This example lambda would add given_name
and family_name
claims to the SAML response.
Let me know which side of SAML you're trying to get working and we can go from there.
I'm using Fusionauth as the IdP, so I tried using a lambda like the last one you provided me, but I'm still getting the same error..
Have you enabled debug on the SAML config? If so, there may be some event logs available.
System --> Event Log
Are there any errors in the log?
yes, debug is enabled, but no logs
Ok. SAML can be a pita and is very complex. This all makes it difficult to debug.
If you'd like to join the FusionAuth Slack channel and DM me to share some config perhaps I can recreate the issue to see if it is something we can do differently or if it is a configuration issue with the service provider.
Yes it would be nice, but I think I do need an invitation right?
Nope, just need to request access. Find the "chat with users" link on https://fusionauth.io/
@emidiotorre any update on this, anything we can help with?
Working with @emidiotorre offline, captured the SAML Authn request.
<samlp:AuthnRequest
xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
Destination="http://fusionauth:9011/samlv2/login/117c46d7-42a3-57df-3410-50c69d555f2b"
ID="_f6d582e90210d1354e45b4c374002e2e"
IssueInstant="2019-07-10T23:25:07Z"
ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
Version="2.0">
<saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
urn:[REMOVED]
</saml:Issuer>
</samlp:AuthnRequest>
This is missing the NameIdPolicy
Here is an example NameIdPolicy
attribute.
<samlp:NameIDPolicy Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" AllowCreate="true"/>
Need to identify if this is a required attribute in the Authn request, and the SP should be sending it, or if FusionAuth needs to be able to handle a request such as this one.
@emidiotorre were you able to get this issue resolved?
Nope, we sadly moved back to the old auth system, hope to get it working in the near future!
Bummer, thanks for the update. Closing this out for now.
Another user ran into this as well and pointed out that this is optional according to the SAML spec.
\<NameIDPolicy> [Optional] Specifies constraints on the name identifier to be used to represent the requested subject. If omitted, then any type of identifier supported by the identity provider for the requested subject can be used, constrained by any relevant deployment-specific policies, with respect to privacy, for example.
http://docs.oasis-open.org/security/saml/v2.0/saml-core-2.0-os.pdf
We'll review, perhaps we can just default to email if this is omitted from the request.
Facing the same issue here due to missing NameIDPolicy as part of the AuthnRequest from Service Provider (Medallia). Here is the sample request from the service provider and the logs causing the 500 error :
I think this has been resolved, if anyone is still seeing this issue please re-open.
I am getting a 500 Error page when logging in from an auth0 service provider
Just to give a little bit of a context, i need my users to be able to move from app A (owned by me) to B (an external service) without any hassle, B is using SAML on auth0.com so we configured it. Now when from A i click on a link to B it prompts me a login page, and then redirects me to my fusionauth installation, which after a while gives me a 500 error page.
I have no clue how to fix this.
This is what fusionauth is logging:
Jun 18, 2019 12:14:36.812 PM ERROR io.fusionauth.app.primeframework.error.ExceptionExceptionHandler - An unhandled exception was thrown java.lang.NullPointerException: null at io.fusionauth.samlv2.service.DefaultSAMLv2Service.parseRequest(DefaultSAMLv2Service.java:428) ~[fusionauth-samlv2-0.2.0.jar:0.2.0] at io.fusionauth.app.action.samlv2.LoginAction.get(LoginAction.java:92) ~[fusionauth-app-1.6.1.jar:1.6.1] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_171] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_171] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_171] at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_171] at org.primeframework.mvc.util.ReflectionUtils.invoke(ReflectionUtils.java:436) ~[prime-mvc-1.13.3.jar:1.13.3] at org.primeframework.mvc.action.DefaultActionInvocationWorkflow.execute(DefaultActionInvocationWorkflow.java:84) ~[prime-mvc-1.13.3.jar:1.13.3] at org.primeframework.mvc.action.DefaultActionInvocationWorkflow.perform(DefaultActionInvocationWorkflow.java:64) ~[prime-mvc-1.13.3.jar:1.13.3] at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:43) ~[prime-mvc-1.13.3.jar:1.13.3] at org.primeframework.mvc.validation.DefaultValidationWorkflow.perform(DefaultValidationWorkflow.java:47) ~[prime-mvc-1.13.3.jar:1.13.3] at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:43) ~[prime-mvc-1.13.3.jar:1.13.3] at org.primeframework.mvc.security.DefaultSecurityWorkflow.perform(DefaultSecurityWorkflow.java:60) ~[prime-mvc-1.13.3.jar:1.13.3] at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:43) ~[prime-mvc-1.13.3.jar:1.13.3] at org.primeframework.mvc.parameter.DefaultPostParameterWorkflow.perform(DefaultPostParameterWorkflow.java:50) ~[prime-mvc-1.13.3.jar:1.13.3] at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:43) ~[prime-mvc-1.13.3.jar:1.13.3] at org.primeframework.mvc.content.DefaultContentWorkflow.perform(DefaultContentWorkflow.java:52) ~[prime-mvc-1.13.3.jar:1.13.3] at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:43) ~[prime-mvc-1.13.3.jar:1.13.3] at org.primeframework.mvc.parameter.DefaultParameterWorkflow.perform(DefaultParameterWorkflow.java:57) ~[prime-mvc-1.13.3.jar:1.13.3] at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:43) ~[prime-mvc-1.13.3.jar:1.13.3] at org.primeframework.mvc.parameter.DefaultURIParameterWorkflow.perform(DefaultURIParameterWorkflow.java:102) ~[prime-mvc-1.13.3.jar:1.13.3] at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:43) ~[prime-mvc-1.13.3.jar:1.13.3] at org.primeframework.mvc.scope.DefaultScopeRetrievalWorkflow.perform(DefaultScopeRetrievalWorkflow.java:58) ~[prime-mvc-1.13.3.jar:1.13.3] at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:43) ~[prime-mvc-1.13.3.jar:1.13.3] at org.primeframework.mvc.message.DefaultMessageWorkflow.perform(DefaultMessageWorkflow.java:45) ~[prime-mvc-1.13.3.jar:1.13.3] at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:43) ~[prime-mvc-1.13.3.jar:1.13.3] at org.primeframework.mvc.action.DefaultActionMappingWorkflow.perform(DefaultActionMappingWorkflow.java:126) ~[prime-mvc-1.13.3.jar:1.13.3] at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:43) ~[prime-mvc-1.13.3.jar:1.13.3] at org.primeframework.mvc.workflow.StaticResourceWorkflow.perform(StaticResourceWorkflow.java:97) ~[prime-mvc-1.13.3.jar:1.13.3] at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:43) ~[prime-mvc-1.13.3.jar:1.13.3] at org.primeframework.mvc.parameter.RequestBodyWorkflow.perform(RequestBodyWorkflow.java:89) ~[prime-mvc-1.13.3.jar:1.13.3] at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:43) ~[prime-mvc-1.13.3.jar:1.13.3] at org.primeframework.mvc.security.DefaultSavedRequestWorkflow.perform(DefaultSavedRequestWorkflow.java:57) ~[prime-mvc-1.13.3.jar:1.13.3] at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:43) ~[prime-mvc-1.13.3.jar:1.13.3] at org.primeframework.mvc.workflow.DefaultMVCWorkflow.perform(DefaultMVCWorkflow.java:91) ~[prime-mvc-1.13.3.jar:1.13.3] at org.primeframework.mvc.workflow.DefaultWorkflowChain.continueWorkflow(DefaultWorkflowChain.java:44) [prime-mvc-1.13.3.jar:1.13.3] at org.primeframework.mvc.servlet.FilterWorkflowChain.continueWorkflow(FilterWorkflowChain.java:50) [prime-mvc-1.13.3.jar:1.13.3] at org.primeframework.mvc.servlet.PrimeFilter.doFilter(PrimeFilter.java:84) [prime-mvc-1.13.3.jar:1.13.3] at com.inversoft.maintenance.servlet.MaintenanceModePrimeFilter.doFilter(MaintenanceModePrimeFilter.java:59) [inversoft-maintenance-mode-0.12.8.jar:0.12.8] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [catalina.jar:8.5.31] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [catalina.jar:8.5.31] at com.inversoft.servlet.UTF8Filter.doFilter(UTF8Filter.java:27) [inversoft-servlet-0.1.1.jar:0.1.1] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [catalina.jar:8.5.31] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [catalina.jar:8.5.31] at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) [catalina.jar:8.5.31] at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [catalina.jar:8.5.31] at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:496) [catalina.jar:8.5.31] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [catalina.jar:8.5.31] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) [catalina.jar:8.5.31] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [catalina.jar:8.5.31] at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) [catalina.jar:8.5.31] at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803) [tomcat-coyote.jar:8.5.31] at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-coyote.jar:8.5.31] at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790) [tomcat-coyote.jar:8.5.31] at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1468) [tomcat-coyote.jar:8.5.31] at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-coyote.jar:8.5.31] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_171] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_171] at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-util.jar:8.5.31] at java.lang.Thread.run(Thread.java:748) [na:1.8.0_171]
It would be great to just have a hint on where to move from here. Thanks.