Hi there
I downloaded WSO2 IS version 5.9.0. I configured an external IDP as
suggested here
https://is.docs.wso2.com/en/5.9.0/learn/adding-and-configuring-an-identity-provider/
and then I configured the claims and a Service Provider where I want to use
SAML2 SSO.
I configured my Service Provider in order to use and advanced configuration
for the login process where step one is basic authentication and step 2 is
done by using my external IdP.
The same identical configuration works pretty good in my WSO2 5.8.0 while
I'm facing a lot of issues in WSO2 IS 5.9.0.
In 5.9.0 version, when I try to log to my application, WSO2 shows to me the
login interface but when I click the login by external IdP the popup is
empty as showed in this image Federated Authentication
Moreover I noticed that when I try so modify the
application-authentication.xml located in
${WSO2_IS_HOME}/repository/conf/identity my modifications are lost and the
file returns to the default state. I tried to insert modification in the
deployment.toml but I can't figure how to configure correctly the SAMLSSO.
Then I tried to configure my Service Provider only by showing the external
login interface. I get an error. The stack trace is the following:
TID: [-1234] [] [2019-10-14 19:34:50,523]
> [a7721bfd-6c47-48f2-b31d-d30a0fbb7e06] DEBUG
> {org.wso2.carbon.identity.application.authenticator.samlsso.manager.DefaultSAML2SSOManager}
> - SAML Request : <?xml version="1.0" encoding="UTF-8"?>
> <samlp:AuthnRequest AssertionConsumerServiceURL="
> https://localhost:9443/commonauth" AttributeConsumingServiceIndex="0"
> Destination="http://localhost:8088/sso" ForceAuthn="true"
> ID="_84b2f91a208bc6b3ee12383e2cf26652"
> IssueInstant="2019-10-14T17:34:50.505Z"
> ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
> Version="2.0"
> xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"><samlp:Issuer
> Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity" NameQualifier="
> http://wso2_590_ai" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:assertion">
> http://wso2_590_ai</samlp:Issuer><saml2p:NameIDPolicy
> Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"
> xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol"/><saml2p:RequestedAuthnContext
> Comparison="exact"
> xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol"><saml2:AuthnContextClassRef
> xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">
> https://www.spid.gov.it/SpidL2
> </saml2:AuthnContextClassRef></saml2p:RequestedAuthnContext></samlp:AuthnRequest>
> TID: [-1234] [] [2019-10-14 19:34:50,524]
> [a7721bfd-6c47-48f2-b31d-d30a0fbb7e06] DEBUG
> {org.wso2.carbon.identity.application.authenticator.samlsso.manager.DefaultSAML2SSOManager}
> - Parameter Map {} tenantDomain carbon.super
> TID: [-1234] [] [2019-10-14 19:34:50,524]
> [a7721bfd-6c47-48f2-b31d-d30a0fbb7e06] DEBUG
> {org.wso2.carbon.identity.application.authenticator.samlsso.manager.X509CredentialImpl}
> - tenantID -1234
> TID: [-1234] [] [2019-10-14 19:34:50,525]
> [a7721bfd-6c47-48f2-b31d-d30a0fbb7e06] ERROR
> {org.wso2.carbon.identity.application.authentication.framework.handler.request.impl.DefaultRequestCoordinator}
> - Exception in Authentication Framework java.util.EmptyStackException
> at java.util.Stack.peek(Stack.java:102)
> at java.util.Stack.pop(Stack.java:84)
> at
> org.wso2.carbon.context.internal.CarbonContextDataHolder.endTenantFlow(CarbonContextDataHolder.java:1295)
> at
> org.wso2.carbon.context.PrivilegedCarbonContext.endTenantFlow(PrivilegedCarbonContext.java:75)
> at
> org.wso2.carbon.identity.application.authentication.framework.util.FrameworkUtils.endTenantFlow(FrameworkUtils.java:1505)
> at
> org.wso2.carbon.identity.application.authenticator.samlsso.manager.X509CredentialImpl.<init>(X509CredentialImpl.java:202)
> at
> org.wso2.carbon.identity.application.authenticator.samlsso.manager.DefaultSAML2SSOManager.buildRequest(DefaultSAML2SSOManager.java:267)
> at
> org.wso2.carbon.identity.application.authenticator.samlsso.SAMLSSOAuthenticator.initiateAuthenticationRequest(SAMLSSOAuthenticator.java:123)
> at
> org.wso2.carbon.identity.application.authentication.framework.AbstractApplicationAuthenticator.process(AbstractApplicationAuthenticator.java:71)
> at
> org.wso2.carbon.identity.application.authentication.framework.handler.step.impl.DefaultStepHandler.doAuthentication(DefaultStepHandler.java:502)
> at
> org.wso2.carbon.identity.application.authentication.framework.handler.step.impl.DefaultStepHandler.handle(DefaultStepHandler.java:267)
> at
> org.wso2.carbon.identity.application.authentication.framework.handler.sequence.impl.DefaultStepBasedSequenceHandler.handle(DefaultStepBasedSequenceHandler.java:185)
> at
> org.wso2.carbon.identity.application.authentication.framework.handler.sequence.impl.GraphBasedSequenceHandler.handle(GraphBasedSequenceHandler.java:111)
> at
> org.wso2.carbon.identity.application.authentication.framework.handler.request.impl.DefaultAuthenticationRequestHandler.handle(DefaultAuthenticationRequestHandler.java:155)
> at
> org.wso2.carbon.identity.application.authentication.framework.handler.request.impl.DefaultRequestCoordinator.handle(DefaultRequestCoordinator.java:239)
> at
> org.wso2.carbon.identity.application.authentication.framework.CommonAuthenticationHandler.doPost(CommonAuthenticationHandler.java:46)
> at
> org.wso2.carbon.identity.application.authentication.framework.CommonAuthenticationHandler.doGet(CommonAuthenticationHandler.java:37)
> at
> org.wso2.carbon.identity.sso.saml.servlet.SAMLSSOProviderServlet.sendRequestToFramework(SAMLSSOProviderServlet.java:1592)
> at
> org.wso2.carbon.identity.sso.saml.servlet.SAMLSSOProviderServlet.sendToFrameworkForAuthentication(SAMLSSOProviderServlet.java:827)
> at
> org.wso2.carbon.identity.sso.saml.servlet.SAMLSSOProviderServlet.handleSPInitSSO(SAMLSSOProviderServlet.java:719)
> at
> org.wso2.carbon.identity.sso.saml.servlet.SAMLSSOProviderServlet.handleRequest(SAMLSSOProviderServlet.java:270)
> at
> org.wso2.carbon.identity.sso.saml.servlet.SAMLSSOProviderServlet.doPost(SAMLSSOProviderServlet.java:156)
> at javax.servlet.http.HttpServlet.service(HttpServlet.java:660)
> at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
> at
> org.eclipse.equinox.http.helper.ContextPathServletAdaptor.service(ContextPathServletAdaptor.java:37)
> at
> org.eclipse.equinox.http.servlet.internal.ServletRegistration.service(ServletRegistration.java:61)
> at
> org.eclipse.equinox.http.servlet.internal.ProxyServlet.processAlias(ProxyServlet.java:128)
> at
> org.eclipse.equinox.http.servlet.internal.ProxyServlet.service(ProxyServlet.java:60)
> at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
> at
> org.wso2.carbon.tomcat.ext.servlet.DelegationServlet.service(DelegationServlet.java:68)
> at
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
> at
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
> at
> org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
> at
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
> at
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
> at
> org.wso2.carbon.identity.captcha.filter.CaptchaFilter.doFilter(CaptchaFilter.java:66)
> at
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
> at
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
> at
> org.owasp.csrfguard.CsrfGuardFilter.doFilter(CsrfGuardFilter.java:72)
> at
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
> at
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
> at
> org.apache.catalina.filters.HttpHeaderSecurityFilter.doFilter(HttpHeaderSecurityFilter.java:126)
> at
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
> at
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
> at
> org.wso2.carbon.tomcat.ext.filter.CharacterSetFilter.doFilter(CharacterSetFilter.java:65)
> at
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
> at
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
> at
> org.apache.catalina.filters.HttpHeaderSecurityFilter.doFilter(HttpHeaderSecurityFilter.java:126)
> at
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
> at
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
> at
> org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
> at
> org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
> at
> org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)
> at
> org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
> at
> org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
> at
> org.wso2.carbon.identity.context.rewrite.valve.TenantContextRewriteValve.invoke(TenantContextRewriteValve.java:80)
> at
> org.wso2.carbon.identity.authz.valve.AuthorizationValve.invoke(AuthorizationValve.java:100)
> at
> org.wso2.carbon.identity.auth.valve.AuthenticationValve.invoke(AuthenticationValve.java:74)
> at
> org.wso2.carbon.tomcat.ext.valves.CompositeValve.continueInvocation(CompositeValve.java:99)
> at
> org.wso2.carbon.tomcat.ext.valves.TomcatValveContainer.invokeValves(TomcatValveContainer.java:49)
> at
> org.wso2.carbon.tomcat.ext.valves.CompositeValve.invoke(CompositeValve.java:62)
> at
> org.wso2.carbon.tomcat.ext.valves.CarbonStuckThreadDetectionValve.invoke(CarbonStuckThreadDetectionValve.java:146)
> at
> org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:678)
> at
> org.wso2.carbon.tomcat.ext.valves.CarbonContextCreatorValve.invoke(CarbonContextCreatorValve.java:57)
> at
> org.wso2.carbon.tomcat.ext.valves.RequestCorrelationIdValve.invoke(RequestCorrelationIdValve.java:116)
> at
> org.wso2.carbon.tomcat.ext.valves.RequestEncodingValve.invoke(RequestEncodingValve.java:49)
> at
> org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
> at
> org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
> at
> org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
> at
> org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
> at
> org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:853)
> at
> org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1587)
> at
> org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
> at
> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
> at
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
> at
> org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
> at java.lang.Thread.run(Thread.java:748)
By debugging it seems that in the class
org.wso2.carbon.context.internal.CarbonContextDataHolder in the method
endTenantFlow() we try to pop from an empty stack as you can see in this
code:
public void endTenantFlow() {
> Stack<CarbonContextDataHolder> carbonContextDataHolders =
> parentContextHolderStack.get();
> if (carbonContextDataHolders != null) {
> currentContextHolder.set(carbonContextDataHolders.pop());
> }
> }
This code is taken from jar org.wso2.carbon.utils-4.5.1.jar
So I focused my attention on the
org.wso2.carbon.identity.application.authenticator.samlsso project and I
found a possibile bug in the class
org.wso2.carbon.identity.application.authenticator.samlsso.manager.X509CredentialImpl
Basically in the constructor there is this piece of code:
try {
> /**
> * Get the private key and the cert for the respective tenant domain.
> */
> if
> (!tenantDomain.equals(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME)) {
> FrameworkUtils.startTenantFlow(tenantDomain);
> //Do some stuffs
> } else {
> //Do other stuffs
> }
> } catch (Exception e) {
> //Handle exception
> } finally {
> FrameworkUtils.endTenantFlow();
> }
As you can see the FrameworkUtils.startTenantFlow(tenantDomain); is called
only if the first if is true. This means that in the finally we have to
handle the endTenantFlow() properly. I modified the code in this way:
try {
> /**
> * Get the private key and the cert for the respective tenant domain.
> */
> if
> (!tenantDomain.equals(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME)) {
> FrameworkUtils.startTenantFlow(tenantDomain);
> //Do some stuffs
> } else {
> //Do other stuffs
> }
> } catch (Exception e) {
> //Handle exception
> } finally {
> if
> (!tenantDomain.equals(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME)) {
> if (log.isDebugEnabled()) {
> log.debug("finalizzo il tenant flow per tenant domain " +
> tenantDomain);
> }
> FrameworkUtils.endTenantFlow();
> } else {
> if (log.isDebugEnabled()) {
> log.debug("Tenant domain " + tenantDomain + " nessun flow da
> finalizzare");
> }
> }
> }
It seems to work now but I don't know if my modification is correct...
I hope this can be useful
Angelo
_______________________________________________
Dev mailing list
[email protected]
http://wso2.org/cgi-bin/mailman/listinfo/dev