Wiki source code of OpenID Authentication with Keycloak
Last modified by Andrey Sytchev on 2023/08/24 08:22
Show last authors
author | version | line-number | content |
---|---|---|---|
1 | {{info}} | ||
2 | The steps below assume, that you have a working Keycloak installation and the clients can connect to XWiki and Keycloak. | ||
3 | {{/info}} | ||
4 | |||
5 | {{info}} | ||
6 | You can find a little step by step documentation for [[mapping ldap groups to keycloak and push them to xwiki>>Extension.OpenID Connect.OpenID Connect Authenticator.OpenID Authentication with Keycloak.Keycloak Group-Mapping.WebHome]]. | ||
7 | {{/info}} | ||
8 | |||
9 | Follow these steps: | ||
10 | * Find ##xwiki.authentication.authclass## in ##xwiki.cfg## and comment it out with ###-### in the beginning. | ||
11 | * Add below: ##xwiki.authentication.authclass=org.xwiki.contrib.oidc.auth.OIDCAuthServiceImpl## | ||
12 | * Open ##xwiki.properties## and adapt the following to your settings, and add this at the end of the file (Note the ##_~_XXX_~_## parts):((( | ||
13 | {{code language='properties'}} | ||
14 | oidc.endpoint.authorization=https://__KEYCLOAK-ADDRESS__/auth/realms/__REALM__/protocol/openid-connect/auth | ||
15 | oidc.endpoint.token=https://__KEYCLOAK-ADDRESS__/auth/realms/__REALM__/protocol/openid-connect/token | ||
16 | oidc.endpoint.userinfo=https://__KEYCLOAK-ADDRESS__/auth/realms/__REALM__/protocol/openid-connect/userinfo | ||
17 | oidc.scope=openid,profile,email,address | ||
18 | oidc.endpoint.userinfo.method=GET | ||
19 | oidc.user.nameFormater=${oidc.user.preferredUsername._clean._lowerCase} | ||
20 | oidc.user.subjectFormater=${oidc.user.subject} | ||
21 | # oidc.groups.claim=xwiki_groups | ||
22 | # oidc.groups.mapping=MyXWikiGroup=my-oidc-group | ||
23 | # oidc.groups.mapping=MyXWikiGroup2=my-oidc-group2 | ||
24 | # oidc.groups.mapping=MyXWikiGroup2=my-oidc-group3 | ||
25 | # oidc.groups.allowed= | ||
26 | # oidc.groups.forbidden= | ||
27 | oidc.userinfoclaims=xwiki_user_accessibility,xwiki_user_company,xwiki_user_displayHiddenDocuments,xwiki_user_editor,xwiki_user_usertype | ||
28 | # oidc.userinforefreshrate=600000 | ||
29 | oidc.clientid=__KEYCLOAK-CLIENT-ID__ | ||
30 | oidc.secret=__KEYCLOAK-CLIENT-SECRET__ | ||
31 | oidc.endpoint.token.auth_method=client_secret_basic | ||
32 | oidc.skipped=false | ||
33 | {{/code}} | ||
34 | |||
35 | {{info}} | ||
36 | See [[futher configuration possibilites>>Extension.OpenID Connect.OpenID Connect Authenticator.WebHome||anchor="Hxwiki.properties"]]. | ||
37 | {{/info}} | ||
38 | ))) | ||
39 | * Adapt the following to your settings and import it to Keycloak (Again: Note the ##_~_XXX_~_## parts):((( | ||
40 | {{code language='json'}} | ||
41 | { | ||
42 | "clientId": "__CLIENT-ID__", | ||
43 | "name": "__CLIENT-NAME__", | ||
44 | "rootUrl": "https://__YOUR-WIKI-URL__", | ||
45 | "adminUrl": "https://__YOUR-WIKI-URL__", | ||
46 | "baseUrl": "https://__YOUR-WIKI-URL__", | ||
47 | "surrogateAuthRequired": false, | ||
48 | "enabled": true, | ||
49 | "alwaysDisplayInConsole": false, | ||
50 | "clientAuthenticatorType": "client-secret", | ||
51 | "redirectUris": [ | ||
52 | "https://__YOUR-WIKI-URL____YOUR_WEBAPP_NAME_OR_EMPTY__/authenticator/callback" | ||
53 | ], | ||
54 | "webOrigins": [ | ||
55 | "https://__YOUR-WIKI-URL__" | ||
56 | ], | ||
57 | "notBefore": 0, | ||
58 | "bearerOnly": false, | ||
59 | "consentRequired": false, | ||
60 | "standardFlowEnabled": true, | ||
61 | "implicitFlowEnabled": true, | ||
62 | "directAccessGrantsEnabled": true, | ||
63 | "serviceAccountsEnabled": true, | ||
64 | "authorizationServicesEnabled": true, | ||
65 | "publicClient": false, | ||
66 | "frontchannelLogout": false, | ||
67 | "protocol": "openid-connect", | ||
68 | "attributes": { | ||
69 | "saml.assertion.signature": "false", | ||
70 | "saml.force.post.binding": "false", | ||
71 | "saml.multivalued.roles": "false", | ||
72 | "saml.encrypt": "false", | ||
73 | "saml.server.signature": "false", | ||
74 | "saml.server.signature.keyinfo.ext": "false", | ||
75 | "exclude.session.state.from.auth.response": "false", | ||
76 | "saml_force_name_id_format": "false", | ||
77 | "saml.client.signature": "false", | ||
78 | "tls.client.certificate.bound.access.tokens": "false", | ||
79 | "saml.authnstatement": "false", | ||
80 | "display.on.consent.screen": "false", | ||
81 | "saml.onetimeuse.condition": "false" | ||
82 | }, | ||
83 | "authenticationFlowBindingOverrides": {}, | ||
84 | "fullScopeAllowed": false, | ||
85 | "nodeReRegistrationTimeout": -1, | ||
86 | "protocolMappers": [{ | ||
87 | "name": "Client Host", | ||
88 | "protocol": "openid-connect", | ||
89 | "protocolMapper": "oidc-usersessionmodel-note-mapper", | ||
90 | "consentRequired": false, | ||
91 | "config": { | ||
92 | "user.session.note": "clientHost", | ||
93 | "id.token.claim": "true", | ||
94 | "access.token.claim": "true", | ||
95 | "claim.name": "clientHost", | ||
96 | "jsonType.label": "String" | ||
97 | } | ||
98 | }, | ||
99 | { | ||
100 | "name": "Client IP Address", | ||
101 | "protocol": "openid-connect", | ||
102 | "protocolMapper": "oidc-usersessionmodel-note-mapper", | ||
103 | "consentRequired": false, | ||
104 | "config": { | ||
105 | "user.session.note": "clientAddress", | ||
106 | "id.token.claim": "true", | ||
107 | "access.token.claim": "true", | ||
108 | "claim.name": "clientAddress", | ||
109 | "jsonType.label": "String" | ||
110 | } | ||
111 | }, | ||
112 | { | ||
113 | "name": "address", | ||
114 | "protocol": "openid-connect", | ||
115 | "protocolMapper": "oidc-address-mapper", | ||
116 | "consentRequired": false, | ||
117 | "config": { | ||
118 | "user.attribute.formatted": "formatted", | ||
119 | "user.attribute.country": "country", | ||
120 | "user.attribute.postal_code": "postal_code", | ||
121 | "userinfo.token.claim": "true", | ||
122 | "user.attribute.street": "street", | ||
123 | "id.token.claim": "true", | ||
124 | "user.attribute.region": "region", | ||
125 | "access.token.claim": "true", | ||
126 | "user.attribute.locality": "locality" | ||
127 | } | ||
128 | }, | ||
129 | { | ||
130 | "name": "Client ID", | ||
131 | "protocol": "openid-connect", | ||
132 | "protocolMapper": "oidc-usersessionmodel-note-mapper", | ||
133 | "consentRequired": false, | ||
134 | "config": { | ||
135 | "user.session.note": "clientId", | ||
136 | "id.token.claim": "true", | ||
137 | "access.token.claim": "true", | ||
138 | "claim.name": "clientId", | ||
139 | "jsonType.label": "String" | ||
140 | } | ||
141 | } | ||
142 | ], | ||
143 | "defaultClientScopes": [ | ||
144 | "web-origins", | ||
145 | "role_list", | ||
146 | "roles", | ||
147 | "profile", | ||
148 | "email" | ||
149 | ], | ||
150 | "optionalClientScopes": [ | ||
151 | "address", | ||
152 | "phone", | ||
153 | "offline_access", | ||
154 | "microprofile-jwt" | ||
155 | ], | ||
156 | "access": { | ||
157 | "view": true, | ||
158 | "configure": true, | ||
159 | "manage": true | ||
160 | } | ||
161 | } | ||
162 | {{/code}} | ||
163 | ))) | ||
164 | |||
165 | {{warning}} | ||
166 | After importing this to Keycloak, you have to generate a new Client-Secret and put it into ##xwiki.properties## under ##oidc.secret=_~_KEYCLOAK-CLIENT-SECRET_~_##. | ||
167 | Aim is: In the end, Client-ID and Client-Secret have to match on Keycloak and in ##xwiki.properties##. | ||
168 | {{/warning}} |