Giter Site home page Giter Site logo

jenkinsci / oic-auth-plugin Goto Github PK

View Code? Open in Web Editor NEW
68.0 6.0 83.0 489 KB

A Jenkins plugin which lets you login to Jenkins using your own, self-hosted or public openid connect server.

Home Page: https://plugins.jenkins.io/oic-auth

License: MIT License

Java 95.61% HTML 4.39%
jenkins-plugin openid-connect authentication jenkins-security-scan-enabled

oic-auth-plugin's Introduction

oic-auth

A Jenkins plugin which lets you login to Jenkins using your own, self-hosted or public openid connect server.

Plugin Version Change Log Install Number MIT license Build Status Contributors Crowdin codecov

OpenID connect

Table of content

User guide

OpenID Connect is an authentication and authorization protocol that allow users to use single sign-on (SSO) to access an application (Jenkins in this case) using Identity Providers. In practice, with this plugin, Jenkins administrators can configure a provider which will authenticate users, provide basic information (email, username, groups) and let Jenkins grant rights accordingly.

After installing the plugin, the Jenkins administrator can choose "OpenID Connect" as Security Realm. The configuration involves the configuration of the provider and the related authorisation strategy.

Configurations for specific providers are documented:

Installation

OpenID Connect Authentication plugin is installed as other plugins:

In either case, choosing the plugin as Security Realm means that other authentication methods (Jenkins Database, LDAP, ...) will no longer be available and any misconfiguration or service availability issue will lock out the users. An escape hatch can be activated at configuration time to define a admin credential which can be used to recover access to Jenkins.

Configuration quickstart

Configuration of this plugin takes a bit of effort as it requires some knowledge of the openid connect standard as well as the non-standard configuration of the various identity providers out there. Should you configure this plugin against a identity provider then please share your experiences and found caveats through a blog post or by adding it to the documentation.

In a nutshell, the configuration is done in three steps:

  1. Register Jenkins as an OIDC client in your provide. You will need these details:
    • Login Redirect URI: ${JENKINS_ROOT_URL}/securityRealm/finishLogin
    • Logout Redirect URI: ${JENKINS_ROOT_URL}/OicLogout
    • scope: openid profile email
    • Grant Type: authorization_code
    • Response Types: code, token, id_token
  2. Generate Client ID and secret which are needed in plugin configuration
  3. Configure plugin with providers endpoints, security features and specific configuration.
    Normally, providers expose .well-known/openid-configuration which has all the details client need to know.

Detailed instructions for Generic OpenID Connect configuration are provided in the documentation. Some HOWTO are provided for the various aspects of the configuration.

See the following screenshot utilizing the google well known endpoint for a minimal configuration example: 

global-config

All of the fields can be configured as a JMES Path specification. Most of the time, the name of the field in the idtoken or userinfo is enough.

Interacting with Jenkins as a non front-end user

TLDR: use an API token instead as described here:  Authenticating scripted clients

Using basic auth for authentication won't work. This is because jenkins has no knowledge of the password due to the way openid connect works: Identifying a user is a three way interaction between the user, Jenkins and the openid provider.

The plugin asks the configured openid provider to confirm the identity of the user is and does this in a way that both Jenkins and the provider are 'talking' about the same user. The openid connect provider will likely challenge the user to prove it's identity and might do this by requesting a username and password but this is entirely up to the provider. This part is between the user and the openid connect provider, Jenkins (using this plugin) delegates proving ones identity to the provider and will go with whatever conclusion the provider draws. This has the benefit that with openid connect the service your trying to access (in our case Jenkins) never sees a user password, so even if Jenkins is compromised an attacker can't intercept passwords or other secrets. Using basic auth would require one to send their password to Jenkins which would defeat this.

Scripted clients can still interact with Jenkins even when the openid connect plugin is active: they will have to use an API token.  Authenticating scripted clients describes how to obtain one. 

OpenID Connect Authentication plugin

This plugin relies on the users and people of goodwill to improve and make the plugin evolve in the most useful way. All feedbacks and help are welcome. We can provide help and support but it is limited to the fair use of volunteers' free time.

Open Tickets (bugs and feature requests)

GitHub issues is our main communication channel for issues and feature request. We will look at issues entered through Jenkins Jira but the response time may currently be spotty at best.

Before adding an issue, please search for any relevant entry in the FAQ or if the same issue has already be reported and avoid duplicating it. If it is a new issue and it not purely related to your environment, please provide relevant information (such as the version of Jenkins and the plugin).

If an issue or a feature request is unclear, it will be tagged with Need more info label. Without answer after a month, the issue will be closed.

Changelog

Changelog file has been removed and CHANGELOG content can be review in the GitHub release panel of the plugin's repository. They also available in the Jenkins plugin panel.

Contributing

Contributions are welcome, we are looking for:

  • developers to implement the features, improve the code and whatever hackers do for a living
  • anybody wanting to help sorting the issues, improve, translate document, participate in pull request review or test before release
  • just anybody who wants to drop by and take an interest

Please refer to the separate CONTRIBUTING document for details on how to proceed!

oic-auth-plugin's People

Contributors

agentgonzo avatar bsmoyers avatar crowdin-bot avatar daniel-beck-bot avatar dependabot[bot] avatar driesverachtert avatar fajran avatar halftan avatar jglick avatar jilyaluk avatar jlamande avatar jovandeginste avatar krezovic avatar linuxsuren avatar michael-doubez avatar mjmbischoff avatar nickpetrovic avatar olamy avatar pdaw avatar sboschman avatar siepkes avatar skiepp avatar spirius avatar timja avatar tumbl3w33d avatar twz123 avatar vlatombe avatar wadeck avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

oic-auth-plugin's Issues

Exception on Group

Can't find a way to send groups :

{
  "error" : "Internal Error"
}
    at com.google.api.client.auth.oauth2.TokenResponseException.from(TokenResponseException.java:105)
    at com.google.api.client.auth.oauth2.TokenRequest.executeUnparsed(TokenRequest.java:287)
    at com.google.api.client.auth.openidconnect.IdTokenResponse.execute(IdTokenResponse.java:120)
    at org.jenkinsci.plugins.oic.OicSecurityRealm$3.onSuccess(OicSecurityRealm.java:328)...

Error with the JSON parser ? Or the cast on line 473 (v4) ? Or from our part ?

! Issues with version 1.6 of the plugin

As indicated in #46 the spec seems to suggest that the scope shouldn't be send when performing an token request as such we won't be sending the scope anymore and thereby fixing the issue with some openid providers that break on this.

As the inverse could also be true: providers no longer working I've created this issue so people can report issues here.

As the only change between 1.5 and 1.6 is not sending the scope it is safe to downgrade to 1.5 and respond to this issue. We will make it configurable in future releases should this be the case.

Value mapping from a nested field

Hi, I am trying to use Dex as OpenID Connect server with its LDAP backend. I want to get the username and looks like Dex puts the username value inside a second level field federated_claims -> user_id in the IdToken claims.

