jenkinsci / oic-auth-plugin

A Jenkins plugin which lets you login to Jenkins using your own, self-hosted or public openid connect server.
https://plugins.jenkins.io/oic-auth
MIT License
71 stars 91 forks source link

Write a HOWTO on how roles from the IDP are mapped to Jenkins roles. #258

Closed tuxmaster5000 closed 5 months ago

tuxmaster5000 commented 10 months ago

Jenkins and plugins versions report

Environment ```Jenkins: 2.434 OS: Linux - 5.14.0-362.8.1.el9_3.x86_64 Java: 17.0.9 - Red Hat, Inc. (OpenJDK 64-Bit Server VM) --- active-directory:2.34 analysis-model-api:11.13.0 antisamy-markup-formatter:162.v0e6ec0fcfcf6 apache-httpcomponents-client-4-api:4.5.14-208.v438351942757 atlassian-bitbucket-server-integration:4.0.0 authentication-tokens:1.53.v1c90fd9191a_b_ aws-credentials:218.v1b_e9466ec5da_ aws-java-sdk-ec2:1.12.586-413.v6a_6c3a_420126 aws-java-sdk-minimal:1.12.586-413.v6a_6c3a_420126 bootstrap5-api:5.3.2-3 bouncycastle-api:2.29 branch-api:2.1135.v8de8e7899051 build-timeout:1.31 caffeine-api:3.1.8-133.v17b_1ff2e0599 checks-api:2.0.2 cloudbees-folder:6.858.v898218f3609d command-launcher:107.v773860566e2e commons-lang3-api:3.13.0-62.v7d18e55f51e2 commons-text-api:1.11.0-95.v22a_d30ee5d36 credentials:1309.v8835d63eb_d8a_ credentials-binding:642.v737c34dea_6c2 data-tables-api:1.13.8-2 display-url-api:2.200.vb_9327d658781 docker-commons:439.va_3cb_0a_6a_fb_29 docker-workflow:572.v950f58993843 durable-task:523.va_a_22cf15d5e0 echarts-api:5.4.3-2 email-ext:2.102 external-monitor-job:215.v2e88e894db_f8 favorite:2.4.3 font-awesome-api:6.5.1-1 forensics-api:2.3.0 git:5.2.1 git-client:4.6.0 git-forensics:2.0.0 git-server:99.va_0826a_b_cdfa_d handy-uri-templates-2-api:2.1.8-22.v77d5b_75e6953 htmlpublisher:1.32 instance-identity:185.v303dc7c645f9 ionicons-api:56.v1b_1c8c49374e jackson2-api:2.15.3-372.v309620682326 jakarta-activation-api:2.0.1-3 jakarta-mail-api:2.0.1-3 javax-activation-api:1.2.0-6 javax-mail-api:1.6.2-9 jaxb:2.3.9-1 jdk-tool:73.vddf737284550 jenkins-design-language:1.27.9 jquery3-api:3.7.1-1 jsch:0.2.8-65.v052c39de79b_2 junit:1240.vf9529b_881428 ldap:711.vb_d1a_491714dc lockable-resources:1215.v895f61d7f794 mailer:463.vedf8358e006b_ matrix-auth:3.2.1 matrix-project:818.v7eb_e657db_924 mina-sshd-api-common:2.11.0-86.v836f585d47fa_ mina-sshd-api-core:2.11.0-86.v836f585d47fa_ nodelabelparameter:1.12.0 oic-auth:2.6 pam-auth:1.10 periodicbackup:2.0 pipeline-build-step:516.v8ee60a_81c5b_9 pipeline-graph-analysis:202.va_d268e64deb_3 pipeline-groovy-lib:689.veec561a_dee13 pipeline-input-step:477.v339683a_8d55e pipeline-milestone-step:111.v449306f708b_7 pipeline-model-api:2.2151.ve32c9d209a_3f pipeline-model-definition:2.2151.ve32c9d209a_3f pipeline-model-extensions:2.2151.ve32c9d209a_3f pipeline-rest-api:2.34 pipeline-stage-step:305.ve96d0205c1c6 pipeline-stage-tags-metadata:2.2151.ve32c9d209a_3f pipeline-stage-view:2.34 plain-credentials:143.v1b_df8b_d3b_e48 plugin-util-api:3.6.0 prism-api:1.29.0-10 pubsub-light:1.18 pyenv-pipeline:2.1.2 resource-disposer:0.23 role-strategy:689.v731678c3e0eb_ saferestart:0.7 scm-api:683.vb_16722fb_b_80b_ script-security:1294.v99333c047434 sidebar-update-notification:1.1.0 snakeyaml-api:2.2-111.vc6598e30cc65 sse-gateway:1.26 ssh-credentials:308.ve4497b_ccd8f4 ssh-slaves:2.916.vd17b_43357ce4 sshd:3.312.v1c601b_c83b_0e structs:325.vcb_307d2a_2782 timestamper:1.26 token-macro:384.vf35b_f26814ec trilead-api:2.84.v72119de229b_7 variant:60.v7290fc0eb_b_cd warnings-ng:10.5.2 workflow-aggregator:596.v8c21c963d92d workflow-api:1283.v99c10937efcb_ workflow-basic-steps:1042.ve7b_140c4a_e0c workflow-cps:3817.vd20b_7e2b_692b_ workflow-durable-task-step:1289.v4d3e7b_01546b_ workflow-job:1385.vb_58b_86ea_fff1 workflow-multibranch:756.v891d88f2cd46 workflow-scm-step:415.v434365564324 workflow-step-api:639.v6eca_cd8c04a_a_ workflow-support:865.v43e78cc44e0d ws-cleanup:0.45 ```

