Skip to end of metadata
Go to start of metadata

Plugin Information

View SAML on the plugin site for more information.

Older versions of this plugin may not be safe to use. Please review the following warnings before using an older version:

This plugin allows authentication to Jenkins via the SAML 2.0 protocol.

Configure Jenkins

Troubleshooting

Changelog

 

46 Comments

  1. Howdy. I've been successfully using the Active Directory plugin and thought I'd give SAML a try since we have an STS and smart admins who can help. Jenkins is making it all the way through the request and then displaying an error (included below) on the finish login page. At the bottom of the stack trace, the last cause reads "Caused by: org.opensaml.xml.security.SecurityException: SAML message intended destination endpoint did not match recipient endpoint".

    This is weird because when I capture the POST to https://server/securityRealm/finishLogin, I can decode the base64 SAMLResponse blob in the form data, which contains a samlp:Response element with a Destination attribute set to the correct uri, and a SubjectConfirmationData element with a Recipient attribute with the exact same correct uri. However, the Jenkins error log shows a more informative message which actually has a different value for the recipient endpoint: "SEVERE: SAML message intended destination endpoint 'https://server/securityRealm/finishLogin' did not match the recipient endpoint 'http://server/securityRealm/finishLogin'"

    So at the heart of the matter is probably the fact that I'm accessing the Jenkins machine behind an load balancer which is doing the SSL for me. On the other side of the port, it talks plain HTTP to Jenkins and this hasn't caused any problems until now. It seems like maybe either the SAML plugin or one of hte libraries in it is picking up on that using the actual protocol coming from the load balancer (HTTP) instead of just paying attention to the message and maybe comparing it against the official server uri in the global config (which properly is https://server).

    Any thoughts on this? I don't have a lot of bandwidth to play with certs to try to get Jenkins going on SSL outside of what the load balancer is already providing here, so I might have to give up on this if there's no workaround.

    Thanks,

    Jesse

    (trace/error/response attached, just anonymized a bit)

    https-server-securityRealm-finishLogin.txt

    jenkins.err.log

    samlp-response.xml

    Jenkins System Properties.xlsx

    1. So I'm thinking either I'm missing something or the plugin is incomplete for use with matrix based authorization. Shouldn't there be a metadata file someplace that describes the attributes it needs from the IdP? I'm using ADFS and I'm basically feeling around in the dark here. Is there not enough code in the plugin to wire up group memberships? There's certainly no service assertion consumer service metadata anywhere that I can tell which describes how to setup the response from my IdP. Has anyone gotten this working? Google is no help, which is unusual, so I'm guessing not many are using this, which is a shame because if all I wanted to do was grant privs by userID this would rock.Until I can figure out how to wire up groups I can't use it since I'm using the AD plugin with matrix based authorization.

      Also it looks like I'm logged in as an individual user, but when I nav to /whoAmI, I get "IsAuthenticated?: false", which is weird since it shows me logged in, and the "toString" is "org.jenkinsci.plugins.saml.SamlAuthenticationToken@3bce19c4: Username: G537832; Password: [PROTECTED]; Authenticated: false; Details: null; Granted Authorities", which is very incomplete compared to when I login with the AD plugin as the same user. Any thoughts?

      Thanks,

      Jesse

      1. So close! After looking over the code I can see that there is no support for requesting or mapping GrantedAuthorities, as your userdetail object just hardcodes an empty array. You would need to add code similar to what's in other plugins like the AD auth plugin and provide some SAML Assertion Consumer Service Metadata describing the structure in which you expect to receive the group attribute values from the IdP. I would love to add this because I'm thinking this is the only way I will ever get SSO, but I'm maybe already too busy just getting Jenkins implemented at a large organization to start a side project like that. I dropped an issue in your original github repo since the new one doesn't accept issues, looking forward to your thoughts.

        -Jesse

  2. Jesse, Any luck getting this working at its most basic mode, just doing SSO authentication? I can live without group coverage, as long as it will just authenticate. But I couldnt get past the issue with the LoadBalancer passing back https URL while we havent setup SSL on the Jenkins servers.

    Any insight would be greatly appreciated.

    Thanks,

    John

    1. Jesse,

      All I see when in Jenkins Security configuration is:

      What do I put in there?

      Thanks,

      john

      1. Yes, I got it working for basic SSO auth but no groups (plugin doesn't support any assertions except generically mapped names and email), so I had to remove it until I either have time to add group support to the plugin or someone else does it for me ;) Seeing Jenkins do SSO is pretty mindblowing, so I wish more people were into this plugin. Addressing your two questions:

        1) I resolved the load balancer problem by enabling SSL on the Jenkins command line. It uses a self-signed certificate by default, so I had the load balancer admin ignore the validation errors on the backside of the VIP since we have a real certificate on the frontside. There's no way around this because SAML requires end-to-end security.

        2) The "IdP Metadata" text box for the plugin should contain your identity provider's metadata xml document contents. Your IdP should have a federation metadata XML file or URL you can access, just copy and paste the contents into that box in Jenkins. The federation metadata document contains important crypto evidence like signatures and certificates to verify the initial safety of the IdP and authenticity of future messages. The document root element should be <EntityDescriptor>.

        Your Identity Provider also needs to know about Jenkins. You have to tell it to post responses redirected from your jenkins URL to https://<jenkinsHost>/securityRealm/finishLogin so the SAML plugin can process them. Most IdPs support (expect?) a service provider metadata document as well, but since the Jenkins SAML plugin doesn't expect any assertions other than basic identity (name and email), you shouldn't need one and your IdP should still be able to process logins.

        I've only worked with ADFS as an IdP, but the SAMLness of the whole thing should make the experience pretty similar from system to system. Speaking of ADFS, the underlying SAML library used by the plugin (pac4j) has an ADFS-specific readme with some additional details that you or your ADFS admin might need to know. My admin read it and wasn't worried, but it's good to know about.

        Lmk if you have other questions, but I think that's all there is to it. It's weirdly technical, but whoever is running your IdP probably has to do most of the heavy lifting--once you get that XML data there really shouldn't be much else to do except get end-to-end SSL going.

        1. Hi Jacob,

          I have copy-pasted the Idp metadata file in jenkins and on the Idp side it is asking for 3 fields.

          ->Target Url->https://<server name>/securityRealm/finishLogin

          ->Entity Id->I Have entered my jenkins Url

          ->Acs url ->I Have entered the Jenkins Url

          Now when i am clicking on login button in Jenkins,it is giving an error that the partner id attribute is invalid

          Kindly help in this.

          Mail Id:-priyadarshi035@gmail.com

  3. Hi,

     We are trying to use this plug in to authenticate using shibboleth2.  I have entered the idp matedata, and jenkins redirects to the shibboletth page.

     For the shibboleth setup the team is asking for the SP metadata.  Do you know where I can get this info?

    Thanks

    Venki

    1. Hi Venki, the SAML plugin is very basic and doesn't have a metadata document included anywhere. You can capture it using a fiddler session that decodes HTTP. I would post it here but I don't currently have the plugin wired up to my test Jenkins instance right now. Also, if you've configured the plugin to the point that it's going to the Shibboleth page, they should actually now have a copy of the doc...they should be able to see it with basic logging/debugging on their end. It's super basic and only supports assertions about username and email (for now).

  4. I am having an issue with user IDs that are numbers and letters... 

    I created a ticket, but it doesn't seem to be getting resolved. Does anyone have a suggestion, or can fix this?

    https://issues.jenkins-ci.org/browse/JENKINS-27423

    1. Hey Camron, What is your IdP? I've used the plugin with Microsoft ADFS and it works great. If your IdP is Active-Directory sourced, I wonder if it's sending back your AD security ID (objectSID property) as the username in the XML response instead of the samAccountName...do you have access to the IdP configuration to be able to see what it's getting from Jenkins and what it's replying with? If you have access to the AD instance that's backing it, it would be interesting if you could look at your account and see if those letters/numbers match up with any attribute values on your user object. You should be able to use something like fiddler to snatch a copy of the full response doc from your IdP, which you could try posting here...

      1. Thanks for the reply, Jesse. I am using Azure Active Directory.

        I assume this is what you are looking for?

        		<AttributeStatement>
        			<Attribute Name="http://schemas.microsoft.com/identity/claims/tenantid">
        				<AttributeValue>fa2e957d-d348-4cf8-94cf-dae799dfbbda</AttributeValue>
        			</Attribute>
        			<Attribute Name="http://schemas.microsoft.com/identity/claims/objectidentifier">
        				<AttributeValue>bafeb2b8-7fe6-48b0-be6a-9edb83b35d9e</AttributeValue>
        			</Attribute>
        			<Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name">
        				<AttributeValue>camron.bute@devfacto.com</AttributeValue>
        			</Attribute>
        			<Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname">
        				<AttributeValue>Bute</AttributeValue>
        			</Attribute>
        			<Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname">
        				<AttributeValue>Camron</AttributeValue>
        			</Attribute>
        			<Attribute Name="http://schemas.microsoft.com/identity/claims/displayname">
        				<AttributeValue>Camron Bute</AttributeValue>
        			</Attribute>
        			<Attribute Name="http://schemas.microsoft.com/identity/claims/identityprovider">
        				<AttributeValue>https://sts.windows.net/fa2e957d-d348-4cf8-94cf-dae799dfbbda/</AttributeValue>
        			</Attribute>
        		</AttributeStatement>
        
        1. This is an attribute statement block. Before this block there is another one like below

           
             <saml:Subject>
               <saml:NameID
                 Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">
                 USER_IDENTIFIER
               </saml:NameID>
               <saml:SubjectConfirmation
                 Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
                 <saml:SubjectConfirmationData
                   InResponseTo="aaf23196-1773-2113-474a-fe114412ab72"
                   Recipient="https://sp.example.com/SAML2/SSO/POST"
                   NotOnOrAfter="2004-12-05T09:27:05"/>
               </saml:SubjectConfirmation>
             </saml:Subject>
          

          where USER_IDENTIFIER is the value that plugin uses as user name. Usually IdP allows to configure a source for this field.

  5. With the SAML plugin, is it possible to send a group instead of a username?  That way I don't have to manually add each user in the security matrix?

    1. Hi Nick. I wouldn't do that. It would use that name as your Jenkins user name, in which case a variety of weirdness is possible. If Jenkins uses the username/email as a unique combo then your users would end up with N unique usernames (N = number of groups you're trying to assign rights to in the matrix) so you wouldn't be able to tell anyone apart without clicking into their user config, and it would break things like source control plugins that associate changesets to Jenkins 
      user names. If Jenkins uses only the username as the user object key then you'd only be able to have as many accounts as you have groups in your matrix, but a multitude of passwords could be used to log into each one, if you get how that would work. Long story short: this is a bad idea and you should wait for someone to implement group support in this otherwise really awesome plugin.

  6. Hi,

    I'm trying to get Jenkins SAML plugin to work with Okta for user authentication. According to the instructions, the setup is supposed to simple and straightforward.

    What I did was:

    1. Installed Jenkins SAML plugin, go to "Configure Global Security" page and select "SAML 2.0", and there is only one input text field asking for IdP metadata where I should get from Okta.

    2. Set up Jenkins App in Okta (I've tried both generic Jenkins app and a custom app), give the Jenkins base URL: https://<Jenkins Server DNS>. If using Okta generic Jenkins app, Postback URL, Recipient, Audience Restriction and Destination will be generated automatically as https://<Jenkins Server DNS>/securityRealm/finishLogin

    3. Copied metadata from Okta Jenkins app to Jenkins, save the settings and restart Jenkins server.

    4. Hit Jenkins URL, everything seems fine, I was redirected to Okta login page asking for Okta username and password.

    5. After filling username and password in Okta login page, weird thing happened, I got "400 bad request" error, see below.

        

    6. And by checking Jenkins logs, I found the following warnings:
        IdP wants authn requests signed, it will perhaps reject your authn requests unless you provide a keystore", and in the log I can see it's always complaining "Relay state exceeds 80 bytes, some application may not support this". 

    7. After clicking on "Go to Homepage" from the "400 bad request" page, I was redirected back to Okta apps page, and I can see the Jenkins app assigned to my Okta account, after clicking on the Jenkins app from the Okta apps page, I was redirected back to Okta Login page again.

    8. Filled in my Okta username and password on the Okta login page, this time I got in Jenkins.

    But why I failed logged in the first time?? And why I got "400 bad request"? Spent almost a week investigating on this problem, but still couldn't figure out. Hoping to get help and advice. Really appreciate it!!

    1. Could you catch Okta response and post it here?

      1. Hi Mikhail,

        Thanks for your reply. I finally got it sorted out after changing request compression from "Uncompressed" to "Compressed" in Okta, the login now works fine.

        However, I'm having another problem that Jenkins cannot be logged out until Okta session expires. I've been seeking SP-initiated logout, but couldn't find anything in Jenkins. Wondering if you can help me with it. Very much appreciated!

        1. As I know, neither local logout nor SP-Initiated Single Logout are not supported. Or to be more precise, local logout is supported, but after it has done the plugin immediately initiates new SAML authentication flow.

          1. This would indeed be a nice feature ...

  7. Does anyone know if group support is in development?

    1. Yes! It's only been tested by the implementer against ADFS, but it works PERFECTLY!! I have it running in a production environment (also against ADFS) and I'm loving it. I built off the implementer's PR as the SAML plugin maintainer has been too busy to do a release. Thanks 0xcfff!

      1. Hi Jesse,

        I am using the saml plugin to integrate with Azure AD.  I was able to use it to login to jenkins however, after login it doesn't keep the username/groups.  We use the matrix based security to allow certain groups access to different jenkins jobs.  We need to either allow anonymous or add the users manually to jenkins.  Would you be able to provide any steps to integrate with Azure AD and have it pass along the group and username?

        1. Just a clarification,  we are using Project Based Matrix Authorization.  Also, do you have instructions/link on how to build and install this patch?

          1. Try release 0.4, instruction will be updated soon.

            1. Hi Mikhail!

              I wonder if there any updates about how to set up these groups?

  8. Hi,

    Just a new issue I noticed.  After the Maximum Authentication Lifetime passes.  I receive a stacktrace of:  Is there a way it can redirect to the login page? javax.servlet.ServletException: org.pac4j.saml.exceptions.SamlException: No valid subject assertion found in response
    at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:796)
    at org.kohsuke.stapler.Stapler.invoke(Stapler.java:876)
    at org.kohsuke.stapler.MetaClass$4.doDispatch(MetaClass.java:211)
    at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:53)
    at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:746)
    at org.kohsuke.stapler.Stapler.invoke(Stapler.java:876)
    at org.kohsuke.stapler.Stapler.invoke(Stapler.java:649)
    at org.kohsuke.stapler.Stapler.service(Stapler.java:238)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:686)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1494)
    at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:123)
    at hudson.plugins.scm_sync_configuration.extensions.ScmSyncConfigurationFilter$1.call(ScmSyncConfigurationFilter.java:46)
    at hudson.plugins.scm_sync_configuration.ScmSyncConfigurationDataProvider.provideRequestDuring(ScmSyncConfigurationDataProvider.java:103)
    at hudson.plugins.scm_sync_configuration.extensions.ScmSyncConfigurationFilter.doFilter(ScmSyncConfigurationFilter.java:42)
    at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:120)
    at hudson.util.PluginServletFilter.doFilter(PluginServletFilter.java:114)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1482)
    at hudson.security.csrf.CrumbFilter.doFilter(CrumbFilter.java:48)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1482)
    at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:84)
    at hudson.security.UnwrapSecurityExceptionFilter.doFilter(UnwrapSecurityExceptionFilter.java:51)
    at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
    at jenkins.security.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:117)
    at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
    at org.acegisecurity.providers.anonymous.AnonymousProcessingFilter.doFilter(AnonymousProcessingFilter.java:125)
    at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
    at org.acegisecurity.ui.rememberme.RememberMeProcessingFilter.doFilter(RememberMeProcessingFilter.java:135)
    at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
    at org.acegisecurity.ui.AbstractProcessingFilter.doFilter(AbstractProcessingFilter.java:271)
    at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
    at jenkins.security.BasicHeaderProcessor.doFilter(BasicHeaderProcessor.java:93)
    at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
    at org.acegisecurity.context.HttpSessionContextIntegrationFilter.doFilter(HttpSessionContextIntegrationFilter.java:249)
    at hudson.security.HttpSessionContextIntegrationFilter2.doFilter(HttpSessionContextIntegrationFilter2.java:67)
    at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
    at hudson.security.ChainedServletFilter.doFilter(ChainedServletFilter.java:76)
    at hudson.security.HudsonFilter.doFilter(HudsonFilter.java:168)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1482)
    at org.kohsuke.stapler.compression.CompressionFilter.doFilter(CompressionFilter.java:49)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1482)
    at hudson.util.CharacterEncodingFilter.doFilter(CharacterEncodingFilter.java:81)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1482)
    at org.kohsuke.stapler.DiagnosticThreadNameFilter.doFilter(DiagnosticThreadNameFilter.java:30)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1474)
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:499)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:137)
    at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:533)
    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:231)
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1086)
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:428)
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:193)
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1020)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116)
    at org.eclipse.jetty.server.Server.handle(Server.java:370)
    at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:489)
    at org.eclipse.jetty.server.AbstractHttpConnection.content(AbstractHttpConnection.java:960)
    at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.content(AbstractHttpConnection.java:1021)
    at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:865)
    at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:240)
    at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82)
    at org.eclipse.jetty.io.nio.SslConnection.handle(SslConnection.java:196)
    at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:668)
    at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:52)
    at winstone.BoundedExecutorService$1.run(BoundedExecutorService.java:77)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)
    Caused by: org.pac4j.saml.exceptions.SamlException: No valid subject assertion found in response
    at org.pac4j.saml.sso.Saml2ResponseValidator.validateSamlSSOResponse(Saml2ResponseValidator.java:168)
    at org.pac4j.saml.sso.Saml2ResponseValidator.validateSamlResponse(Saml2ResponseValidator.java:99)
    at org.pac4j.saml.client.Saml2Client.retrieveCredentials(Saml2Client.java:317)
    at org.pac4j.saml.client.Saml2Client.retrieveCredentials(Saml2Client.java:95)
    at org.pac4j.core.client.BaseClient.getCredentials(BaseClient.java:211)
    at org.jenkinsci.plugins.saml.SamlSecurityRealm.doFinishLogin(SamlSecurityRealm.java:148)
    at sun.reflect.GeneratedMethodAccessor810.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.kohsuke.stapler.Function$InstanceFunction.invoke(Function.java:298)
    at org.kohsuke.stapler.Function.bindAndInvoke(Function.java:161)
    at org.kohsuke.stapler.Function.bindAndInvokeAndServeResponse(Function.java:96)
    at org.kohsuke.stapler.MetaClass$1.doDispatch(MetaClass.java:121)
    at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:53)
    at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:746)
    ... 68 more

    1. You can increase Maximum Authentication Lifetime parameter in plugin settings to fix that. Redirect to IdP will not help as it will end up with a new assertion where AuthnInstant will have the same value as before. To workarond that, you can logout/login on IdP and then login to jenkins, this will renew AuthnInstant value. This trick allows to change plugin's settings through jenkins UI.

  9. Hey everyone...just wanted to "bump" this discussion...

    I have the SAML plug-in working like a champ in production, using ADFS as my IDP.  Like others, the only thing missing that I would *really* like to have is support for Active Directory groups, as was present in the AD plugin.  We have a good many development\scrum teams, and some of the groups are pretty large, so being able to have one item in our matrix rather than 10-40 per group would be a really nice feature!

    I see some have gotten it working, but has anyone documented how to do so?  If not, is there an update for the plugin coming down the pipe anytime soon?

    Thanks for everything!

    1. Mikhail posted above that it was officially implemented in v0.4 and the instructions on this page have already been updated--see above under "Configuring groups security". Just remember the group names you enter are case-sensitive as that's the most usual gotcha about anything AD-related in Jenkins.

      1. Doh, you're right...I think I misunderstood because I missed the part about needing the Role-Based plugin.  I am good to go, thanks again to everyone for this amazing plugin!

  10. In the, "Single Log Out" example above the following is referenced:RewriteRule ^/?logout$ https://idp.example.com/simplesamlphp/saml2/idp/initSLO.php?RelayState=https://jenkins.example.com/ 0:;

    The CO value in the RewriteRule flags appears to be problematic (i.e. HTTP Cookie isn't terminated. Proposing the following update for your example above to ensure sessions are terminated properly:
    LOGGED_OUT:;

    • Username Attribute - URI of claim that carries user name which will be used as the Jenkins id if specified, otherwise the SAML profile id will be used.

    This field seems to be missing from the configuration page in v0.5 - is the documentation incorrect?

  11. Hey Jan Fabry, Are there user-friendly release notes anywhere? 

    1. in this page, you have the changelog at the end

  12. Having this issue, have tested upgrading from 0.14 to 1.0.3 Java 8 & Java 9 with Jenkins 2.60.1 and 2.60.3 . Same problems with Okta and Saml.  Thought this was fixed in 1.0.3 but it's not... Any help here for a definitive fix would be appreciated.
    Stack trace

    java.lang.NullPointerException

     at java.lang.String.compareTo(java.base@9-internal/String.java:1210)

     at org.jenkinsci.plugins.saml.SamlSecurityRealm.loadUserName(SamlSecurityRealm.java:325)

     at org.jenkinsci.plugins.saml.SamlSecurityRealm.doFinishLogin(SamlSecurityRealm.java:268)

     at java.lang.invoke.MethodHandle.invokeWithArguments(java.base@9-internal/MethodHandle.java:636)

     at org.kohsuke.stapler.Function$MethodFunction.invoke(Function.java:343)

     at org.kohsuke.stapler.Function.bindAndInvoke(Function.java:184)

     at org.kohsuke.stapler.Function.bindAndInvokeAndServeResponse(Function.java:117)

     at org.kohsuke.stapler.MetaClass$1.doDispatch(MetaClass.java:129)

     at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:58)

     at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:715)

    Caused: javax.servlet.ServletException

     at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:765)

     at org.kohsuke.stapler.Stapler.invoke(Stapler.java:845)

     at org.kohsuke.stapler.MetaClass$3.doDispatch(MetaClass.java:209)

     at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:58)

     at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:715)

     at org.kohsuke.stapler.Stapler.invoke(Stapler.java:845)

     at org.kohsuke.stapler.Stapler.invoke(Stapler.java:649)

     at org.kohsuke.stapler.Stapler.service(Stapler.java:238)

     at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)

     at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:812)

     at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1669)

     at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:135)

     at hudson.util.PluginServletFilter.doFilter(PluginServletFilter.java:138)

     at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)

     at hudson.security.csrf.CrumbFilter.doFilter(CrumbFilter.java:49)

     at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)

     at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:84)

     at hudson.security.UnwrapSecurityExceptionFilter.doFilter(UnwrapSecurityExceptionFilter.java:51)

     at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)

     at jenkins.security.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:117)

     at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)

     at org.acegisecurity.providers.anonymous.AnonymousProcessingFilter.doFilter(AnonymousProcessingFilter.java:125)

     at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)

     at org.acegisecurity.ui.rememberme.RememberMeProcessingFilter.doFilter(RememberMeProcessingFilter.java:135)

     at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)

     at org.acegisecurity.ui.AbstractProcessingFilter.doFilter(AbstractProcessingFilter.java:271)

     at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)

     at jenkins.security.BasicHeaderProcessor.doFilter(BasicHeaderProcessor.java:92)

     at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)

     at org.acegisecurity.context.HttpSessionContextIntegrationFilter.doFilter(HttpSessionContextIntegrationFilter.java:249)

     at hudson.security.HttpSessionContextIntegrationFilter2.doFilter(HttpSessionContextIntegrationFilter2.java:67)

     at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)

     at hudson.security.ChainedServletFilter.doFilter(ChainedServletFilter.java:90)

     at hudson.security.HudsonFilter.doFilter(HudsonFilter.java:171)

     at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)

     at org.kohsuke.stapler.compression.CompressionFilter.doFilter(CompressionFilter.java:49)

     at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)

     at hudson.util.CharacterEncodingFilter.doFilter(CharacterEncodingFilter.java:82)

     at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)

     at org.kohsuke.stapler.DiagnosticThreadNameFilter.doFilter(DiagnosticThreadNameFilter.java:30)

     at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)

     at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:585)

     at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)

     at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:553)

     at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:223)

     at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1127)

     at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515)

     at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)

     at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1061)

     at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)

     at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)

     at org.eclipse.jetty.server.Server.handle(Server.java:499)

     at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:311)

     at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257)

     at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:544)

     at winstone.BoundedExecutorService$1.run(BoundedExecutorService.java:77)

     at java.util.concurrent.ThreadPoolExecutor.runWorker(java.base@9-internal/ThreadPoolExecutor.java:1158)

     at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@9-internal/ThreadPoolExecutor.java:632)

     at java.lang.Thread.run(java.base@9-internal/Thread.java:804)

    1. Open a JIRA for the issue (How to report an issue),  The problem should be on the SAMLResponse try to increase the log level and attach the logs on the issue.

      Troubleshooting

      When you face an issue you could try to enable a logger to these two packages on the level specified and try to find errors, this will show in logs the information send from Jenkins (SP) to the SAML service (IdP), this information could be sensitive so take care where you copy/send it.  

      • org.jenkinsci.plugins.saml - FINEST
      • org.pac4j - FINE


      Also, Java 9 is not yet supported by Jenkins.

  13. Hi,

    While trying to setup SSO using Okta IDP with Jenkins using SAML2.0 Addin I get the below error:

    SP Entity ID: http://lnx-scc-d001.nike.com:8080 

    where host is lnx-scc-d001 where the Jenkins is installed.

     

    org.pac4j.saml.exceptions.SAMLException: No valid subject assertion found in response at org.pac4j.saml.sso.impl.SAML2DefaultResponseValidator.validateSamlSSOResponse(SAML2DefaultResponseValidator.java:313) at org.pac4j.saml.sso.impl.SAML2DefaultResponseValidator.validate(SAML2DefaultResponseValidator.java:138) at org.pac4j.saml.sso.impl.SAML2WebSSOMessageReceiver.receiveMessage(SAML2WebSSOMessageReceiver.java:77) at org.pac4j.saml.sso.impl.SAML2WebSSOProfileHandler.receive(SAML2WebSSOProfileHandler.java:35) at org.pac4j.saml.client.SAML2Client.retrieveCredentials(SAML2Client.java:225) at org.pac4j.saml.client.SAML2Client.retrieveCredentials(SAML2Client.java:60) at org.pac4j.core.client.IndirectClient.getCredentials(IndirectClient.java:106) at org.jenkinsci.plugins.saml.SamlProfileWrapper.process(SamlProfileWrapper.java:53) at org.jenkinsci.plugins.saml.SamlProfileWrapper.process(SamlProfileWrapper.java:33) at org.jenkinsci.plugins.saml.OpenSAMLWrapper.get(OpenSAMLWrapper.java:65) at org.jenkinsci.plugins.saml.SamlSecurityRealm.doFinishLogin(SamlSecurityRealm.java:265) at java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:627) at org.kohsuke.stapler.Function$MethodFunction.invoke(Function.java:343) at org.kohsuke.stapler.Function.bindAndInvoke(Function.java:184) at org.kohsuke.stapler.Function.bindAndInvokeAndServeResponse(Function.java:117) at org.kohsuke.stapler.MetaClass$1.doDispatch(MetaClass.java:129) at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:58) at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:715) Caused: javax.servlet.ServletException at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:765) at org.kohsuke.stapler.Stapler.invoke(Stapler.java:845) at org.kohsuke.stapler.MetaClass$3.doDispatch(MetaClass.java:209) at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:58) at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:715) at org.kohsuke.stapler.Stapler.invoke(Stapler.java:845) at org.kohsuke.stapler.Stapler.invoke(Stapler.java:649) at org.kohsuke.stapler.Stapler.service(Stapler.java:238) at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:841) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1650) at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:135) at hudson.util.PluginServletFilter.doFilter(PluginServletFilter.java:138) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637) at org.jenkinsci.plugins.saml.SamlCrumbExclusion.process(SamlCrumbExclusion.java:28) at hudson.security.csrf.CrumbFilter.doFilter(CrumbFilter.java:59) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637) at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:84) at hudson.security.UnwrapSecurityExceptionFilter.doFilter(UnwrapSecurityExceptionFilter.java:51) at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87) at jenkins.security.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:117) at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87) at org.acegisecurity.providers.anonymous.AnonymousProcessingFilter.doFilter(AnonymousProcessingFilter.java:125) at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87) at org.acegisecurity.ui.rememberme.RememberMeProcessingFilter.doFilter(RememberMeProcessingFilter.java:135) at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87) at org.acegisecurity.ui.AbstractProcessingFilter.doFilter(AbstractProcessingFilter.java:271) at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87) at jenkins.security.BasicHeaderProcessor.doFilter(BasicHeaderProcessor.java:93) at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87) at org.acegisecurity.context.HttpSessionContextIntegrationFilter.doFilter(HttpSessionContextIntegrationFilter.java:249) at hudson.security.HttpSessionContextIntegrationFilter2.doFilter(HttpSessionContextIntegrationFilter2.java:67) at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87) at hudson.security.ChainedServletFilter.doFilter(ChainedServletFilter.java:90) at hudson.security.HudsonFilter.doFilter(HudsonFilter.java:171) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637) at org.kohsuke.stapler.compression.CompressionFilter.doFilter(CompressionFilter.java:49) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637) at hudson.util.CharacterEncodingFilter.doFilter(CharacterEncodingFilter.java:82) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637) at org.kohsuke.stapler.DiagnosticThreadNameFilter.doFilter(DiagnosticThreadNameFilter.java:30) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637) at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:533) at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:524) at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132) at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:190) at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1595) at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:188) at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1253) at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:168) at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:473) at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1564) at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:166) at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1155) at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132) at org.eclipse.jetty.server.Server.handle(Server.java:564) at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:317) at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:251) at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:279) at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:110) at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:124) at org.eclipse.jetty.util.thread.Invocable.invokePreferred(Invocable.java:128) at org.eclipse.jetty.util.thread.Invocable$InvocableExecutor.invoke(Invocable.java:222) at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:294) at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:199) at winstone.BoundedExecutorService$1.run(BoundedExecutorService.java:77) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748)

     

    Please help.

     

    Thanks,

    Vipin

     

     

  14. Hi

    I want to config jenkins with ADFS, according to Example of configuration for ADFS 

    But words on all images (png) are almosts unreadable . 

    For example 

    So can you try to upload some readable images...  Thank you.

    1. I know it, they are old captures and I do not have the original ones.

      1. oh... without these images and texts, it's really difficult to me to configure ADFS with SAML on jenkins.

        I googled "Jenkins SAML ADFS" and other relative keywords, but find nothing useful....

  15. Hello,

     

    How can I remove the XML Declaration from the <localhost>/securityRealm/metadata? Our configuration can't accept xml files with the declaration in it.

    Thank you in advance.

  16. Hi all, we're having an issue with the plugin getting stuck in an endless redirect loop between Jenkins and Okta authentication.  It seems it happens 24 hours after a successful login, the next time you visit Jenkins it redirects to Okta which must be seeing that you checked the box "Do not challenge me on this device for the next 24 hours" so Okta thinks you are already logged in, it redirects back to Jenkins and the loop continues.  The only way we are able to log in is if we clear all cookies for both the Jenkins server and Okta. I created a short screen capture to show how this is happening:

    Does anyone have any ideas on how we can fix this?

    Thank you!!

  17. Shawn Woodford Even i am facing the same issue it is looping continues when log in while initial setup,i am passing the configs as

    SP Entity ID - https://JENKINS_URL:8080/securityRealm/finishLogin

    can you please let me know what we need to give for below configs,

    Username Attribute -

    Group Attribute -

    2) Do we need to enable the Encryption Configuration

    3) Authorization - Role based Strategy