Looking at the oic-auth-plugin code, particularly OicSecurityRealm.java#L369, it seems that currently there is no way to retrieve value from nested fields.

I am thinking we can do a simple nested field lookup using a dot separated field names. So if the user entered federated_claims.user_id as field name, we will retrieve federated_claims value first and make sure it is a map. Then from that map, we continue to retrieve user_id. I understand this is very simple and will not handle cases like a field name that contains dots or retrieving value from arrays.

What do you think?

OIC user not able to make API calls

I am using Jenkins Login with Openid Connect (Amazon Cognito). I am able to use group-based authorization. I can see my groups in Granted Authorities: authenticated,

But when I try making API call, it gives me a "403" error saying "Missing overall read permissions".

I am using API token created using /configure/me

It is only allowing in case I give "Read" access to the anonymous group in Jenkins, which I couldn't give in my production environment.

Issue::

Jenkins is not able to read neither SSO users authorized in groups nor in the authenticated group.
Can't we use SSO users to make API calls

NullpointerException on Logout when endSession endpoint is absent

javax.servlet.ServletException: java.lang.NullPointerException
	at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:795)
	at org.kohsuke.stapler.Stapler.invoke(Stapler.java:875)
	at org.kohsuke.stapler.Stapler.invoke(Stapler.java:648)
	at org.kohsuke.stapler.Stapler.service(Stapler.java:237)
	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:96)
	at hudson.util.PluginServletFilter.doFilter(PluginServletFilter.java:88)
	at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
	at hudson.security.csrf.CrumbFilter.doFilter(CrumbFilter.java:48)
	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:142)
	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:86)
	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:164)
	at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
	at org.kohsuke.stapler.compression.CompressionFilter.doFilter(CompressionFilter.java:46)
	at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
	at hudson.util.CharacterEncodingFilter.doFilter(CharacterEncodingFilter.java:81)
	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.ContextHandlerCollection.handle(ContextHandlerCollection.java:215)
	at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:110)
	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 org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)
	at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555)
	at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NullPointerException
	at java.lang.StringBuilder.<init>(StringBuilder.java:112)
	at org.jenkinsci.plugins.oic.OicSecurityRealm.getPostLogOutUrl(OicSecurityRealm.java:583)
	at hudson.security.SecurityRealm.doLogout(SecurityRealm.java:303)
	at org.jenkinsci.plugins.oic.OicSecurityRealm.doLogout(OicSecurityRealm.java:577)
	at jenkins.model.Jenkins.doLogout(Jenkins.java:3168)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	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:745)
	... 53 more

Unable to logout when using OpenAM as idP

OpenAM advertised logout url:

https://idp.example.com/openam/oauth2/connect/endSession

Result redirect happening when trying to logout from Jenkins:

https://idp.example.com/openam/oauth2/connect/endSession/?id_token_hint=REDACTED&state=REDACTED&post_logout_redirect_uri=https://jenkins.example.com/

While OpenAM expects redirect to endpoint without trailing slash:

https://idp.example.com/openam/oauth2/connect/endSession?id_token_hint=REDACTED&state=REDACTED&post_logout_redirect_uri=https://jenkins.example.com/

So, without patching the code I'm currently unable to satisfy OpenAM expectations as it rightfully distinguishes those two endpoints and returns 404 on one with trailing slash.

This slash seems to be appended here, but removing it alltogether can possibly break existing installations, that's why I'm starting this discussion instead of prosing trivial PR.

Support for CSRF during emergency login

If CSRF is enabled, the emergency login (escape hatch) is not anymore working. I'm always getting the error message "No valid crumb was included in the request" when I try to login.
Is it possible to add support for CSRF in case the escape hatch is needed?

Look for groups in UserInfo

determineAuthorities only looks for the groups someone is part of in the response from the authorization endpoint.
It should look in the user info as well (if available).

Set the id-token as Env variable

I need the received id-token set as an Env variable or to be able to get it in some other way from my pipelines, as It would be required when using Helm & Kubernetes from scripts, so that these invocations happens on behalf of the actual logged in user.
All our jobs/pipelines runs in contianers on Kubernetes, so it would only be a matter of either create kubeconfig file from the token (and the rest of the information), and then helm & kubectl executions happens from the correct logged in use, providing somewhat of an SSO experience. And not as the Jenkins user.

Cannot Save Security Settings with version 1.1

I updated the oic-auth plugin to version 1.1 today and now I cannot save the settings to config.xml. Below is the stack trace I get.

Mar 02, 2018 6:40:15 PM hudson.init.impl.InstallUncaughtExceptionHandler lambda$init$0
WARNING: null
java.io.IOException: java.lang.RuntimeException: Failed to serialize jenkins.model.Jenkins#securityRealm for class hudson.model.Hudson
at hudson.XmlFile.write(XmlFile.java:200)
at jenkins.model.Jenkins.save(Jenkins.java:3168)
at hudson.BulkChange.commit(BulkChange.java:98)
at hudson.security.GlobalSecurityConfiguration.doConfigure(GlobalSecurityConfiguration.java:106)
at java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:627)
at org.kohsuke.stapler.Function$MethodFunction.invoke(Function.java:343)
at org.kohsuke.stapler.interceptor.RequirePOST$Processor.invoke(RequirePOST.java:77)
at org.kohsuke.stapler.PreInvokeInterceptedFunction.invoke(PreInvokeInterceptedFunction.java:26)
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)
at org.kohsuke.stapler.Stapler.invoke(Stapler.java:845)
at org.kohsuke.stapler.MetaClass$10.dispatch(MetaClass.java:374)
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:154)
at org.jenkinsci.plugins.ssegateway.Endpoint$SSEListenChannelFilter.doFilter(Endpoint.java:225)
at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:151)
at io.jenkins.blueocean.auth.jwt.impl.JwtAuthenticationFilter.doFilter(JwtAuthenticationFilter.java:61)
at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:151)
at io.jenkins.blueocean.ResourceCacheControl.doFilter(ResourceCacheControl.java:134)
at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:151)
at jenkins.metrics.impl.MetricsFilter.doFilter(MetricsFilter.java:125)
at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:151)
at hudson.util.PluginServletFilter.doFilter(PluginServletFilter.java:157)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637)
at hudson.security.csrf.CrumbFilter.doFilter(CrumbFilter.java:99)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637)
at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:84)
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.RequestLogHandler.handle(RequestLogHandler.java:56)
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)
Caused by: java.lang.RuntimeException: Failed to serialize jenkins.model.Jenkins#securityRealm for class hudson.model.Hudson
at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:256)
at hudson.util.RobustReflectionConverter$2.visit(RobustReflectionConverter.java:224)
at com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider.visitSerializableFields(PureJavaReflectionProvider.java:138)
at hudson.util.RobustReflectionConverter.doMarshal(RobustReflectionConverter.java:209)
at hudson.util.RobustReflectionConverter.marshal(RobustReflectionConverter.java:150)
at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:69)
at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:58)
at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:43)
at com.thoughtworks.xstream.core.TreeMarshaller.start(TreeMarshaller.java:82)
at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.marshal(AbstractTreeMarshallingStrategy.java:37)
at com.thoughtworks.xstream.XStream.marshal(XStream.java:1026)
at com.thoughtworks.xstream.XStream.marshal(XStream.java:1015)
at com.thoughtworks.xstream.XStream.toXML(XStream.java:988)
at hudson.XmlFile.write(XmlFile.java:193)
... 74 more
Caused by: java.lang.RuntimeException: Failed to serialize org.jenkinsci.plugins.oic.OicSecurityRealm#httpTransport for class org.jenkinsci.plugins.oic.OicSecurityRealm
at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:256)
at hudson.util.RobustReflectionConverter$2.visit(RobustReflectionConverter.java:224)
at com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider.visitSerializableFields(PureJavaReflectionProvider.java:138)
at hudson.util.RobustReflectionConverter.doMarshal(RobustReflectionConverter.java:209)
at hudson.util.RobustReflectionConverter.marshal(RobustReflectionConverter.java:150)
at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:69)
at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:58)
at com.thoughtworks.xstream.core.AbstractReferenceMarshaller$1.convertAnother(AbstractReferenceMarshaller.java:84)
at hudson.util.RobustReflectionConverter.marshallField(RobustReflectionConverter.java:265)
at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:252)
... 87 more
Caused by: java.lang.UnsupportedOperationException: Refusing to marshal com.google.api.client.http.javanet.NetHttpTransport for security reasons; see https://jenkins.io/redirect/class-filter/
at hudson.util.XStream2$BlacklistedTypesConverter.marshal(XStream2.java:543)
at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:69)
at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:58)
at com.thoughtworks.xstream.core.AbstractReferenceMarshaller$1.convertAnother(AbstractReferenceMarshaller.java:84)
at hudson.util.RobustReflectionConverter.marshallField(RobustReflectionConverter.java:265)
at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:252)
... 96 more

