Important Update Effective February 1, 2024!
Due to recent changes in Jira and Confluence, we've made the tough decision to discontinue the OpenID Connect (OIDC)/OAuth app and no longer provide new versions for the newest Jira/Confluence releases as of January 31, 2024.
This is due to some necessary components no longer shipping with Jira/Confluence, which would require some extensive rewrites of the OIDC App.
Important Update! This app will be discontinued soon!
Due to recent changes in Jira, which no longer ships with some components required for our Read Receipts app to run, we've made the tough decision to discontinue the app, as of Februar 5, 2025.
Important Update! This app will be discontinued soon!
We've made the tough business decision to discontinue the app, as of January 11, 2025.
How SAMLSingleSignOn works
This page gives a brief overview about how SAML Single Sign On from resolution GmbH works. For more detailed information about SAML 2.0 see http://saml.xml.org/saml-specifications. SAML SingleSignOn uses the HTTP POST Binding.
SAMLSingleSignOn currently implements a subset of SAML 2.0 only. Additional features (e.g. message encryption, IdP discovery, Single Sign Out) may be implemented in future releases. Please contact us at atlassianplugins@resolution.de if you require additional functionality.
Step 1: A user requests access to a restricted page
A user requests access to a restricted page within Confluence or JIRA.
Step 2: Redirect to the SAMLSSO-Servlet
The plugin will recognise the user request and will redirect the user to Single Sign On Servlet (at https://<baseurl>/plugins/servlet/samlsso) to start the authentication process.
- Action for user: Activate "Enable SSO Redirect" in the configuration page. Otherwise, the servlet on the URL above has to be called explicitly to perform SSO.
Step 3: The SAML-request is created
The SAMLSSO-Servlet creates SAML-request.
<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" AssertionConsumerServiceURL="https://jira01.lab.inserve.local/plugins/servlet/samlsso" Destination="https://dc01.ad.lab.inserve.local/adfs/ls/" ID="fpfphpacfcmenaooalnnkkdolgpnnajhjgkiaeop" IssueInstant="2015-02-06T19:10:51.620Z" Version="2.0">
<samlp:Issuer xmlns:samlp="urn:oasis:names:tc:SAML:2.0:assertion">https://jira01.lab.inserve.local/plugins/servlet/samlsso</samlp:Issuer>
<saml2p:RequestedAuthnContext xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" Comparison="minimum">
<saml:AuthnContextClassRef xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef>
</saml2p:RequestedAuthnContext>
</samlp:AuthnRequest>
Step 4: The user is redirected to the IdP
The servlet creates and sends an HTTP redirect to the user browser, which points to the Identity Provider. An example looks like below (the encoded request is abridged for clarity):
https://dc01.ad.lab.inserve.local/adfs/ls/?SAMLRequest=nZJNa%2BMwEIb2Bl448L3THy2e7t8e4zAO2J1vSPt38B&RelayState=%2F
- The URL set: https://dc01.ad.lab.inserve.local/adfs/ls/?
- SAML Request: SAMLRequest=nZJNa%2BMwEIb2Bl448L3THy2e7t8e4zAO2J1vSPt38B&
- RelayState-Parameter: RelayState=%2F
Starting with version 0.9.5, SAML SingleSignOn can be configured to respond with a auto-submitting HTML form containing the SAML-request. This allows using POST instead of GET to redirect to the IdP
Step 5: The user is authenticated at the IdP
The Identity Provider decodes the SAMLRequest and performs the user authentication.
What happens here is depending on the IdP configuration and the situation:
The IdP
- already know the user (because he/she already signed in to another application)
- uses a sophisticated authentication mechanism, such as Kerberos
- do not know the user and prompts for credentials
If the authentication was successful, the IdP creates a SAML-Response.
<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified" Destination="https://jira01.lab.inserve.local/plugins/servlet/samlsso" ID="_2b176e8e-306f-41ff-a270-6c31912da25d" InResponseTo="fpfphpacfcmenaooalnnkkdolgpnnajhjgkiaeop" IssueInstant="2015-02-06T19:12:54.168Z" Version="2.0">
<Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion">http://dc01.ad.lab.inserve.local/adfs/services/trust</Issuer>
<samlp:Status>
<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
</samlp:Status>
<Assertion xmlns="urn:oasis:names:tc:SAML:2.0:assertion" ID="_c8a8f7cc-2ecf-44fe-bb9d-c0690a8d4215" IssueInstant="2015-02-06T19:12:54.168Z" Version="2.0">
<Issuer>http://dc01.ad.lab.inserve.local/adfs/services/trust</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/2001/04/xmldsig-more#rsa-sha256"/>
<ds:Reference URI="#_c8a8f7cc-2ecf-44fe-bb9d-c0690a8d4215">
<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/2001/04/xmlenc#sha256"/>
<ds:DigestValue>GprR3FWR3i2x+Gu/dxSJUj1pElL9l2OsnzGPZFG2XKM=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>fQBzUop+[...]YsoCI/Qgg==</ds:SignatureValue>
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<ds:X509Data>
<ds:X509Certificate>YAS[...]tU3Qmo9/QQyr7zxBTVsQBNp7H1Mi69gIw==</ds:X509Certificate>
</ds:X509Data>
</KeyInfo>
</ds:Signature>
<Subject>
<NameID>sam</NameID>
<SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<SubjectConfirmationData InResponseTo="fpfphpacfcmenaooalnnkkdolgpnnajhjgkiaeop" NotOnOrAfter="2015-02-06T19:17:54.168Z" Recipient="https://jira01.lab.inserve.local/plugins/servlet/samlsso"/>
</SubjectConfirmation>
</Subject>
<Conditions NotBefore="2015-02-06T19:12:54.168Z" NotOnOrAfter="2015-02-06T20:12:54.168Z">
<AudienceRestriction>
<Audience>https://jira01.lab.inserve.local/plugins/servlet/samlsso</Audience>
</AudienceRestriction>
</Conditions>
<AuthnStatement AuthnInstant="2015-02-06T16:47:19.213Z" SessionIndex="_c8a8f7cc-2ecf-44fe-bb9d-c0690a8d4215">
<AuthnContext>
<AuthnContextClassRef>urn:federation:authentication:windows</AuthnContextClassRef>
</AuthnContext>
</AuthnStatement>
</Assertion>
</samlp:Response>
The important part here is the <Subject>-Tag, especially the containing <NameID>-Tag: The containing data (sam in this example) is considered as the userid to login.
Step 8: The plugin validates the response and extracts the userid.
The SAMLSSO-servlet receives the form data and decodes the response. The response from Step 6 contains a digital signature which is validated against the certificate set in the plugin configuration. The user ID is extracted from the XML.
Step 9: The user is authenticated
The Plugin tries to load the user from the Confluence/JIRA user-directory. If this is successful, a session is established (similar to what happens after the user has successfully entered his credentials into the login form) and the user is redirected to the originally requested URL.