Skip to content

Commit

Permalink
chore: document providers (#296)
Browse files Browse the repository at this point in the history
* Add FAQ
* Update CONTRIBUTING.md
* Add generic configuration
* Add GOOGLE Provider configuration
* Add GITLAB configuration
  • Loading branch information
michael-doubez authored Apr 11, 2024
1 parent a971cb1 commit 7201721
Show file tree
Hide file tree
Showing 7 changed files with 288 additions and 29 deletions.
55 changes: 28 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
</details>

## User guide
Expand All @@ -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:
Expand All @@ -64,36 +73,28 @@ 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
(<https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig>)

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.<br />
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)

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: <https://developers.google.com/identity/protocols/OpenIDConnect>

#### Using the plugin with Azure AD

See this blog post <http://www.epiclabs.io/configure-jenkins-use-azure-ad-authentication-openid-connect/>

### Interacting with Jenkins as a non front-end user

Expand Down Expand Up @@ -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).

Expand All @@ -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!

39 changes: 39 additions & 0 deletions docs/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.<br />
Tips: read the documenta loud to spot awkward phrasings, repetitive words, and other inconsistencies more easily
- **Check** for spelling, grammar, and punctuation errors.<br />
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.<br />
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.<br/>
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
34 changes: 34 additions & 0 deletions docs/FAQ.md
Original file line number Diff line number Diff line change
@@ -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
```
61 changes: 61 additions & 0 deletions docs/configuration/GITLAB.md
Original file line number Diff line number Diff line change
@@ -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://<name>/<jenkins>/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
63 changes: 63 additions & 0 deletions docs/configuration/GOOGLE.md
Original file line number Diff line number Diff line change
@@ -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://<name>/<jenkins>/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/
61 changes: 61 additions & 0 deletions docs/configuration/README.md
Original file line number Diff line number Diff line change
@@ -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
(<https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig>)

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: <string:enum>
wellKnownOpenIDConfigurationUrl: <url>
tokenServerUrl: <url>
authorizationServerUrl: <url>
# Credentials
clientId: <string>
clientSecret: <string:secret>
tokenAuthMethod: <string:enum>
# claims
scopes: <string:space separated words>
userNameField: <string:jmes path>
groupsFieldName: <string:jmes path>
fullNameFieldName: <string: jmes path>
emailFieldName: <string:jmes path>
# advanced configuration
logoutFromOpenidProvider: <boolean>
rootURLFromRequest: <boolean>
sendScopesInTokenRequest: <boolean>
# Security
disableSslVerification: <boolean>
nonceDisabled: <boolean>
pkceEnabled: <boolean>
tokenFieldToCheckKey: <string:jmes path>
tokenFieldToCheckValue: string
# escape hatch
escapeHatchEnabled: <boolean>
escapeHatchUsername: escapeHatchUsername
escapeHatchSecret: <string:secret>
escapeHatchGroup: <string>
```
4 changes: 2 additions & 2 deletions src/main/java/org/jenkinsci/plugins/oic/OicSecurityRealm.java
Original file line number Diff line number Diff line change
Expand Up @@ -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() &&

Check warning on line 261 in src/main/java/org/jenkinsci/plugins/oic/OicSecurityRealm.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Partially covered line

Line 261 is only partially covered, one branch is missing
!Util.fixNull(wellKnownOpenIDConfigurationUrl).isEmpty())) {

Check warning on line 262 in src/main/java/org/jenkinsci/plugins/oic/OicSecurityRealm.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered line

Line 262 is not covered by tests
this.automanualconfigure = "auto";
this.wellKnownOpenIDConfigurationUrl = Util.fixEmptyAndTrim(wellKnownOpenIDConfigurationUrl);
this.loadWellKnownOpenIDConfigurationUrl();
Expand Down

0 comments on commit 7201721

Please sign in to comment.