Few Issues with Keycloak

Environment

Problem

Thanks for the plugin. I am able to log in using my user in Keycloak but have few issues.

  • I am trying to save preferrred_username in User name field, it allows me to save, but when I re-open it, somehow sub gets populated.

2017-07-14_22-58-23

  • Unable to log out. When hit 'log out', page refreshes and I get redirected to home page but doesn't get logged out

  • Username is not populated in top right, instead, the long ID of Keycloak is being displayed
    2017-07-14_23-03-05

Probable Solution (to few of above)

This link has few other options like UserInfo server url and Logout url
Somehow, I do not have these options. May be these were in older versions and were removed in v1.0?

Logout not logging out of OpenId Provider

The logout via the Jenkins Logout-Funcationality just logs the User out of Jenkins. To provide more usability, the user should also be logged out of the SSO Server.

The end session URL send to provider is incorrect

The correct end session url is http://{host} /connect/endsession, but for the plugin, when logout, the url send to provider is http://{host} /connect/endsession/?id_token_hint={value}&state={value}&post_logout_redirect_uri={value},
The slash before question mark is not needed.
Please see the screenshot as below

endseesion

by the way, for the configuration, there is no slash at the end
333

java.net.ConnectException: Connection refused (Connection refused) - Connection with local keycloak

Environment:
Jenkins: 2.124
Keycloak: 3.4.0.Final
Plugin Version: 1.4

Behind haproxy.
JENKINS_OPTS=--prefix=/jenkins --httpPort=-1 --httpsPort=8083 --httpsKeyStore=/usr/share/jenkins/jenkins_keystore.jks --httpsKeyStorePassword=REDACTED

Settings for plugin

selection_101

Settings for keycloak CI realm:

selection_099

Well-known at keycloak

{ "issuer": "https://localhost/auth/realms/ci", "authorization_endpoint": "https://localhost/auth/realms/ci/protocol/openid-connect/auth", "token_endpoint": "https://localhost/auth/realms/ci/protocol/openid-connect/token", "token_introspection_endpoint": "https://localhost/auth/realms/ci/protocol/openid-connect/token/introspect", "userinfo_endpoint": "https://localhost/auth/realms/ci/protocol/openid-connect/userinfo", "end_session_endpoint": "https://localhost/auth/realms/ci/protocol/openid-connect/logout", "jwks_uri": "https://localhost/auth/realms/ci/protocol/openid-connect/certs", "check_session_iframe": "https://localhost/auth/realms/ci/protocol/openid-connect/login-status-iframe.html", "grant_types_supported": ["authorization_code", "implicit", "refresh_token", "password", "client_credentials"], "response_types_supported": ["code", "none", "id_token", "token", "id_token token", "code id_token", "code token", "code id_token token"], "subject_types_supported": ["public", "pairwise"], "id_token_signing_alg_values_supported": ["RS256"], "userinfo_signing_alg_values_supported": ["RS256"], "request_object_signing_alg_values_supported": ["none", "RS256"], "response_modes_supported": ["query", "fragment", "form_post"], "registration_endpoint": "https://localhost/auth/realms/ci/clients-registrations/openid-connect", "token_endpoint_auth_methods_supported": ["private_key_jwt", "client_secret_basic", "client_secret_post"], "token_endpoint_auth_signing_alg_values_supported": ["RS256"], "claims_supported": ["sub", "iss", "auth_time", "name", "given_name", "family_name", "preferred_username", "email"], "claim_types_supported": ["normal"], "claims_parameter_supported": false, "scopes_supported": ["openid", "offline_access"], "request_parameter_supported": true, "request_uri_parameter_supported": true }

Flow:
https://localhost/jenkins -> https://localhost/auth/realms/ci/jenkins etc. -> autentication -> Exception at Jenkins

Result:
Stacktrace
java.net.ConnectException: Connection refused (Connection refused) at java.net.PlainSocketImpl.socketConnect(Native Method) at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350) at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206) at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) at java.net.Socket.connect(Socket.java:589) at sun.security.ssl.SSLSocketImpl.connect(SSLSocketImpl.java:673) at sun.net.NetworkClient.doConnect(NetworkClient.java:175) at sun.net.www.http.HttpClient.openServer(HttpClient.java:463) at sun.net.www.http.HttpClient.openServer(HttpClient.java:558) at sun.net.www.protocol.https.HttpsClient.<init>(HttpsClient.java:264) at sun.net.www.protocol.https.HttpsClient.New(HttpsClient.java:367) at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.getNewHttpClient(AbstractDelegateHttpsURLConnection.java:191) at sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1156) at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1050) at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:177) at sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(HttpURLConnection.java:1334) at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1309) at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:259) at com.google.api.client.http.javanet.NetHttpRequest.execute(NetHttpRequest.java:77) at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:981) at com.google.api.client.auth.oauth2.TokenRequest.executeUnparsed(TokenRequest.java:283) at com.google.api.client.auth.openidconnect.IdTokenResponse.execute(IdTokenResponse.java:120) at org.jenkinsci.plugins.oic.OicSecurityRealm$3.onSuccess(OicSecurityRealm.java:328) at org.jenkinsci.plugins.oic.OicSession.doFinishLogin(OicSession.java:108) at org.jenkinsci.plugins.oic.OicSecurityRealm.doFinishLogin(OicSecurityRealm.java:564) 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) 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:860) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1650) at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:154) at org.jenkinsci.plugins.ssegateway.Endpoint$SSEListenChannelFilter.doFilter(Endpoint.java:225) at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:151) at io.jenkins.blueocean.ResourceCacheControl.doFilter(ResourceCacheControl.java:134) at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:151) at io.jenkins.blueocean.auth.jwt.impl.JwtAuthenticationFilter.doFilter(JwtAuthenticationFilter.java:61) at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:151) at hudson.util.PluginServletFilter.doFilter(PluginServletFilter.java:157) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637) at hudson.security.csrf.CrumbFilter.doFilter(CrumbFilter.java:64) 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:530) at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:347) at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:256) at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:279) at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:102) at org.eclipse.jetty.io.ssl.SslConnection.onFillable(SslConnection.java:289) at org.eclipse.jetty.io.ssl.SslConnection$3.succeeded(SslConnection.java:149) at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:102) at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:124) at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:247) at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.produce(EatWhatYouKill.java:140) at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:131) at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:382) 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)