What Operating System are you using (both controller, and any agents involved in the problem)?

Rocky 9.3

Reproduction steps

  1. Log in

Expected Results

That the roles that comes from the IDP are mapped to the Jenkins roles with the same name.

Actual Results

Only the error, that the user don't have the "overall/read" right.

Anything else?

sample : roles comes from the IDP: "realm_access": { "roles": [ "Jenkins user", "offline_access", "default-roles-", "uma_authorization", "Jenkins admin" ] }, that the roles are mapped to the jenkins roles "Jenkins user" and "Jenkins admin"

Are you interested in contributing a fix?

No response

logidru commented 10 months ago

have you set the "groups name field"? i have exactly the same setting and it works perfect. you just need to set

realm_access.roles[].name

to groupsNameField then the roles on keykloak are mapped.

Not sure if there might be a Problem with spaces. my roles are jenkins_admin, jenkins_builder, jenkins_reader and the same names are groups in MatrixAuthorizationStrategy with the proper rights set.

tuxmaster5000 commented 10 months ago

Hm I have set it to "realm_access.roles[].name" but it will only result in this error: o.j.plugins.oic.OicSecurityRealm#determineAuthorities: idToken and userInfo did not contain group field name: realm_access The field exits only in the user access token not in the user id/user info token. And when I add this field to the idToken, then it will result in the error as above, that user don't have the "overall/read" right.

michael-doubez commented 6 months ago

It looks like an issue similar to #218.

AFAIK the access token is not supposed to be parsed by the client. Only the provider should be able to valide it.

michael-doubez commented 6 months ago

Even Oauth specification are clear on that point: "[...] An access token is a string representing an authorization issued to the client. The string is usually opaque to the client. [...]"

See: https://datatracker.ietf.org/doc/html/rfc6749#section-1.4

Now, we could argue that the /usually/ means we could add an option to parse it as a JWT.

You can open a request for this feature and if there are enough use cases, someone may take it up.

tuxmaster5000 commented 6 months ago

@michael-doubez Where should I send the enquiry?

michael-doubez commented 6 months ago

Re-reading your message, you said that

And when I add this field to the idToken, then it will result in the error as above, that user don't have the "overall/read" right.

So, you don't need the groups to be parsed from access token. It does find the groups in the idtoken. But there is some kind of issue associating them with existing groups.

Try adding your user in the matrix and display the user's groups.

tuxmaster5000 commented 6 months ago

When I add the user manual to the group then it will work. (add the login name) And after the first login, the user name in the "Assign Roles" board was changes to the full user name. Before it was the login name.

michael-doubez commented 6 months ago

When you go to https://<instance>/jenkins/user/<username>/ (or click on your name on the top right hand side), do you see groups associated to your user

example:

Groups:

  • Jenkins user
  • Jenkins admin

And do those groups exist in you matrix ?

tuxmaster5000 commented 6 months ago

Hi @michael-doubez , in UI they are called: "Jenkins Admin" and "Jenkins Nutzer", as inn the token

