diff --git a/README.md b/README.md index d5da0e9d..f012b5a1 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,9 @@ A Jenkins plugin which lets you login to Jenkins using your own, self-hosted or - [Open Tickets (bugs and feature requests)](#open-tickets-bugs-and-feature-requests) - [Changelog](#changelog) - [Contributing](#contributing) - +- [Documentation](docs/) + - [Configuration](docs/configuration/README.md) + - [FAQ](docs/FAQ.md) ## User guide @@ -40,6 +42,13 @@ After installing the plugin, the Jenkins administrator can choose The configuration involves the configuration of the provider and the related authorisation strategy. +Configurations for specific providers are documented: + +* [Google Provider](docs/configuration/GOOGLE.md) +* [Gitlab Provider](docs/configuration/GITLAB.md) +* [Azure AD (blog post)](http://www.epiclabs.io/configure-jenkins-use-azure-ad-authentication-openid-connect/) + + ### Installation OpenID Connect Authentication plugin is installed as other plugins: @@ -64,13 +73,21 @@ 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. -Also note that the spec describes a well known configuration location -which will also help discovering your settings -() - -From 1.5 and onward the well known configuration location may be used to -populate the configuration simplifying the configuration greatly. See -also the following screenshot utilizing the google well known endpoint +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 Redirec 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](docs/configuration/README.md) +configuration are provided in the documentation. + +See the following screenshot utilizing the google well known endpoint for a minimal configuration example:  ![global-config](/docs/images/global-config.png) @@ -78,22 +95,6 @@ for a minimal configuration example:  All of the fields can be configured as a [JMES Path](https://jmespath.org/) specification. Most of the time, the name of the field in the idtoken or userinfo is enough. -#### Using g-suite / google - -Obtain the client id and secret from the developer console: -https://console.cloud.google.com/apis/credentials by creating Oauth client id. - -Use those to fill the respective fields in the configuration of Jenkins. - -Choose automatic configuration: - -Well-known configuration: https://accounts.google.com/.well-known/openid-configuration - -see also:  - -#### Using the plugin with Azure AD - -See this blog post  ### Interacting with Jenkins as a non front-end user @@ -140,8 +141,9 @@ is our main communication channel for issues and feature request. We will look at issues entered through [Jenkins Jira](https://issues.jenkins.io/issues/?jql=project+%3D+JENKINS+AND+component+%3D+oic-auth-plugin) but the response time may currently be spotty at best. -Before adding an issue, please search if the same issue has already be reported -and avoid duplicating it. If it is a new issue and it not purley related +Before adding an issue, please search for any relevant entry in the [FAQ](docs/FAQ.md) +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). @@ -168,4 +170,3 @@ Contributions are welcome, we are looking for: - just anybody who wants to drop by and take an interest Please refer to the separate [CONTRIBUTING](docs/CONTRIBUTING.md) document for details on how to proceed! - diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index 8858d806..3e754b2d 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -8,3 +8,42 @@ the [general Jenkins participation](https://www.jenkins.io/participate/) needs. This contribution guide comes in complement to the general guidelines and [Jenkins GitHub organization contributing guide](https://github.com/jenkinsci/.github/blob/master/CONTRIBUTING.md). +## Document + +Good documentation is a great help for users and maintainers. +All of the plugin's documentation is written in [Github Markdown](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/quickstart-for-writing-on-github). + +Github makes a good job of facilitating the modification of Markdown files: click on the `Edit file` button on any markdown file and it will guides you through the steps. +If you want to make more changes or have a nice interface, you can make changes through a [codespace](https://docs.github.com/en/codespaces): click on the `Open in codespace` to have a visual studio code in the browser. + +All changes should be done in a branch, then create a pull request to propose them into the main branch. + +### Editing and proofreading + +Documentation is prone to typos and errors. Proofreading helps us maintain an unambiguous, good quality documentation that gives confidence in the plugin. +Some (most) of the contributors are non-native english speakers, feel free to rewrite the documentation to a more idiomatic english. + +Guidelines: + +- **Read through** the entire document to get a sense of the overall content and structure.
+ Tips: read the documenta loud to spot awkward phrasings, repetitive words, and other inconsistencies more easily +- **Check** for spelling, grammar, and punctuation errors.
+ Tips: spellcheck and grammar tool may not catch every errors but are a great help +- **Review** the use of technical terms and jargon to make sure they're used correctly and consistently.
+ Goal: replace specific terms with simpler words, provide clear explanations. +- **Look for inconsistencies** in the content, such as conflicting information or terminology. +- **Assess document structure** to make sure the document is well organized and easy to follow.
+ Goal: Ensure that headlines, sub-headlines, bullet points, and numbered lists are used effectively to break up lengthy paragraphs and improve readability. + +### Add guides and walkthroughs + +Configuration often requires to understand the domain and how the various parameters apply to one's own specific case. +Most people want to understand just enough for their purpose or just wants it *to work*. + +The [configuration](configuration/README.md) documentation contains space for addressing known providers. +Contributing to document a specific provider involves: + +- describing the setup on the provider side: not the install step, only the necessary steps to configure the client +- describing the setup on the plugin side: the specific features that can be actived or that need to be disabled +- provide a JCasC sample with placeholders +- link with known issues, quastions and workarounds related to the specific provider diff --git a/docs/FAQ.md b/docs/FAQ.md new file mode 100644 index 00000000..1eb32539 --- /dev/null +++ b/docs/FAQ.md @@ -0,0 +1,34 @@ +# Frequently Asked Questions + +## Odd issues + +Issues that were reported and solved without clear root cause. + +### Crumb issues + +*Symptom*: Jenkins reports multiple crumb issues and is unable to logout user. + +*Providers*: OKTA + +*Details* + +Logs contains warnings about crumb and CSRF issues: + +``` +2023-02-24 15:47:05.103+0000 [id=127] WARNING hudson.security.csrf.CrumbFilter#doFilter: Found invalid crumb 0b13bbc28c54659d3ea7f105cb9e49bb50898d77ec94f821fad1bf28dca956f6. If you are calling this URL with a script, please use the API Token instead. More information: https://www.jenkins.io/redirect/crumb-cannot-be-used-for-script +2023-02-24 15:47:05.107+0000 [id=127] WARNING hudson.security.csrf.CrumbFilter#doFilter: No valid crumb was included in request for /manage/descriptorByName/org.jenkinsci.plugins.oic.OicSecurityRealm/checkPostLogoutRedirectUrl by 00u8erxt6sBAIguA65d7. Returning 403. +``` + +*Workaround* + +This was solved by installin the [Strict Crumb Issuer](https://plugins.jenkins.io/strict-crumb-issuer/) plugin. +Relevant JCasC configuration is the following: + +```jenkins: + crumbIssuer: + strict: + checkOnlyLocalPath: true + checkSameSource: true + hoursValid: 8 + disableRememberMe: false +``` diff --git a/docs/configuration/GITLAB.md b/docs/configuration/GITLAB.md new file mode 100644 index 00000000..96aedd5f --- /dev/null +++ b/docs/configuration/GITLAB.md @@ -0,0 +1,61 @@ +# Gilab Provider + +[Gitlab][1] can be used as as an OpenID Connect identity provider. + +## Provider configuration + +An application must be setup on Gitlab as describe in the documentation +of [OAuth 2.0 authentication identity provider][2]. The application must +be configured with: + +- scopes: openid profile email +- redirect URI: `https:////securityRealm/finishLogin`. + +In order to obtain the client id and secret: + +- the OAuth 2 Client ID is provided in the Application ID field. +- the OAuth 2 Client Secret is accessed by selecting Copy in the Secret field + + +## Plugin configuration + +Gitla provides a well known configuration endpoint which can be used +for automating endpoint configuration. It also supports PKCE +verification for additional security. + +Except for those parameters and the choice of user information, default parameters value are suitable. + +### User information + +The following user information is used by the plugin: + +| field | description | +| ----- | ----------- | +| sub | The user's GitLab username | +| email | he user's primary email address | +| name | The user's full name | +| groups | Paths for the groups the user is a member of | + +The flag for overriding scope must be set for requesting only needed +scopes. + +### JCasC + +```yaml +jenkins: + securityRealm: + oic: + wellKnownOpenIDConfigurationUrl: https://gitlab.com/.well-known/openid-configuration + automanualconfigure: auto + clientId: identifier-client-id + clientSecret: identifuer-client-secret + overrideScopes: openid profile email + userNameField: preferred_username + fullNameFieldName: name + emailFieldName: email + groupFieldName: groups + pkceEnabled: true +``` + +[1]: https://docs.gitlab.com/ee/integration/openid_connect_provider.html +[2]: https://docs.gitlab.com/ee/integration/oauth_provider.html diff --git a/docs/configuration/GOOGLE.md b/docs/configuration/GOOGLE.md new file mode 100644 index 00000000..59cb5ed1 --- /dev/null +++ b/docs/configuration/GOOGLE.md @@ -0,0 +1,63 @@ +# Google Provider + +The [Google's OAuth 2.0 APIs][1] implementation for authentication +conforms to the OpenID Connect specification. + + +## Provider configuration + +A project must be setup in the [Google API Console][2] which will be +associated to your Jenkins instance. In the identifiers section, create +new "OAuth Client ID" identifier + +- application type: `Web application` +- name: any name which is meaningful for you +- authorized redirection URI: `https:////securityRealm/finishLogin` + +After, clicking on the creation button, a popup window provides the +client Id and the associated client secret to be used in the +configuration of the plugin. + +Additional configurations are available as indicated in [Google's documentation][1] such as the customization of the consent screen. + +## Plugin configuration + +Google provides a well known configuration endpoint which can be used +for automating endpoint configuration. It also supports PKCE +verification for additional security. + +Except for those parameters and the choice of user information, default parameters value are suitable. + +### User information + +The following user information is used by the plugin: + +| field | scope | description | +| ----- | ----- | ----------- | +| sub | (always) | An identifier for the user, unique among all Google accounts. | +| email | email | The user's email address. | +| name | profile | The user's full name, in a displayable form. | +| hd | (optional) | The domain associated with the Google Workspace or Cloud organization of the user. | + +The flag for overriding scope must be set for requesting only needed +scopes. + +### JCasC + +```yaml +jenkins: + securityRealm: + oic: + wellKnownOpenIDConfigurationUrl: https://accounts.google.com/.well-known/openid-configuration + automanualconfigure: auto + clientId: identifier-client-id + clientSecret: identifuer-client-secret + overrideScopes: openid profile name email + userNameField: sub + fullNameFieldName: name + emailFieldName: email + pkceEnabled: true +``` + +[1]: https://developers.google.com/identity/openid-connect/openid-connect +[2]: https://console.developers.google.com/ diff --git a/docs/configuration/README.md b/docs/configuration/README.md new file mode 100644 index 00000000..2eb0b797 --- /dev/null +++ b/docs/configuration/README.md @@ -0,0 +1,61 @@ +# Plugin configuration + +The OpenID Connect authentication plugin tries to support a wide range +of OpenID providers. The configuration reflects the various ways the +plugin accomodates their differences and provide a way to select the +information to extract. + +There are specifics instructions for well known providers: + +* [Google Provider](GOOGLE.md) +* [Gitlab Provider](GITLAB.md) + + +## Provider configuration + +The OpenID Conenct spec describes a well known configuration location +which will also help discovering your settings +() + +From 1.5 and onward the well known configuration location may be used to +populate the configuration simplifying the configuration greatly. + +## JCasC configuration reference + +JCasC configuration can be defined with the following fields: + +```yaml +jenkins: + securityRealm: + oic: + # Endpoints + automanualconfigure: + wellKnownOpenIDConfigurationUrl: + tokenServerUrl: + authorizationServerUrl: + # Credentials + clientId: + clientSecret: + tokenAuthMethod: + # claims + scopes: + userNameField: + groupsFieldName: + fullNameFieldName: + emailFieldName: + # advanced configuration + logoutFromOpenidProvider: + rootURLFromRequest: + sendScopesInTokenRequest: + # Security + disableSslVerification: + nonceDisabled: + pkceEnabled: + tokenFieldToCheckKey: + tokenFieldToCheckValue: string + # escape hatch + escapeHatchEnabled: + escapeHatchUsername: escapeHatchUsername + escapeHatchSecret: + escapeHatchGroup: +``` diff --git a/src/main/java/org/jenkinsci/plugins/oic/OicSecurityRealm.java b/src/main/java/org/jenkinsci/plugins/oic/OicSecurityRealm.java index 5002f6a9..28e36acb 100644 --- a/src/main/java/org/jenkinsci/plugins/oic/OicSecurityRealm.java +++ b/src/main/java/org/jenkinsci/plugins/oic/OicSecurityRealm.java @@ -258,8 +258,8 @@ public OicSecurityRealm( this.endSessionEndpoint = endSessionEndpoint; if ("auto".equals(automanualconfigure) - || (Util.fixNull(automanualconfigure).isEmpty() - && !Util.fixNull(wellKnownOpenIDConfigurationUrl).isEmpty())) { + || (Util.fixNull(automanualconfigure).isEmpty() && + !Util.fixNull(wellKnownOpenIDConfigurationUrl).isEmpty())) { this.automanualconfigure = "auto"; this.wellKnownOpenIDConfigurationUrl = Util.fixEmptyAndTrim(wellKnownOpenIDConfigurationUrl); this.loadWellKnownOpenIDConfigurationUrl();