java.net.ConnectException: Connection refused (Connection refused)
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at sun.security.ssl.SSLSocketImpl.connect(SSLSocketImpl.java:673)
at sun.net.NetworkClient.doConnect(NetworkClient.java:175)
at sun.net.www.http.HttpClient.openServer(HttpClient.java:463)
at sun.net.www.http.HttpClient.openServer(HttpClient.java:558)
at sun.net.www.protocol.https.HttpsClient.(HttpsClient.java:264)
at sun.net.www.protocol.https.HttpsClient.New(HttpsClient.java:367)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.getNewHttpClient(AbstractDelegateHttpsURLConnection.java:191)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1156)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1050)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:177)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(HttpURLConnection.java:1334)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1309)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:259)
at com.google.api.client.http.javanet.NetHttpRequest.execute(NetHttpRequest.java:77)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:981)
at com.google.api.client.auth.oauth2.TokenRequest.executeUnparsed(TokenRequest.java:283)
at com.google.api.client.auth.openidconnect.IdTokenResponse.execute(IdTokenResponse.java:120)
at org.jenkinsci.plugins.oic.OicSecurityRealm$3.onSuccess(OicSecurityRealm.java:328)
at org.jenkinsci.plugins.oic.OicSession.doFinishLogin(OicSession.java:108)
at org.jenkinsci.plugins.oic.OicSecurityRealm.doFinishLogin(OicSecurityRealm.java:564)
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)
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:860)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1650)
at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:154)
at org.jenkinsci.plugins.ssegateway.Endpoint$SSEListenChannelFilter.doFilter(Endpoint.java:225)
at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:151)
at io.jenkins.blueocean.ResourceCacheControl.doFilter(ResourceCacheControl.java:134)
at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:151)
at io.jenkins.blueocean.auth.jwt.impl.JwtAuthenticationFilter.doFilter(JwtAuthenticationFilter.java:61)
at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:151)
at hudson.util.PluginServletFilter.doFilter(PluginServletFilter.java:157)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637)
at hudson.security.csrf.CrumbFilter.doFilter(CrumbFilter.java:64)
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:530)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:347)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:256)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:279)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:102)
at org.eclipse.jetty.io.ssl.SslConnection.onFillable(SslConnection.java:289)
at org.eclipse.jetty.io.ssl.SslConnection$3.succeeded(SslConnection.java:149)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:102)
at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:124)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:247)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.produce(EatWhatYouKill.java:140)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:131)
at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:382)
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)

Besides this I must add, this error might be jenkins (version maybe) related and not the plugin, as by using Keycloak auth plugin, I get an endless loop while connecting.

I've created a scenario without Haproxy, with equal results.

Improve the description for configuration-as-code (casc) plugin: logoutFromOpenidProvider not marked as required

In the reference page of CasC the logoutFromOpenidProvider key is not described as required. But not setting that boolean leads to Jenkins not being reachable because of a NPE, see log below, last line.

Since we're building Jenkins with a custom set of plugins, creating a docker image and deploying it to multiple k8s, we're heavily relying on the CasC plugin. Since the option to Logout of from the OpenID Provider is set to false by default when installing the plugin via the UI, I'd suggest to change the option for CasC to false by default as well.
The other option of course is to just fix the description for CasC and add "Required".

... Caused by: io.jenkins.plugins.casc.ConfiguratorException: oic: Failed to construct instance of class org.jenkinsci.plugins.oic.OicSecurityRealm. Constructor: public org.jenkinsci.plugins.oic.OicSecurityRealm(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,boolean,java.lang.Boolean,java.lang.String,java.lang.String,boolean,java.lang.String,java.lang.String,java.lang.String,java.lang.String) throws java.io.IOException. Arguments: [java.lang.String, java.lang.String, null, java.lang.String, java.lang.String, java.lang.String, null, null, null, null, null, java.lang.String, null, java.lang.Boolean, null, java.lang.String, null, java.lang.Boolean, null, null, null, null] at io.jenkins.plugins.casc.impl.configurators.DataBoundConfigurator.tryConstructor(DataBoundConfigurator.java:149) at io.jenkins.plugins.casc.impl.configurators.DataBoundConfigurator.instance(DataBoundConfigurator.java:73) at io.jenkins.plugins.casc.BaseConfigurator.configure(BaseConfigurator.java:262) at io.jenkins.plugins.casc.impl.configurators.DataBoundConfigurator.configure(DataBoundConfigurator.java:79) at io.jenkins.plugins.casc.impl.configurators.HeteroDescribableConfigurator.lambda$doConfigure$16668e2$1(HeteroDescribableConfigurator.java:225) at io.vavr.CheckedFunction0.lambda$unchecked$52349c75$1(CheckedFunction0.java:201) at io.jenkins.plugins.casc.impl.configurators.HeteroDescribableConfigurator.doConfigure(HeteroDescribableConfigurator.java:225) at io.jenkins.plugins.casc.impl.configurators.HeteroDescribableConfigurator.lambda$null$2(HeteroDescribableConfigurator.java:81) at io.vavr.control.Option.map(Option.java:373) at io.jenkins.plugins.casc.impl.configurators.HeteroDescribableConfigurator.lambda$configure$3(HeteroDescribableConfigurator.java:81) at io.vavr.Tuple2.apply(Tuple2.java:239) at io.jenkins.plugins.casc.impl.configurators.HeteroDescribableConfigurator.configure(HeteroDescribableConfigurator.java:78) at io.jenkins.plugins.casc.impl.configurators.HeteroDescribableConfigurator.check(HeteroDescribableConfigurator.java:87) at io.jenkins.plugins.casc.impl.configurators.HeteroDescribableConfigurator.check(HeteroDescribableConfigurator.java:50) at io.jenkins.plugins.casc.BaseConfigurator.configure(BaseConfigurator.java:347) at io.jenkins.plugins.casc.BaseConfigurator.check(BaseConfigurator.java:282) at io.jenkins.plugins.casc.ConfigurationAsCode.lambda$checkWith$6(ConfigurationAsCode.java:644) at io.jenkins.plugins.casc.ConfigurationAsCode.invokeWith(ConfigurationAsCode.java:606) ... 18 more Caused by: java.lang.reflect.InvocationTargetException at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at io.jenkins.plugins.casc.impl.configurators.DataBoundConfigurator.tryConstructor(DataBoundConfigurator.java:141) ... 35 more Caused by: java.lang.NullPointerException at org.jenkinsci.plugins.oic.OicSecurityRealm.<init>(OicSecurityRealm.java:154) ... 40 more