"roles": [
      "Jenkins Nutzer",
      "offline_access",
      "default-roles-mdc",
      "uma_authorization",
      "Jenkins Admin"
    ]

Screenshot 2024-04-11 at 06-44-02 Manage Roles Jenkins

michael-doubez commented 6 months ago

If they are associated to your user, they should appear in your profile. Do they ?

Can you share the structure of your idtoken and userinfo content ? And the configuration you used for the groupFieldName.

If you have a test instance, you can try to configure the field to hard-coded value ['Jenkins Admin'] (provided you have a recent version of the plugin) and check the group is correctly associated to your user.

michael-doubez commented 6 months ago

Even better: the whoami url of your jenkins https://<root url>/whoAmI/ should give you the details of the login outcome.

tuxmaster5000 commented 5 months ago

whoAmI will result in:

<h1>Who Am I?</h1>
Name: | <login name>
-- | --
IsAuthenticated?: | true
Authorities: | "authenticated"

Here I don't see any role memberships.

michael-doubez commented 5 months ago

That means your configuration doesn't capture "roles".

What does your idtoken or userinfo look like ? What did you configure in the plugin ? (realm_access.roles ?)

tuxmaster5000 commented 5 months ago

I have set: "Groups field name" to realm_access.roles[].name do you mean this? And here an sample token:

{
  "exp": 1713262211,
  "iat": 1713261911,
  "auth_time": 0,
  "jti": "1b2bb44e-1a14-4b04-9eab-3ec4f66d225a",
  "iss": "https://<KC server>/realms/<realm>",
  "aud": "Jenkins",
  "sub": "f:19c9166a-bbef-4efc-a087-c42b411af5f4:<user>",
  "typ": "ID",
  "azp": "Jenkins",
  "session_state": "3eea64c8-b67e-4806-bf64-f87cc072257d",
  "acr": "1",
  "sid": "3eea64c8-b67e-4806-bf64-f87cc072257d",
  "email_verified": true,
  "realm_access": {
    "roles": [
      "Jenkins Nutzer",
      "offline_access",
      "default-roles-<realm>",
      "uma_authorization",
      "Jenkins Admin"
    ]
  },
  "name": "<Full name>",
  "preferred_username": "<login name>",
  "given_name": "<First name>",
  "family_name": "<last name>",
  "email": "<mail address>"
}
michael-doubez commented 5 months ago

The expression realm_access.roles[].name would fit.

{
  "realm_access": {
    "roles": [
      {"name": "Jenkins Nutzer"},
      {"name": "offline_access"},
      {"name": "default-roles-<realm>"},
     {"name":  "uma_authorization"},
     {"name":  "Jenkins Admin"}
    ]
  }
}

Set it to realm_access.roles.

You can test it on https://jmespath.org/

tuxmaster5000 commented 5 months ago

Hm, but the result are the same :( Set it to "realm_access.roles" and remove the user manual from the role, will end with the old error: don't have the "overall/read" right. Adding the user manual to the role again, an login will works. The only diff that I can see, that whoAmI now show the memberships:

Jenkins User ID: Gruppen:

default-roles-<realm>
Jenkins Admin
Jenkins Nutzer
offline_access
uma_authorization
tuxmaster5000 commented 5 months ago

Here an picture of it. Screenshot 2024-04-17 at 11-02-11 Who Am I Jenkins But the role settings are not updated, because both user/Nutzer and admin/Admin must bet set, I think.:

Screenshot 2024-04-17 at 11-04-40 Assign Roles Jenkins

michael-doubez commented 5 months ago

Unless I miss something you are nearly set:

By example: a group called Jenkins Admin with a tick in Jenkins Admin column

tuxmaster5000 commented 5 months ago

Yes, that's exactly how it works. But the user should actually end up in the role on their own if they are assigned it via the token. And manual addition should not really be necessary.

michael-doubez commented 5 months ago

I don t understand your comment.

The configuration steps are:

  1. Create group in keycloack and associate to user
  2. Create group with same name in Jenkins and associate rights
  3. When user connects, it gets the rights of group configured in step 2

Isn't that your experience?

tuxmaster5000 commented 4 months ago

Hi @michael-doubez no, because step 3 don't work. I must add the user by hand to the role in jenkins. Because the automatic role mapping from the IDP to jeninks will not work. Bot has the same roles, but the users are not automatic added in jenkins.