Community Tip - When posting, your subject should be specific and summarize your question. Here are some additional tips on asking a great question. X
Version: Windchill 12.0
Use Case: I have a slightly advanced setup of a reverse proxy handling SSL https and the external facing hostname for users and the internal PTC Apache server configured with HTTP and a virtual hostname known only on that server (not in DNS) . The shibboleth metadata file that was generated exposes that internal virtual hostname and my IDP requires reply and login urls to be https. Where did I good this?
Description:
@jbailey you might know this off the top of your head.
For discussions sake, say my system DNS addressable host is pdmlink-test.mycompany.com and the internal name is pdm12.mycompany.com. I've installed shibboleth to my windchill server, configured it, defined an entityID that is "https://pdmlink-test.my company.com/shibboleth" and it is talking to my IDP. We got an error from the IDP when login was redirected that the replyURL did not match. Checking the metadata file, all the location attributes are showing "http://pdm12.mycompany.com/Shibboleth.sso/..." yada yada. Am I correct is saying that this should have said https://pdmlink-test.mycompany.com...?
Did Shibboleth need to be configured on my reverse proxy webserver? I have that module installed on my PTC Apache server which is behind the proxy.
Solved! Go to Solution.
I justed wanted to return to this thread and close it out thought I still have a few more loose ends to wrap up. Thank you so much to @jbailey for all your help. We actually took this offline to keep thread smaller. Here is a summary of what I learned:
Your IdP shouldn't need to know (or expose) anything for the local host. entityID is just a string that matches the IdP.
"Checking the metadata file, all the location attributes are showing "http://pdm12.mycompany.com/Shibboleth.sso/..." yada yada. Am I correct is saying that this should have said https://pdmlink-test.mycompany.com...?"
Shibboleth shouldn't be installed at the proxy level- because then you would have to configure Windchill Apache to accept the username in the header from the proxy which could be impersonated (PTC recommends against this method anyway).
If your IdP is configured with FQDN's instead of relative paths for the Assertion Consumer Service URL's, make sure they are for the proxy FQDN, not the internal host name. Ideally you could just use relative URL's
Also, I would consider end to end HTTPS. Yes, it is another cert and probably a little bit of a performance hit in transactions, but you will end up more secure.
Agreed on more secure but this setup makes cloning and other things easier. Recommended by consultants. We've also changed company names so many darn times, its nice to be able to change it in a few locations (on the proxy and some xconf file).
Here is some testing of configurations info. My IDP has return URL as "https://pdmlink-test.mycompany.com..." pattern. With the configuration below:
<Sessions lifetime="28800" timeout="3600" relayState="ss:mem"
checkAddress="false" handlerSSL="false" cookieProps="https"
redirectLimit="exact" >
yields a urlMismatchError from the IDP since it was being given "http://pdm12.mycompany.com..." as the URL. I can confirm that the metadata file indeed does show pdm12 as hostname and I can download it using https://pdmlink-test.mycompany.com/Shibboleth.sso/Metadata
In an attempt to fix this I modified the above configuration to the following:
<Sessions lifetime="28800" timeout="3600" relayState="ss:mem"
checkAddress="false" handlerSSL="false" cookieProps="https"
redirectLimit="exact" handlerURL="https://pdmlink-test.mycompany.com/Shibboleth.sso">
Now my IDP redirects me to https://pdmlink-test.mycompany.com/Shibboleth.sso/SAML2/POST but I now get a 404 error. It seems that the IDP liked what it got but something went wrong between the proxy and the main webserver. I can see in the webserver access log the 404 message. Getting closer. Any clue where to look next? I think it might be the Shibboleth module configuration on the Windchill webserver.
Download the SAML Tracer extension for Chrome or Edge and redo the auth attempt from a clean session with SAML tracer open. It will help you figure out what isn't liked (if it is SP side or IdP side).
Is the proxy new for you? (just going through my proxy notes, not assuming you missed any of this 🙂
Did you set wt.server.codebase="$(wt.webserver.protocol)://<PROXY FQDN>:$(wt.webserver.port)/$(wt.webapp.name)" -t codebase/wt.properties -p ?
Something else you might try in your proxy conf file is to add ProxyPass and ProxyPassReverse for the SSO related paths ( I don't know if this is necessary or not but you could do it to force to the right local address)
No proxy is not new. I've been running it for years. Here is my proxy config:
# Windchill Reverse Proxy Additions and Settings
RewriteEngine on
SSLProxyEngine on
ProxyPass /Windchill/ http://pdm12.mycompany.com:8888/Windchill/
ProxyPassReverse /Windchill/ http://pdm12.mycompany.com:8888/Windchill/
ProxyPass /Windchill-WHC http://pdm12.mycompany.com:8888/Windchill-WHC
ProxyPassReverse /Windchill-WHC http://pdm12.mycompany.com:8888/Windchill-WHC
ProxyPass /Windchill-WHC/ http://pdm12.mycompany.com:8888/Windchill-WHC/
ProxyPassReverse /Windchill-WHC/ http://pdm12.mycompany.com:8888/Windchill-WHC/
RewriteRule ^/Windchill$ /Windchill/ [R]
#Shibboleth Reverse Proxy Additions and Settings
ProxyPass /Shibboleth.sso/ http://pdm12.mycompany.com:8888/Shibboleth.sso/
ProxyPassReverse /Shibboleth.sso/ http://pdm12.mycompany.com:8888/Shibboleth.sso/
#Basic Authentication login page settings
ProxyPass /basicLogin.html http://pdm12.mycompany.coml:8888/basicLogin.html
ProxyPassReverse /bsaicLogin.html http://pdm12.mycompany.com:8888/basicLogin.html
# Force requests to Windchill
RedirectMatch ^/$ https://pdmlink-test.mycompany.com/Windchill/
RedirectMatch ^/windchill$ https://pdmlink-test.mycompany.com/Windchill/
What was added was the Shibboleth and basic auth sections. The other proxy settings I've always had. I can see that its hitting the pdm12 webserver since its logs the URL and a 404 error. This is why I suspect Shibboleth module is throwing the error.
welp, my issue was a misconfigured webserver all along. I came across a testy thread online that indicated my ServerName value was wrong. It was set to pdm12.my company.com:80 and should have been the same as my proxy as https://pdmlink-test.mycompany.com:443. That fixed my 404 error on the Metadata and I think I am authenticating. The remaining issue has to do with the sessionHook step.
Request Id: 4eih2vlk;lyeu3nzi;3457257;ceciz6;1828
Request URI: /Windchill/sso/shibboleth/sessionHook
Query String: <redacted>
Status Code: 500
Exception: wt.util.WTException: Failed to process the request. Contact your administrator for assistance.
rechecking my steps but stumped on this one.
I always forget about that one:-)
Let's step through this (I think I did all of this):
1. sessionHook.jsp (this was not done but based on error, do not think its the issue)
2. web.xml
<servlet-mapping>
<servlet-name>MVCDispatcher</servlet-name>
<url-pattern>/servlet/WizardServlet/*</url-pattern>
<url-pattern>/servlet/ActionsMenu/*</url-pattern>
<url-pattern>/servlet/RecentList/*</url-pattern>
<url-pattern>/servlet/Navigation/*</url-pattern>
<url-pattern>/servlet/SuggestServlet/*</url-pattern>
<url-pattern>/servlet/TypeBasedIncludeServlet/*</url-pattern>
<url-pattern>/servlet/UIValidationAJAXServlet/*</url-pattern>
<url-pattern>/ptc1/*</url-pattern>
<url-pattern>/app/</url-pattern>
<url-pattern>/gwt/*</url-pattern>
<url-pattern>/sso/*</url-pattern>
</servlet-mapping>
3. config.xml
<target name="-addTargetedUriWorkerMapEntries">
<!-- Description: Adds specific uriworkermap.properties entries required by a Windchill web app -->
<echo file="${uriworkerFile}" append="true" message="/${appName}/*.jsp=${iisAjpWorker}${line.separator}"/>
<echo file="${uriworkerFile}" append="true" message="/${appName}/*.jspx=${iisAjpWorker}${line.separator}"/>
<echo file="${uriworkerFile}" append="true" message="/${appName}/*.jspf=${iisAjpWorker}${line.separator}"/>
<echo file="${uriworkerFile}" append="true" message="/${appName}/*.jsp*=${iisAjpWorker}${line.separator}"/>
<echo file="${uriworkerFile}" append="true" message="/${appName}/servlet/*=${iisAjpWorker}${line.separator}"/>
<echo file="${uriworkerFile}" append="true" message="/${appName}/j_security_check=${iisAjpWorker}${line.separator}"/>
<echo file="${uriworkerFile}" append="true" message="/${appName}/*/j_security_check=${iisAjpWorker}${line.separator}"/>
<echo file="${uriworkerFile}" append="true" message="/${appName}/*.jar=${iisAjpWorker}${line.separator}"/>
<echo file="${uriworkerFile}" append="true" message="/${appName}/gwt/servlet/*=${iisAjpWorker}${line.separator}"/>
<echo file="${uriworkerFile}" append="true" message="/${appName}/gwt/*/servlet/*=${iisAjpWorker}${line.separator}"/>
<echo file="${uriworkerFile}" append="true" message="/${appName}/ptc1/*=${iisAjpWorker}${line.separator}"/>
<echo file="${uriworkerFile}" append="true" message="/${appName}/app=${iisAjpWorker}${line.separator}"/>
<echo file="${uriworkerFile}" append="true" message="/${appName}/app/*=${iisAjpWorker}${line.separator}"/>
<echo file="${uriworkerFile}" append="true" message="/${appName}/oslc/*=${iisAjpWorker}${line.separator}"/>
<echo file="${uriworkerFile}" append="true" message="/${appName}/trustedAuth/*=${iisAjpWorker}${line.separator}"/>
<echo file="${uriworkerFile}" append="true" message="/${appName}/protocolAuth/*=${iisAjpWorker}${line.separator}"/>
<echo file="${uriworkerFile}" append="true" message="/${appName}/sslClientAuth/*=${iisAjpWorker}${line.separator}"/>
<echo file="${uriworkerFile}" append="true" message="/${appName}/wt.properties=${iisAjpWorker}${line.separator}"/>
<echo file="${uriworkerFile}" append="true" message="/${appName}/*/wt.properties=${iisAjpWorker}${line.separator}"/>
<echo file="${uriworkerFile}" append="true" message="/${appName}/MethodServer=${iisAjpWorker}${line.separator}"/>
<echo file="${uriworkerFile}" append="true" message="/${appName}/jwt/*=${iisAjpWorker}${line.separator}"/>
<echo file="${uriworkerFile}" append="true" message="/${appName}/TokenGenerator/*=${iisAjpWorker}${line.separator}"/>
<echo file="${uriworkerFile}" append="true" message="/${appName}/sso/*=${iisAjpWorker}${line.separator}"/>
</target>
4. 30-app-Windchill-AJP.conf
JkMount /Windchill/WebEditor/* ajpWorker
JkMount /Windchill/MethodServer ajpWorker
JkMount /Windchill/jwt/* ajpWorker
JkMount /Windchill/TokenGenerator/* ajpWorker
JkMount /Windchill/sso/* ajpWorker
</IfModule>
I did restart and did clear tomcat cache. I think this is correct entries.
Have you done the SAML trace yet? that gives you a pretty good indication if the error lies on the IdP side or the SP side.
What attribute is defined in "REMOTE_USER" in the ApplicationDefault segment? Is that attribute defined in attributemap.xml? Is the attribute being sent by the IdP matching the attribute name (case sensitive) defined in REMOTE_USER / attributemap.xml?
I think I am getting as far as step 7 and failing at 8.
Yes, was able run trace:
Under the SAML tab for the last POST, I can see all my information as attributes. We've used sAMAccountName in our AD mapping for ever which I have plans to change but that is what matches to my Windchill ID.
<Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname">
<AttributeValue>Antonio</AttributeValue>
</Attribute>
<Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname">
<AttributeValue>Villanueva</AttributeValue>
</Attribute>
<Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress">
<AttributeValue>myemail</AttributeValue>
</Attribute>
<Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name">
<AttributeValue>my_sAMAccount_id</AttributeValue>
</Attribute>
Remote user is as follows: REMOTE_USER="uid"
and attribute-map.xml is as follows:
<!-- Added based on CS387845 -->
<Attribute name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/sAMAccountName" id="uid">
<AttributeDecoder xsi:type="StringAttributeDecoder" caseSensitive="false"/>
</Attribute>
Hmm, I think I see a disconnect from CS387845. Possibly, should I be mapping to "name"? Odd since when I am currently authenticating to AD, I used sAMAccountName,
You are on the right track questioning "name" yes that is likely the issue.
Try this in attribute map:
<!-- Added based on CS387845 -->
<Attribute name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name" id="uid">
<AttributeDecoder xsi:type="StringAttributeDecoder" caseSensitive="false"/>
</Attribute>
After that, restart apache and shibboleth service and try again
I did a bit more digging in the knowledge base and its strange. BTW, I was successfully able to authenticate and Windchill came up. I did change it to name but it did not work, got the same error. I believe name is the right value based on the SAML trace. Thanks for that. I came across CS387849 which says you can just remove the session hook. I did that and bingo, I am in.
Reading further, I questioned what is the session hook even for? CS349078 indicates it was a fix in cases where # in the URL caused issues and I am running 12.0.2. So strange. CS415010 was the exact error I was seeing which strongly points to the attribute mapping being the cause however, since I changed it from sAMAccountName to name, that should have fixed it.
<Attribute name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name" id="uid">
<AttributeDecoder xsi:type="StringAttributeDecoder" caseSensitive="false"/>
</Attribute>
Sessionhook is required. Otherwise whenever you send someone a link that has the # sign in it, it will take them to the home page instead.
Your users will hate you quick if Windchill behaves this way..
Yep, did a test with "Email this page". I hate myself already.
I would add sessionhook back to Shibboleth2.xml
Make sure in the SSO Block to add postArtifact / template / outgoingbindings (the bindingTemplate.html callout and file mods are what Windchill uses to make sessionhook work, so this is important!)
<SSO entityID="<IdP Entity>"
....
postArtifact="true" template="bindingTemplate.html" outgoingBindings="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" >
....
</SSO>
Make sure to edit the bindingTemplate.html file located at shibboleth_install_directory/etc/shibboleth (Add the following after the </head> tag and before the <noscript> tag
<!-- PTC Recommended Customization(1) Start -->
<!-- SHA-256 encoding for 'bindingTemplate.html' is a891be6b892aae62a98c82206444295c252c16622c1a386c5b0fbc293e376745 -->
<!-- keep the content, needed to handle some use cases -->
<body onload="submit();">
<!-- PTC Recommended Customization(1) End -->
<script type="text/javascript">
<!--
document.write("<p>You are automatically being redirected to the authentication service. ");
document.write("If the browser appears to be hung up after 15-20 seconds, try reloading ");
document.write("the page before contacting the technical support staff in charge of the ");
document.write("authentication service you are trying to access.</p>");
document.write("<h2>Redirecting...</h2>");
// -->
<!-- PTC Recommended Customization(2) Start -->
if (document.body != null && typeof document.body.onload !== 'function' && window.location != null) {
window.location.reload();
}
<!-- PTC Recommended Customization(2) End -->
</script>
<!-- PTC Recommended Customization(3) Start -->
<script type="text/javascript">
/**
* Saves the URL fragment to session store, if it is available in browsers address bar
*/
function saveURLFragment(){
var URL_FRAGMENT_KEY = 'WINDCHILL_SSO_URL_FRAGMENT';
var windchillStore = window.sessionStorage;
if(windchillStore){
var hash = document.location.href.split('#')[1];
if(hash && hash.length > 0 ){
windchillStore.setItem(URL_FRAGMENT_KEY , hash);
}else{
// clean-up, if left by previous incomplete login attempt.
windchillStore.removeItem(URL_FRAGMENT_KEY);
}
}
}
function submit(){
saveURLFragment();
document.forms[0].submit();
}
</script>
<!-- PTC Recommended Customization(3) End -->
If you modified any templates you can run a regenAllWebapps command from the httpserver folder again similar to when you turn on ProtocolAuthOnly (
ant -DprotocolAuthOnly=true -f webAppConfig.xml regenAllWebApps)
Another note, if you use Desktop Integration, you need to modify the following files accordingly:
The DTILogin action of the connect command must be defined as WIZARD, for this use the below steps:
I will take another look here. PTC instruction was strange. I one place they said to copy their file they provided and other place they said strongly NOT to do that. I ended up cutting and pasting sections in. Thanks again for all your help.
I think there is some poor documentation. Help Docs do show sample changes for the bindingTemplate.html with 3 customization sections. The same file they reference, one, is not in that location but did find it, and two, only has two customization sections. I see what is missing and an added that back in.
Lot's of poor documentation / conflicting instructions. I helped troubleshoot this before it was officially supported (In WC 11.2) where the components were there, but not officially supported. I sent a bunch of comments back and suggestions for updates to documentation. Several things were never updated
I justed wanted to return to this thread and close it out thought I still have a few more loose ends to wrap up. Thank you so much to @jbailey for all your help. We actually took this offline to keep thread smaller. Here is a summary of what I learned:
I am doing a similar setup with reverse proxy and SAML SSO. I was able to fix the sessionHook issue by changing my version of Shibboleth. I am using Windchill 12.0 so I followed this guide: https://partnervision.com.br/wp-content/uploads/2022/03/WindchillSoftwareMatrices_12_0_0_0.pdf
On page 13, it says Shibboleth must be within the 3.1.x series even though the latest version is 3.4.x
Also all attribute-map does is takes an attribute with a name from the IdP (left side) and translate it to an attribute that Shibboleth will use, and REMOTE_USER mapped to that shibboleth attribute name to present to apache. It honestly doesn't matter what you use, as long as shibboleth knows the attribute it is getting and translates it to something your app will use.