Null Pointer exception - help needed

I am getting a null pointer exception after configuring the plugin in jenkins. This is running on windows server.

Following fields have the values. Can you please help me understand what I am doing wrong here?

Appreciate your time and help in advance.

clientid:
Tokenserverurl
authorization server url

FullName fielld name
email field name
Scopes openid

Given below is my stack trace:
ava.lang.NullPointerException
at org.jenkinsci.plugins.oic.OicSecurityRealm.doFinishLogin(OicSecurityRealm.java:564)
at java.lang.invoke.MethodHandle.invokeWithArguments(Unknown Source)
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:734)
Caused: javax.servlet.ServletException
at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:784)
at org.kohsuke.stapler.Stapler.invoke(Stapler.java:864)
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:734)
at org.kohsuke.stapler.Stapler.invoke(Stapler.java:864)
at org.kohsuke.stapler.Stapler.invoke(Stapler.java:668)
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:865)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1655)
at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:154)
at hudson.util.PluginServletFilter.doFilter(PluginServletFilter.java:157)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1642)
at hudson.security.csrf.CrumbFilter.doFilter(CrumbFilter.java:105)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1642)
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:1642)
at org.kohsuke.stapler.compression.CompressionFilter.doFilter(CompressionFilter.java:49)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1642)
at hudson.util.CharacterEncodingFilter.doFilter(CharacterEncodingFilter.java:82)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1642)
at org.kohsuke.stapler.DiagnosticThreadNameFilter.doFilter(DiagnosticThreadNameFilter.java:30)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1642)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:533)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:146)
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:257)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1595)
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:255)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1317)
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:203)
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:201)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1219)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:144)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
at org.eclipse.jetty.server.Server.handle(Server.java:531)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:352)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:260)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:281)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:102)
at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:118)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:333)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:310)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:168)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:126)
at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:366)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:762)
at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:680)
at java.lang.Thread.run(Unknown Source)

Exception with Azure authority

I configured the plugin to use with my Azure authority and got he below stack trace - my naive guess is that the code is assuming there is a field that only Google returns....:

This is our end-point configuration (available at https://sts.windows.net/226151a9-bcce-47cc-b359-54b1c9041a44/.well-known/openid-configuration)

{
   "frontchannel_logout_supported" : true,
   "claims_supported" : [
      "sub",
      "iss",
      "cloud_instance_name",
      "aud",
      "exp",
      "iat",
      "auth_time",
      "acr",
      "amr",
      "nonce",
      "email",
      "given_name",
      "family_name",
      "nickname"
   ],
   "jwks_uri" : "https://login.windows.net/common/discovery/keys",
   "microsoft_multi_refresh_token" : true,
   "token_endpoint" : "https://login.windows.net/226151a9-bcce-47cc-b359-54b1c9041a44/oauth2/token",
   "id_token_signing_alg_values_supported" : [
      "RS256"
   ],
   "cloud_instance_name" : "microsoftonline.com",
   "authorization_endpoint" : "https://login.windows.net/226151a9-bcce-47cc-b359-54b1c9041a44/oauth2/authorize",
   "scopes_supported" : [
      "openid"
   ],
   "cloud_graph_host_name" : "graph.windows.net",
   "userinfo_endpoint" : "https://login.windows.net/226151a9-bcce-47cc-b359-54b1c9041a44/openid/userinfo",
   "issuer" : "https://sts.windows.net/226151a9-bcce-47cc-b359-54b1c9041a44/",
   "token_endpoint_auth_methods_supported" : [
      "client_secret_post",
      "private_key_jwt"
   ],
   "response_types_supported" : [
      "code",
      "id_token",
      "code id_token",
      "token id_token",
      "token"
   ],
   "http_logout_supported" : true,
   "subject_types_supported" : [
      "pairwise"
   ],
   "response_modes_supported" : [
      "query",
      "fragment",
      "form_post"
   ],
   "end_session_endpoint" : "https://login.windows.net/226151a9-bcce-47cc-b359-54b1c9041a44/oauth2/logout",
   "check_session_iframe" : "https://login.windows.net/226151a9-bcce-47cc-b359-54b1c9041a44/oauth2/checksession",
   "tenant_region_scope" : "NA"
}
Stack trace

javax.servlet.ServletException: java.lang.IllegalArgumentException: key expires_in
	at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:796)
	at org.kohsuke.stapler.Stapler.invoke(Stapler.java:876)
	at org.kohsuke.stapler.MetaClass$3.doDispatch(MetaClass.java:197)
	at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:58)
	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: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 com.smartcodeltd.jenkinsci.plugin.assetbundler.filters.LessCSS.doFilter(LessCSS.java:46)
	at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:132)
	at hudson.plugins.greenballs.GreenBallFilter.doFilter(GreenBallFilter.java:59)
	at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:132)
	at hudson.util.PluginServletFilter.doFilter(PluginServletFilter.java:126)
	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: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: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(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.IllegalArgumentException: key expires_in
	at com.google.api.client.json.JsonParser.parseValue(JsonParser.java:889)
	at com.google.api.client.json.JsonParser.parse(JsonParser.java:382)
	at com.google.api.client.json.JsonParser.parse(JsonParser.java:355)
	at com.google.api.client.json.JsonObjectParser.parseAndClose(JsonObjectParser.java:87)
	at com.google.api.client.json.JsonObjectParser.parseAndClose(JsonObjectParser.java:81)
	at com.google.api.client.http.HttpResponse.parseAs(HttpResponse.java:459)
	at com.google.api.client.auth.openidconnect.IdTokenResponse.execute(IdTokenResponse.java:120)
	at org.jenkinsci.plugins.oic.OicSecurityRealm$2.onSuccess(OicSecurityRealm.java:200)
	at org.jenkinsci.plugins.oic.OicSession.doFinishLogin(OicSession.java:98)
	at org.jenkinsci.plugins.oic.OicSecurityRealm.doFinishLogin(OicSecurityRealm.java:294)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.kohsuke.stapler.Function$InstanceFunction.invoke(Function.java:335)
	at org.kohsuke.stapler.Function.bindAndInvoke(Function.java:175)
	at org.kohsuke.stapler.Function.bindAndInvokeAndServeResponse(Function.java:108)
	at org.kohsuke.stapler.MetaClass$1.doDispatch(MetaClass.java:124)
	at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:58)
	at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:746)
	... 62 more
Caused by: java.lang.IllegalArgumentException: key expires_in, field private java.lang.Long com.google.api.client.auth.oauth2.TokenResponse.expiresInSeconds
	at com.google.api.client.json.JsonParser.parseValue(JsonParser.java:889)
	at com.google.api.client.json.JsonParser.parse(JsonParser.java:472)
	at com.google.api.client.json.JsonParser.parseValue(JsonParser.java:781)
	... 81 more
Caused by: java.lang.IllegalArgumentException: number field formatted as a JSON string must use the @JsonString annotation
	at com.google.api.client.repackaged.com.google.common.base.Preconditions.checkArgument(Preconditions.java:125)
	at com.google.api.client.util.Preconditions.checkArgument(Preconditions.java:49)
	at com.google.api.client.json.JsonParser.parseValue(JsonParser.java:854)
	... 83 more

Failure to integrate with hydra

After configuring by looking at the urls provided by my hydra installation's well known configuration route, I am getting the following stack trace after login:

com.google.api.client.auth.oauth2.TokenResponseException: 400 Bad Request
{
  "error" : "invalid_request",
  "error_description" : "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed",
  "statusCode" : 400
}
	at com.google.api.client.auth.oauth2.TokenResponseException.from(TokenResponseException.java:105)
	at com.google.api.client.auth.oauth2.TokenRequest.executeUnparsed(TokenRequest.java:287)
	at com.google.api.client.auth.openidconnect.IdTokenResponse.execute(IdTokenResponse.java:120)
	at org.jenkinsci.plugins.oic.OicSecurityRealm$2.onSuccess(OicSecurityRealm.java:200)
	at org.jenkinsci.plugins.oic.OicSession.doFinishLogin(OicSession.java:98)
	at org.jenkinsci.plugins.oic.OicSecurityRealm.doFinishLogin(OicSecurityRealm.java:294)
	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)
	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 hudson.security.csrf.CrumbFilter.doFilter(CrumbFilter.java:86)
	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:142)
	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: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 winstone.BoundedExecutorService$1.run(BoundedExecutorService.java:77)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:748)

On the hydra server the following error is displayed:

time="2017-07-12T12:32:35-04:00" level=error msg="An error occurred" error="HTTP authorization header missing or invalid: The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed" 

The finishLogin url looks like:

$JENKINS_URL/securityRealm/finishLogin?code=FpE-33KHMULG7M0u3FOI3e8Tme8lT7JMi2ONY5dcZrs.0_KkgWN9Xk_ixatdhaN-MYqTOEBDovvQsom-PM3_t7w&scope=openid&state=ZjY1NjI1M2MtMDMwYS00

User name field value not being updated

When attempting to update the User name field in the Jenkins UI from sub to preferred_username, the value is not saved and remains at sub.
screen shot 2017-02-01 at 2 09 36 pm

I tracked this down to doCheckUserNameField method:

388         public FormValidation doCheckUserNameField(@QueryParameter String userNameField) {
389             if (userNameField == null || userNameField.trim().length() == 0) {
390                 return FormValidation.ok("Using 'sub'.");
391             }
392             return FormValidation.ok();
393         }

For some reason, userNameField is null rather than populated with the updated value.

If the config.xml is updated with

    <userNameField>sub</userNameField>
    <fullNameFieldName>name</fullNameFieldName>
    <scopes>openid email</scopes>
  </securityRealm>

to

    <userNameField>preferred_username</userNameField>
    <fullNameFieldName>name</fullNameFieldName>
    <scopes>openid email</scopes>
  </securityRealm>

it works fine. However, default values are obviously returned if you attempt to use the Jenkins UI to update the configuration.

Use Jenkins proxy information

My Jenkins instance is set up behind a proxy, but oic-auth-plugin does not seem to be using the proxy information. I'm getting a "cannot find host" error.

Exception message
java.net.UnknownHostException: 622eb47a.ngrok.io
	at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:184)
	at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
	at java.net.Socket.connect(Socket.java:589)
	at sun.security.ssl.SSLSocketImpl.connect(SSLSocketImpl.java:673)
	at sun.net.NetworkClient.doConnect(NetworkClient.java:175)
	at sun.net.www.http.HttpClient.openServer(HttpClient.java:463)
	at sun.net.www.http.HttpClient.openServer(HttpClient.java:558)
	at sun.net.www.protocol.https.HttpsClient.(HttpsClient.java:264)
	at sun.net.www.protocol.https.HttpsClient.New(HttpsClient.java:367)
	at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.getNewHttpClient(AbstractDelegateHttpsURLConnection.java:191)
	at sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1156)
	at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1050)
	at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:177)
	at sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(HttpURLConnection.java:1334)
	at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1309)
	at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:259)
	at com.google.api.client.http.javanet.NetHttpRequest.execute(NetHttpRequest.java:77)
	at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:981)
	at com.google.api.client.auth.oauth2.TokenRequest.executeUnparsed(TokenRequest.java:283)
	at com.google.api.client.auth.openidconnect.IdTokenResponse.execute(IdTokenResponse.java:120)
	at org.jenkinsci.plugins.oic.OicSecurityRealm$3.onSuccess(OicSecurityRealm.java:326)
	at org.jenkinsci.plugins.oic.OicSession.doFinishLogin(OicSession.java:108)
	at org.jenkinsci.plugins.oic.OicSecurityRealm.doFinishLogin(OicSecurityRealm.java:544)
	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)
	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:860)
	at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1650)
	at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:154)
	at hudson.util.PluginServletFilter.doFilter(PluginServletFilter.java:157)
	at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637)
	at hudson.security.csrf.CrumbFilter.doFilter(CrumbFilter.java:105)
	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:530)
	at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:347)
	at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:256)
	at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:279)
	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:102)
	at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:124)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:247)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.produce(EatWhatYouKill.java:140)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:131)
	at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:382)
	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)
/var/lib/jenkins/proxy.xml (redacted)
<?xml version='1.1' encoding='UTF-8'?>
<proxy>
  <name>myproxy.mycompany.example.com</name>
  <port>2011</port>
  <noProxyHost>*.mycompany.example.net</noProxyHost>
  <secretPassword>{AQAAABAAAAAQkGsWCLVacawMLOjdvU5oIngzhulRnZoC8cgTCBabrKs=}</secretPassword>
</proxy>

Pass arbitrary URL Params on all requests to OIDC Provider

Thanks for this plugin, I have a small feature-request which I believe we could contribute.

tl;dr: It would help us tremendously if we could pass arbitrary data as url params to the oidc token issuer. Reason fro that is a custom implementation.

How Keycloak does it

The OIDC provider we are using is custom-built at an enterprise company. It provides realms, similar to how keycloak provides realms. However, with keycloak, realms are a top-level namespace, like so:

Discovery: https://keycloak.local/auth/realms/master/.well-known/openid-configuration
Authorization: https://keycloak.local/auth/realms/master/protocol/openid-connect/auth

If you wanted to change the realm, you'd change it in the path and all URLs (including the discovery) are affected:

Discovery: https://keycloak.local/auth/realms/other-realm/.well-known/openid-configuration
Authorization: https://keycloak.local/auth/realms/other-realm/protocol/openid-connect/auth

How our custom solution does it

In our solution unfortunately all URLs only exist once, like so. This implies the "GLOBAL REALM".

Discovery: https://custom-oidc.local/.well-known/openid-configuration
Authorization: https://custom-oidc.local/openid-connect/auth

If we wanted to change the realm, the path of the urls wouldn't change, but an additional url param would be added, like so:

Discovery: https://custom-oidc.local/.well-known/openid-configuration
Authorization: https://custom-oidc.local/openid-connect/auth?realm_id=other-realm

What we need from oic-auth-plugin

Since the URL param is not part of the "base url", we cannot specify the realm at all. This currently leads us to seeing an error like this:
screen shot 2018-04-06 at 10 16 00

Changing the OIDC Provider is not that easy, unfortunately as this would be a breaking change for many users and the OIDC Provider is outside of our team's control. So for us it would help if we could just pass the realm_id as a url param.

So, we're suggesting an additional field in the config where users can specify arbitrary url params, which will be sent on every request.

Willingness to contribute

Our team doesn't have any experience writing Jenkins plugins, but this seems like a very minor change. We'd be willing to contribute that, if you believe such an optional field is compatible with your strategy for oic-auth-plugin. Please let us know, Thanks.

Unable access Jenkins API with basic auth

I am trying to access Jenkins API using user and password but I get an authentication error. Example with curl:

$ curl --user admin:admin https://jenkins/api/json?depth=1
...
<h2>HTTP ERROR 401</h2>
<p>Problem accessing /api/json. Reason:
<pre>    Invalid password/token for user: admin</pre></p>
...

However if I connect using the user API token everything works fine:
curl --user admin:<token> https://jenkins/api/json?depth=1

Is this behavior expected?

The plugin works fine through the web ui.

Compilation error

Hello,
While compiling the project I got the following error:

[ERROR] oic-auth-plugin/src/main/java/org/jenkinsci/plugins/oic/OicSecurityRealm.java:[474,70] incompatible types: java.lang.String cannot be converted to java.util.List<java.lang.String>

The line in error is List<String> groupNames = (List<String>) getField(idToken, groupsFieldName);

Use Dynamic Configuration of Endpoints

Some (or all?) OpenId Connect Provider contain a link, that delivers a JSON-File with all necessary Endpoints (https://OPENID_PROVIDER_URL/.well-known/openid-configuration).

This file looks like the following:

{
    "issuer": "https://OPENID_PROVIDER_URL",
    "authorization_endpoint": "https://OPENID_PROVIDER_URL/protocol/openid-connect/auth",
    "token_endpoint": "https://OPENID_PROVIDER_URL/protocol/openid-connect/token",
    "token_introspection_endpoint": "https://OPENID_PROVIDER_URL/protocol/openid-connect/token/introspect",
    "userinfo_endpoint": "https://OPENID_PROVIDER_URL/protocol/openid-connect/userinfo",
    "end_session_endpoint": "https://OPENID_PROVIDER_URL/protocol/openid-connect/logout",
    "jwks_uri": "https://OPENID_PROVIDER_URL/protocol/openid-connect/certs",
    "grant_types_supported": ["authorization_code", "implicit", "refresh_token", "password", "client_credentials"],
    "response_types_supported": ["code", "none", "id_token", "token", "id_token token", "code id_token", "code token", "code id_token token"],
    "subject_types_supported": ["public"],
    "id_token_signing_alg_values_supported": ["RS256"],
    "userinfo_signing_alg_values_supported": ["RS256"],
    "request_object_signing_alg_values_supported": ["none", "RS256"],
    "response_modes_supported": ["query", "fragment", "form_post"],
    "registration_endpoint": "https://OPENID_PROVIDER_URL/clients-registrations/openid-connect",
    "token_endpoint_auth_methods_supported": ["private_key_jwt", "client_secret_basic", "client_secret_post"],
    "token_endpoint_auth_signing_alg_values_supported": ["RS256"],
    "claims_supported": ["sub", "iss", "auth_time", "name", "given_name", "family_name", "preferred_username", "email"],
    "claim_types_supported": ["normal"],
    "claims_parameter_supported": false,
    "scopes_supported": ["openid", "offline_access"],
    "request_parameter_supported": true,
    "request_uri_parameter_supported": true
}

To make the configuration of the Plugin easier, this file should be used. The configuration could be re-read after a certain amount of time, in case the configuration changes on the server.

use relam_access.roles in Keycloak for groups field

Hi,

I am using
openid - keycloak - jenkins using this oic-auth plugin.

I want to use roles in keycloak rather than groups,
so in mapper, I want to create mapper type "User Realm Role" instead of "Group Membership" and use it.

I guess basic auth response is like

{
  "jti": "3a07bd76-8085-40c1-99c6-22b85f746814",
  "exp": 1557756222,
  "nbf": 0,
  "iat": 1557755922,
  "aud": "stage-jenkins",
  "sub": "f01ea816-c022-4460-af53-ec216fc898fe",
  "typ": "Bearer",
  "azp": "stage-jenkins",
  "auth_time": 0,
  "session_state": "db864fd9-f9e3-412a-9595-e6504346b682",
  "acr": "1",
  "realm_access": {
    "roles": [
      "offline_access",
      "uma_authorization",
      "role_created"
    ]
  },
  "scope": "roles profile email",
  "firstName": "first",
  "lastName": "last",
  "email_verified": false,
  "name": "given family",
  "preferred_username": "abc",
  "given_name": "given",
  "family_name": "family",
  "email": "[email protected]",
  "username": "abc"
}

In this case, I want to write realms_access.roles in Groups field name,
but now the plugin does not support this thing.

Feature to use jenkins credentials for client secret

Currently, we need to manually enter in the client secret. This doesn't allow for good jenkins config automation. I am using the jcac plugin and would love to be able to just pull the client secret in from the jenkins credentials/secrets.

When the user decline authorization, oic-auth prints unfriendly stack trace.

After declining authorization (error: access_denied), the end-user is redirected to http://***/securityRealm/finishLogin, which prints unfriendly stack trace information showing 'Error from provider: null .......'.
It will be better if there's a way to customize the error page. Or just redirect the end-user back to jenkins if access_denied occurrs.

Using role-based permissions

Hi,
how would I be possible to use the roles provided through my OIC provider along with the role-based auth in Jenkins?
Would be great to see a short documentation on that.
Cheers

Local Login

Even though an SSO-Server is configured, we would like to have a local login possibility. This means, that certain user (eg. admin) can still login to the jenkins if the SSO-Server is not available. This is just a fallback mechanism to avoid any problems with misconfiguration and/or SSO-Server outages.

Automatic re-login if you try to logout

If you configure your security Realm to use "Logged-in users can do anything" and disable anonymous read access, you effectively can't logout.
The following is what happens:

  1. Logout
  2. Jenkins detects that you're not logged in, so redirects you to /securityRealm/commenceLogin
  3. commenceLogin redirects you to your IdP
  4. You are already logged in with your IdP and have a cookie, so it automatically (if there is no approval screen or your preferences are cached - which is the standard case) redirects you back to /securityRealm/finishLogin
  5. You're logged in again.

Support of reverse proxy chain is missing : determineRedirectTarget

Given the documentation about Jenkins proxies :
https://support.cloudbees.com/hc/en-us/articles/360034638071-Reverse-Proxy-troubleshooting-guide#validatetheurlfromrequest

The correct method to use in order to determine the redirect target should be getRootUrlFromRequest
When no proxy is present or no special headers like X-Forwarded-... ones the value returned by getRootUrlFromRequest will be the same than getRootUrl.

target = Jenkins.getInstance().getRootUrl();

Consider making client secret optional

I've just started using this plugin on a Windows host running Jenkins in an AD integrated environment using AD FS and one thing I've noticed is that you don't have to have a client secret when you are using Windows integrated authentication with AD FS.

So you can just register jenkins with a client id in AD FS, then have the browser auth with windows integrated auth to adfs and redirect back to jenkins.

So in that case the client secret should be optional as sending one will break.
I've made a local patch not requiring client secret and it's working fine with AD FS.

To avoid NPE changed ClientParametersAuthentication to use Secret.toString instead of clientSecret.getPlainText()

Secret.toString(clientSecret)

and just returning FormValidation.ok() from doCheckClientSecret

Not sure how would this be the most user friendly with a pit of success?
Perhaps a checkbox for AD FS which would cause the client secret be optional ?
I haven't done Jenkins plugin development, so not sure what's the best practice here.

Thanks

Client secret as env variable not correctly substituted

When using CLIENT_SECRET as env variable it is not substituted correct.

When setting CLIENT_SECRET as env variable it is not correctly substituted in this code:

<securityRealm class="org.jenkinsci.plugins.oic.OicSecurityRealm" plugin="[email protected]">
              <clientId>jenkins</clientId>
              <clientSecret>${CLIENT_SECRET}</clientSecret>

The env variable shows a different value after running apply configuration

Reboot of Jenkins causes loss of OIDC configuration

When you reboot Jenkins through the API '/jenkins/restart' All the OIDC information is lost and the jenkins config.xml security realm is reset.

I would expect Jenkins to come back with previously configured SSO settings.

Latest OIDC plugin does not support digital signing of userinfo

Looking to implement OpenID connect client with jenkins to a OIDC IdP.

Security requirements are that the client must be able to digital sign userinfo endpoint of the OIDC provider, including its parsing and digital signature verification. It was noted that if Jenkins used any of the userinfo data for any authorization or security related decisions, the security would be compromised without the integrity of the Userinfo.

Please advise.

Thanks,

Access via API Token won't use group information

Albeit a user is in an administrative group, that user is not able to use the REST API via API Token and gets a 403 Forbidden response. The Web UI works as expected. Also the /api/json page when opening it up in the browser.

But when trying to use it with the API Token, the HTTP response body is telling that the user is missing the Overall/Read permission.

I reckon this might be connected to the fact that group information is ephemeral and just connected to the ID Token? This in turn renders API Tokens (and probably also SSH key based access) a bit useless, when user permissions are purely managed via groups.

If this is really the cause of the 403, would it maybe be feasible to add some caching to the ID Token group information? Maybe connected to the lifetime of the ID Token. That way, one could at least use the API Token for a certain amount of time.

$ http -a user:token https://jenkins/api/json
HTTP/1.1 403 Forbidden
Cache-Control: no-cache,no-store,must-revalidate
Content-Encoding: gzip
Content-Length: 1859
Content-Type: text/html;charset=utf-8
Date: Thu, 26 Jul 2018 10:08:24 GMT
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Server: Jetty(9.4.z-SNAPSHOT)
Set-Cookie: JSESSIONID.f9ff99b0=node0bhlg184ovzfu1vr9mglaapt5j37158.node0;Path=/;Secure;HttpOnly
X-Content-Type-Options: nosniff
X-Frame-Options: sameorigin
X-Hudson: 1.395
X-Hudson-CLI-Port: 50000
X-Hudson-Theme: default
X-Instance-Identity: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm7z6NAvVLlKLhOAs7tIckjHQyMXzWnoRx9fmfKeAB2aCZ61Xto7t91DTY4pMFMNDgFjVdTSKW3pmKGMflb/fgEnJRK/o2XO0IptQoDGWPn8pStZJlkEnweIN93k0epfXi8BL76V0RgkoshZmi8iC6ITm+Ta3N9AeUxSyzed9rwAoRrSecC2SwJa75DqxnXcauBGvFQYM71EOM2dVFtedDsxNr8qPVWofJxF/gcSZlUPj74HCySWd1b/WCiojDd23O0m/Y5MDX/8bT4r0hf0p4ytbo4erbEx1khYBWAHhnbBHyFpVeben0DEG2+3kjYWUX4SNyGh8EFeYvs54uElHEQIDAQAB
X-Jenkins: 2.121.2
X-Jenkins-CLI-Port: 50000
X-Jenkins-CLI2-Port: 50000
X-Jenkins-Session: c60d4fbc
X-Permission-Implied-By: hudson.security.Permission.GenericRead
X-Permission-Implied-By: hudson.model.Hudson.Administer
X-Required-Permission: hudson.model.Hudson.Read
X-You-Are-Authenticated-As: user
X-You-Are-In-Group-Disabled: JENKINS-39402: use -Dhudson.security.AccessDeniedException2.REPORT_GROUP_HEADERS=true or use /whoAmI to diagnose

Doesn't work after upgrade to Jenkins 2.150.2

After upgraded Jenkins from 2.150.1 to 2.150.2 (see Security Advisor https://jenkins.io/security/advisory/2019-01-16/), it's not possible to login into Jenkins anymore.

  1. Jenkins 2.150.1 is running with OpenID Connect Plugin 1.4 and connected to our Keycloak server
  2. Login redirects the users to the Keycloak login page and after authentication the users are redirected to Jenkins and authenticated in Jenkins with the correct user.
  3. Upgrade Jenkins to version 2.150.2
  4. Login redirects to the Keycloak login page and after authentication the users are redirected to Jenkins and again redirected to Keycloak. This loop will never end.
  5. Downgrade Jenkins to version 2.150.1 recovers the old behavior from 2.

Search Box does not return proper results, always sends to user profile page

Hi, we are currently using openid with keycloak and seeing some strange behavior with the Jenkins search box. Version 1.6 of oic-auth-plugin.

When initially typing in some text, the dropdown appears with valid results. If the user selects an entry and presses enter, it usually will go directly to the specified job.

However when just trying to search a string that doesn't exactly match a job name and press enter, we'd expect to be sent to the jenkins.local/search/?q=string page. However it sends us to the jenkins.local/user/string page, as if it were a "valid" user, it doesn't matter what the string is.

I have tested on Jenkins version 2.121.3 and latest 2.187.

Any ideas would be appreciated, Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.