Compare commits
22 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
903ad6566b | |
|
|
ed92d938e2 | |
|
|
99359e50c5 | |
|
|
9514848c89 | |
|
|
3a7ff5309e | |
|
|
8160625284 | |
|
|
6e4e303827 | |
|
|
bb0c00cbcd | |
|
|
417e372ea5 | |
|
|
b99f7f22c0 | |
|
|
10ad4c7ec7 | |
|
|
efef4b9053 | |
|
|
39f9a585eb | |
|
|
ddc2852c32 | |
|
|
1da46d1645 | |
|
|
7e7cf86e69 | |
|
|
fbf1c5273e | |
|
|
3101d4dc3b | |
|
|
7079aef105 | |
|
|
80fffdd66d | |
|
|
4840fe0ef7 | |
|
|
5fcf562d30 |
57
CHANGELOG.md
57
CHANGELOG.md
|
|
@ -2,33 +2,46 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
|||
|
||||
# Changelog for "keycloak-client"
|
||||
|
||||
## [v2.2.0-SNAPSHOT]
|
||||
- Added support to add scopes in requests in client and constants for d4s-context dynamic scope. (#28084)
|
||||
- Added tests to demonstrate dynamic scopes for clients and for users on both private and public clients (#28084)
|
||||
- Moved form gxJRS to low level gxHTTP (#28294)
|
||||
- Moved to `jjwt` internal lib (#28296)
|
||||
## [v2.4.0]
|
||||
- Fixed use of client's scope, audience and token exchange related tests
|
||||
- Added dynamic scope "enabler" value to `/*` static config value
|
||||
|
||||
## [v2.1.0]
|
||||
- Added `token-exchange` support, also with `offline-token` scope, and methods to add extra headers during the OIDC token requests (#27099).
|
||||
- Added custom base URL set via factory (not automatically working cross environments) [#27234].
|
||||
|
||||
## [v2.3.0]
|
||||
|
||||
- aligned with keycloak-client v3.0.0 for java17
|
||||
|
||||
## [v2.2.0] - 2025-11-05
|
||||
|
||||
- Added support to add scopes in requests in client and constants for d4s-context dynamic scope. [#28084]
|
||||
- Added tests to demonstrate dynamic scopes for clients and for users on both private and public clients [#28084]
|
||||
- Moved form gxJRS to low level gxHTTP [#28294]
|
||||
- Moved to `jjwt` internal lib [#28296]
|
||||
|
||||
## [v2.1.0] - 2024-05-07
|
||||
|
||||
- Added `token-exchange` support, also with `offline-token` scope, and methods to add extra headers during the OIDC token requests [#27099].
|
||||
- Added custom base URL set via factory (not automatically working cross environments) [#27234]
|
||||
- Added JWKS server configuration retrieval, realm's info (as `PublishedRealmRepresentation` JSON containing public key) and JWT digital signature verification by using the RSA public key of the realm on server. It uses the `jjwt` library by `io.jsonwebtoken` [#27340]
|
||||
|
||||
## [v2.0.0]
|
||||
- Removed the discovery functionality to be compatible with SmartGears.v4 and moved to the new library `keycloak-client-legacy-is` that will provide the backward compatibility. (#23478).
|
||||
- Fixed typo in `AccessToken` class for `setAccessToken(..)` method (#23654)
|
||||
- Added predictive infrastructure URL support based on context (and on context and realm if the target realm is not the default one) and overloaded all methods that take the URL as argument with the context. (#23655)
|
||||
## [v2.0.0] - 2023-07-21
|
||||
|
||||
- Removed the discovery functionality to be compatible with SmartGears.v4 and moved to the new library `keycloak-client-legacy-is` that will provide the backward compatibility. [#23478].
|
||||
- Fixed typo in `AccessToken` class for `setAccessToken(..)` method [#23654]
|
||||
- Added predictive infrastructure URL support based on context (and on context and realm if the target realm is not the default one) and overloaded all methods that take the URL as argument with the context. [#23655]
|
||||
- Added support for the use of the custom Keycloak's D4S mapper that maps/shrink the `aud` (and optionally also the resource access) to the value requested via `X-D4Science-Context` HTTP header.
|
||||
- Added support of password grant flow (corresponding to the now deprecated OAuth2 flow: Resource Owner Password Credentials grant) also for specific context/audience by using the specific D4S mapper. (#25291)
|
||||
- Added new `KeycloakClientHelper` class to perform token request for user in one shot and without the need to provide the `clientId` parameter (#25291). Only `context`, `username` and `password` are required. (#25291)
|
||||
- Added support of password grant flow (corresponding to the now deprecated OAuth2 flow: Resource Owner Password Credentials grant) also for specific context/audience by using the specific D4S mapper. [#25291]
|
||||
- Added new `KeycloakClientHelper` class to perform token request for user in one shot and without the need to provide the `clientId` parameter. Only `context`, `username` and `password` are required. [#25291], [#25291]
|
||||
- Added functions to introspect and verify access tokens (both OIDC and UMA are supported) [#23326]
|
||||
|
||||
## [v1.3.0-SNAPSHOT]
|
||||
- Added functions to introspect and verify access tokens (both OIDC and UMA are supported) (#23326).
|
||||
## [v1.2.0] - 2022-04-04
|
||||
|
||||
## [v1.2.0]
|
||||
- Added OIDC token retrieve for clients [#23076] and UMA token from OIDC token as bearer auth, instead of credentials only (basic auth)
|
||||
- Added OIDC token retrieve for clients and UMA token from OIDC token as bearer auth, instead of credentials only [basic auth](#23076)
|
||||
|
||||
## [v1.1.0]
|
||||
- Added refresh token facilities for expired tokens (#22515) and some helper methods added.
|
||||
## [v1.1.0] - 2022-01-13
|
||||
|
||||
## [v1.0.1]
|
||||
- First release (#21389 #22155) provides the basic helper classes for Keycloak tokens retrieve and functions for the gCube framework integration (automatic service discovery).
|
||||
- Added refresh token facilities for expired tokens and some helper methods added [#22515]
|
||||
|
||||
## [v1.0.1] - 2021-10-07
|
||||
|
||||
- First release, provides the basic helper classes for Keycloak tokens retrieve and functions for the gCube framework integration (automatic service discovery) [#21389], [#22155]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,210 @@
|
|||
cff-version: 1.2.0
|
||||
message: If you use this software, please cite it using the metadata from this file
|
||||
title: My best software
|
||||
type: software
|
||||
authors:
|
||||
- given-names: Mauro
|
||||
family-names: Mugnaini
|
||||
affiliation:
|
||||
- "Nubisware S.r.l., Pisa, Italy"
|
||||
- "D4Science Infrastructure, Pisa, Italy"
|
||||
repository-code: https://code-repo.d4science.org/gCubeSystem/keycloak-client
|
||||
url: https://www.gcube-system.org/
|
||||
repository-artifact: https://maven.d4science.org/nexus/
|
||||
license: EUPL-1.2
|
||||
references:
|
||||
- type: article
|
||||
authors:
|
||||
- family-names: Assante
|
||||
given-names: Massimiliano
|
||||
affiliation: "Istituto di Scienza e Tecnologie dell'Informazione (ISTI), Consiglio Nazionale delle Ricerche (CNR), Pisa, Italy"
|
||||
orcid: https://orcid.org/0000-0002-3761-1492
|
||||
- family-names: Candela
|
||||
given-names: Leonardo
|
||||
affiliation: "Istituto di Scienza e Tecnologie dell'Informazione (ISTI), Consiglio Nazionale delle Ricerche (CNR), Pisa, Italy"
|
||||
orcid: https://orcid.org/0000-0002-7279-2727
|
||||
- family-names: Castelli
|
||||
given-names: Donatella
|
||||
affiliation: "Istituto di Scienza e Tecnologie dell'Informazione (ISTI), Consiglio Nazionale delle Ricerche (CNR), Pisa, Italy"
|
||||
- family-names: Cirilllo
|
||||
given-names: Roberto
|
||||
affiliation: "Istituto di Scienza e Tecnologie dell'Informazione (ISTI), Consiglio Nazionale delle Ricerche (CNR), Pisa, Italy"
|
||||
orcid: https://orcid.org/0009-0006-2359-4202
|
||||
- family-names: Coro
|
||||
given-names: Gianpaolo
|
||||
affiliation: "Istituto di Scienza e Tecnologie dell'Informazione (ISTI), Consiglio Nazionale delle Ricerche (CNR), Pisa, Italy"
|
||||
orcid: https://orcid.org/0000-0001-7232-191X
|
||||
- family-names: Frosini
|
||||
given-names: Luca
|
||||
affiliation: "Istituto di Scienza e Tecnologie dell'Informazione (ISTI), Consiglio Nazionale delle Ricerche (CNR), Pisa, Italy"
|
||||
orcid: https://orcid.org/0000-0003-3183-2291
|
||||
- family-names: Lelii
|
||||
given-names: Lucio
|
||||
affiliation: "Istituto di Scienza e Tecnologie dell'Informazione (ISTI), Consiglio Nazionale delle Ricerche (CNR), Pisa, Italy"
|
||||
orcid: https://orcid.org/0000-0001-7581-5325
|
||||
- family-names: Mangiacrapa
|
||||
given-names: Francesco
|
||||
affiliation: "Istituto di Scienza e Tecnologie dell'Informazione (ISTI), Consiglio Nazionale delle Ricerche (CNR), Pisa, Italy"
|
||||
orcid: https://orcid.org/0000-0002-6528-664X
|
||||
- family-names: Marioli
|
||||
given-names: Valentina
|
||||
affiliation: "Istituto di Scienza e Tecnologie dell'Informazione (ISTI), Consiglio Nazionale delle Ricerche (CNR), Pisa, Italy"
|
||||
- family-names: Pagano
|
||||
given-names: Pasquale
|
||||
affiliation: "Istituto di Scienza e Tecnologie dell'Informazione (ISTI), Consiglio Nazionale delle Ricerche (CNR), Pisa, Italy"
|
||||
orcid: https://orcid.org/0000-0001-6611-3209
|
||||
- family-names: Panichi
|
||||
given-names: Giancarlo
|
||||
affiliation: "Istituto di Scienza e Tecnologie dell'Informazione (ISTI), Consiglio Nazionale delle Ricerche (CNR), Pisa, Italy"
|
||||
orcid: https://orcid.org/0000-0001-8375-6644
|
||||
- family-names: Perciante
|
||||
given-names: Costantino
|
||||
affiliation: "Istituto di Scienza e Tecnologie dell'Informazione (ISTI), Consiglio Nazionale delle Ricerche (CNR), Pisa, Italy"
|
||||
- family-names: Sinibaldi
|
||||
given-names: Fabio
|
||||
affiliation: "Istituto di Scienza e Tecnologie dell'Informazione (ISTI), Consiglio Nazionale delle Ricerche (CNR), Pisa, Italy"
|
||||
orcid: https://orcid.org/0000-0003-1013-6203
|
||||
title: "The gCube system: Delivering Virtual Research Environments as-a-Service"
|
||||
year: 2019
|
||||
journal: Future Generation Computer System
|
||||
volume: 95
|
||||
doi: 10.1016/j.future.2018.10.035
|
||||
url: https://doi.org/10.1016/j.future.2018.10.035
|
||||
- type: article
|
||||
authors:
|
||||
- family-names: Assante
|
||||
given-names: Massimiliano
|
||||
affiliation: "Istituto di Scienza e Tecnologie dell'Informazione (ISTI), Consiglio Nazionale delle Ricerche (CNR), Pisa, Italy"
|
||||
orcid: https://orcid.org/0000-0002-3761-1492
|
||||
- family-names: Candela
|
||||
given-names: Leonardo
|
||||
affiliation: "Istituto di Scienza e Tecnologie dell'Informazione (ISTI), Consiglio Nazionale delle Ricerche (CNR), Pisa, Italy"
|
||||
orcid: https://orcid.org/0000-0002-7279-2727
|
||||
- family-names: Castelli
|
||||
given-names: Donatella
|
||||
affiliation: "Istituto di Scienza e Tecnologie dell'Informazione (ISTI), Consiglio Nazionale delle Ricerche (CNR), Pisa, Italy"
|
||||
- family-names: Cirilllo
|
||||
given-names: Roberto
|
||||
affiliation: "Istituto di Scienza e Tecnologie dell'Informazione (ISTI), Consiglio Nazionale delle Ricerche (CNR), Pisa, Italy"
|
||||
orcid: https://orcid.org/0009-0006-2359-4202
|
||||
- family-names: Coro
|
||||
given-names: Gianpaolo
|
||||
affiliation: "Istituto di Scienza e Tecnologie dell'Informazione (ISTI), Consiglio Nazionale delle Ricerche (CNR), Pisa, Italy"
|
||||
orcid: https://orcid.org/0000-0001-7232-191X
|
||||
- family-names: Frosini
|
||||
given-names: Luca
|
||||
affiliation: "Istituto di Scienza e Tecnologie dell'Informazione (ISTI), Consiglio Nazionale delle Ricerche (CNR), Pisa, Italy"
|
||||
orcid: https://orcid.org/0000-0003-3183-2291
|
||||
- family-names: Lelii
|
||||
given-names: Lucio
|
||||
affiliation: "Istituto di Scienza e Tecnologie dell'Informazione (ISTI), Consiglio Nazionale delle Ricerche (CNR), Pisa, Italy"
|
||||
orcid: https://orcid.org/0000-0001-7581-5325
|
||||
- family-names: Mangiacrapa
|
||||
given-names: Francesco
|
||||
affiliation: "Istituto di Scienza e Tecnologie dell'Informazione (ISTI), Consiglio Nazionale delle Ricerche (CNR), Pisa, Italy"
|
||||
orcid: https://orcid.org/0000-0002-6528-664X
|
||||
- family-names: Marioli
|
||||
given-names: Valentina
|
||||
affiliation: "Istituto di Scienza e Tecnologie dell'Informazione (ISTI), Consiglio Nazionale delle Ricerche (CNR), Pisa, Italy"
|
||||
- family-names: Pagano
|
||||
given-names: Pasquale
|
||||
affiliation: "Istituto di Scienza e Tecnologie dell'Informazione (ISTI), Consiglio Nazionale delle Ricerche (CNR), Pisa, Italy"
|
||||
orcid: https://orcid.org/0000-0001-6611-3209
|
||||
- family-names: Panichi
|
||||
given-names: Giancarlo
|
||||
affiliation: "Istituto di Scienza e Tecnologie dell'Informazione (ISTI), Consiglio Nazionale delle Ricerche (CNR), Pisa, Italy"
|
||||
orcid: https://orcid.org/0000-0001-8375-6644
|
||||
- family-names: Perciante
|
||||
given-names: Costantino
|
||||
affiliation: "Istituto di Scienza e Tecnologie dell'Informazione (ISTI), Consiglio Nazionale delle Ricerche (CNR), Pisa, Italy"
|
||||
- family-names: Sinibaldi
|
||||
given-names: Fabio
|
||||
affiliation: "Istituto di Scienza e Tecnologie dell'Informazione (ISTI), Consiglio Nazionale delle Ricerche (CNR), Pisa, Italy"
|
||||
orcid: https://orcid.org/0000-0003-1013-6203
|
||||
title: "Enacting open science by D4Science"
|
||||
year: 2019
|
||||
journal: Future Generation Computer Systems
|
||||
volume: 101
|
||||
doi: 10.1016/j.future.2019.05.063
|
||||
url: https://doi.org/10.1016/j.future.2019.05.063
|
||||
- type: article
|
||||
authors:
|
||||
- family-names: Assante
|
||||
given-names: Massimiliano
|
||||
affiliation: "Istituto di Scienza e Tecnologie dell'Informazione (ISTI), Consiglio Nazionale delle Ricerche (CNR), Pisa, Italy"
|
||||
orcid: https://orcid.org/0000-0002-3761-1492
|
||||
- family-names: Candela
|
||||
given-names: Leonardo
|
||||
affiliation: "Istituto di Scienza e Tecnologie dell'Informazione (ISTI), Consiglio Nazionale delle Ricerche (CNR), Pisa, Italy"
|
||||
orcid: https://orcid.org/0000-0002-7279-2727
|
||||
- family-names: Castelli
|
||||
given-names: Donatella
|
||||
affiliation: "Istituto di Scienza e Tecnologie dell'Informazione (ISTI), Consiglio Nazionale delle Ricerche (CNR), Pisa, Italy"
|
||||
- family-names: Cirilllo
|
||||
given-names: Roberto
|
||||
affiliation: "Istituto di Scienza e Tecnologie dell'Informazione (ISTI), Consiglio Nazionale delle Ricerche (CNR), Pisa, Italy"
|
||||
orcid: https://orcid.org/0009-0006-2359-4202
|
||||
- family-names: Coro
|
||||
given-names: Gianpaolo
|
||||
affiliation: "Istituto di Scienza e Tecnologie dell'Informazione (ISTI), Consiglio Nazionale delle Ricerche (CNR), Pisa, Italy"
|
||||
orcid: https://orcid.org/0000-0001-7232-191X
|
||||
- family-names: Dell'Amico
|
||||
given-names: Andrea
|
||||
affiliation: "Istituto di Scienza e Tecnologie dell'Informazione (ISTI), Consiglio Nazionale delle Ricerche (CNR), Pisa, Italy"
|
||||
orcid: https://orcid.org/0000-0002-0127-2791
|
||||
- family-names: Frosini
|
||||
given-names: Luca
|
||||
affiliation: "Istituto di Scienza e Tecnologie dell'Informazione (ISTI), Consiglio Nazionale delle Ricerche (CNR), Pisa, Italy"
|
||||
orcid: https://orcid.org/0000-0003-3183-2291
|
||||
- family-names: Lelii
|
||||
given-names: Lucio
|
||||
affiliation: "Istituto di Scienza e Tecnologie dell'Informazione (ISTI), Consiglio Nazionale delle Ricerche (CNR), Pisa, Italy"
|
||||
orcid: https://orcid.org/0000-0001-7581-5325
|
||||
- family-names: Lettere
|
||||
given-names: Marco
|
||||
affiliation: "Nubisware S.r.l."
|
||||
- family-names: Mangiacrapa
|
||||
given-names: Francesco
|
||||
affiliation: "Istituto di Scienza e Tecnologie dell'Informazione (ISTI), Consiglio Nazionale delle Ricerche (CNR), Pisa, Italy"
|
||||
orcid: https://orcid.org/0000-0002-6528-664X
|
||||
- family-names: Pagano
|
||||
given-names: Pasquale
|
||||
affiliation: "Istituto di Scienza e Tecnologie dell'Informazione (ISTI), Consiglio Nazionale delle Ricerche (CNR), Pisa, Italy"
|
||||
orcid: https://orcid.org/0000-0001-6611-3209
|
||||
- family-names: Panichi
|
||||
given-names: Giancarlo
|
||||
affiliation: "Istituto di Scienza e Tecnologie dell'Informazione (ISTI), Consiglio Nazionale delle Ricerche (CNR), Pisa, Italy"
|
||||
orcid: https://orcid.org/0000-0001-8375-6644
|
||||
- family-names: Piccioli
|
||||
given-names: Tommaso
|
||||
affiliation: "Istituto di Scienza e Tecnologie dell'Informazione (ISTI), Consiglio Nazionale delle Ricerche (CNR), Pisa, Italy"
|
||||
orcid: https://orcid.org/0009-0009-2419-4261
|
||||
- family-names: Sinibaldi
|
||||
given-names: Fabio
|
||||
affiliation: "Istituto di Scienza e Tecnologie dell'Informazione (ISTI), Consiglio Nazionale delle Ricerche (CNR), Pisa, Italy"
|
||||
orcid: https://orcid.org/0000-0003-1013-6203
|
||||
title: "Virtual research environments co-creation: The D4Science experience"
|
||||
year: 2023
|
||||
journal: 'Concurrency and Computation: Practice and Experience'
|
||||
volume: 35
|
||||
doi: 10.1002/cpe.6925
|
||||
url: https://doi.org/10.1002/cpe.6925
|
||||
- type: article
|
||||
authors:
|
||||
- family-names: Candela
|
||||
given-names: Leonardo
|
||||
affiliation: "Istituto di Scienza e Tecnologie dell'Informazione (ISTI), Consiglio Nazionale delle Ricerche (CNR), Pisa, Italy"
|
||||
orcid: https://orcid.org/0000-0002-7279-2727
|
||||
- family-names: Castelli
|
||||
given-names: Donatella
|
||||
affiliation: "Istituto di Scienza e Tecnologie dell'Informazione (ISTI), Consiglio Nazionale delle Ricerche (CNR), Pisa, Italy"
|
||||
- family-names: Pagano
|
||||
given-names: Pasquale
|
||||
affiliation: "Istituto di Scienza e Tecnologie dell'Informazione (ISTI), Consiglio Nazionale delle Ricerche (CNR), Pisa, Italy"
|
||||
orcid: https://orcid.org/0000-0001-6611-3209
|
||||
title: "The D4Science Experience on Virtual Research Environment Development"
|
||||
year: 2023
|
||||
journal: 'Computing in Science & Engineering'
|
||||
volume: 25
|
||||
doi: 10.1109/MCSE.2023.3290433
|
||||
url: https://doi.org/10.1109/MCSE.2023.3290433
|
||||
72
FUNDING.md
72
FUNDING.md
|
|
@ -1,29 +1,51 @@
|
|||
# Acknowledgments
|
||||
# Funding
|
||||
|
||||
The projects leading to this software have received funding from a series of European Union programmes including:
|
||||
The **gCube Framework** and the **D4Science Research Infrastructure** have been developed and evolved through the support of multiple European and national research projects.
|
||||
|
||||
- the Sixth Framework Programme for Research and Technological Development
|
||||
- [DILIGENT](https://cordis.europa.eu/project/id/004260) (grant no. 004260).
|
||||
---
|
||||
|
||||
- the Seventh Framework Programme for research, technological development and demonstration
|
||||
- [D4Science](https://cordis.europa.eu/project/id/212488) (grant no. 212488);
|
||||
- [D4Science-II](https://cordis.europa.eu/project/id/239019) (grant no.239019);
|
||||
- [ENVRI](https://cordis.europa.eu/project/id/283465) (grant no. 283465);
|
||||
- [iMarine](https://cordis.europa.eu/project/id/283644) (grant no. 283644);
|
||||
- [EUBrazilOpenBio](https://cordis.europa.eu/project/id/288754) (grant no. 288754).
|
||||
## European Framework Programmes
|
||||
|
||||
- the H2020 research and innovation programme
|
||||
- [SoBigData](https://cordis.europa.eu/project/id/654024) (grant no. 654024);
|
||||
- [PARTHENOS](https://cordis.europa.eu/project/id/654119) (grant no. 654119);
|
||||
- [EGI-Engage](https://cordis.europa.eu/project/id/654142) (grant no. 654142);
|
||||
- [ENVRI PLUS](https://cordis.europa.eu/project/id/654182) (grant no. 654182);
|
||||
- [BlueBRIDGE](https://cordis.europa.eu/project/id/675680) (grant no. 675680);
|
||||
- [PerformFISH](https://cordis.europa.eu/project/id/727610) (grant no. 727610);
|
||||
- [AGINFRA PLUS](https://cordis.europa.eu/project/id/731001) (grant no. 731001);
|
||||
- [DESIRA](https://cordis.europa.eu/project/id/818194) (grant no. 818194);
|
||||
- [ARIADNEplus](https://cordis.europa.eu/project/id/823914) (grant no. 823914);
|
||||
- [RISIS 2](https://cordis.europa.eu/project/id/824091) (grant no. 824091);
|
||||
- [EOSC-Pillar](https://cordis.europa.eu/project/id/857650) (grant no. 857650);
|
||||
- [Blue Cloud](https://cordis.europa.eu/project/id/862409) (grant no. 862409);
|
||||
- [SoBigData-PlusPlus](https://cordis.europa.eu/project/id/871042) (grant no. 871042);
|
||||
|
||||
### FP6 - Sixth framework programme of the European Community for research, technological development and demonstration activities, contributing to the creation of the European Research Area and to innovation (2002 to 2006)
|
||||
|
||||
- [DILIGENT](https://cordis.europa.eu/project/id/004260) — A testbed digital library infrastructure on grid enabled technology (grant no. 004260)
|
||||
|
||||
### FP7 - Seventh framework programme of the European Community for research and technological development and demonstration activities (2007-2013)
|
||||
|
||||
- [D4Science](https://cordis.europa.eu/project/id/212488) — DIstributed colLaboratories Infrastructure on Grid ENabled Technology 4 Science (grant no. 212488)
|
||||
- [D4Science-II](https://cordis.europa.eu/project/id/239019) — Data Infrastructure Ecosystem for Science (grant no.239019)
|
||||
- [ENVRI](https://cordis.europa.eu/project/id/283465) — Common Operations of Environmental Research Infrastructures (grant no. 283465)
|
||||
- [iMarine](https://cordis.europa.eu/project/id/283644) — Data e-Infrastructure Initiative for Fisheries Management and Conservation of Marine Living Resources (grant no. 283644)
|
||||
- [EUBrazilOpenBio](https://cordis.europa.eu/project/id/288754) — EU-Brazil Open Data and Cloud Computing e-Infrastructure for Biodiversity (grant no. 288754)
|
||||
|
||||
### Horizon 2020 - the Framework Programme for Research and Innovation (2014-2020)
|
||||
- [SoBigData](https://cordis.europa.eu/project/id/654024) — SoBigData Research Infrastructure (grant no. 654024)
|
||||
- [PARTHENOS](https://cordis.europa.eu/project/id/654119) — Pooling Activities, Resources and Tools for Heritage E-research Networking, Optimization and Synergies (grant no. 654119)
|
||||
- [EGI-Engage](https://cordis.europa.eu/project/id/654142) — Engaging the EGI Community towards an Open Science Commons (grant no. 654142)
|
||||
- [ENVRI PLUS](https://cordis.europa.eu/project/id/654182) — Environmental Research Infrastructures Providing Shared Solutions for Science and Society (grant no. 654182)
|
||||
- [BlueBRIDGE](https://cordis.europa.eu/project/id/675680) — Building Research environments for fostering Innovation, Decision making, Governance and Education to support Blue growth (grant no. 675680)
|
||||
- [PerformFISH](https://cordis.europa.eu/project/id/727610) — Consumer driven Production: Integrating Innovative Approaches for Competitive and Sustainable Performance across the Mediterranean Aquaculture Value Chain (grant no. 727610)
|
||||
- [AGINFRA PLUS](https://cordis.europa.eu/project/id/731001) — Accelerating user-driven e-infrastructure innovation in Food Agriculture (grant no. 731001)
|
||||
- [DESIRA](https://cordis.europa.eu/project/id/818194) — Digitisation: Economic and Social Impacts in Rural Areas (grant no. 818194)
|
||||
- [ARIADNEplus](https://cordis.europa.eu/project/id/823914) — Advanced Research Infrastructure for Archaeological Data Networking in Europe - plus (grant no. 823914)
|
||||
- [RISIS 2](https://cordis.europa.eu/project/id/824091) — European Research Infrastructure for Science, technology and Innovation policy Studies 2 (grant no. 824091)
|
||||
- [EOSC-Pillar](https://cordis.europa.eu/project/id/857650) — Coordination and Harmonisation of National Inititiatives, Infrastructures and Data services in Central and Western Europe (grant no. 857650)
|
||||
- [Blue Cloud](https://cordis.europa.eu/project/id/862409) — Blue-Cloud: Piloting innovative services for Marine Research & the Blue Economy (grant no. 862409)
|
||||
- [I-GENE](https://cordis.europa.eu/project/id/862714) — In-vivo Gene Editing by NanotransducErs (grant. no. 862714)
|
||||
- [MOVING](https://cordis.europa.eu/project/id/862739) — Mountain Valorization through Interconnectedness and Green Growth (grant no. 862739)
|
||||
- [SoBigData-PlusPlus](https://cordis.europa.eu/project/id/871042) — SoBigData++: European Integrated Infrastructure for Social Mining and Big Data Analytics (grant no. 871042)
|
||||
|
||||
### Horizon Europe – the Framework Programme for Research and Innovation (2021 to 2027)
|
||||
- [SoBigData RI PPP](https://cordis.europa.eu/project/id/101079043) — SoBigData RI Preparatory Phase Project (grant no. 101079043)
|
||||
- [Blue-Cloud 2026](https://cordis.europa.eu/project/id/101094227) — A federated European FAIR and Open Research Ecosystem for oceans, seas, coastal and inland waters (grant no. 101094227)
|
||||
- [GreenDIGIT](https://cordis.europa.eu/project/id/101131207) — Greener Future Digital Research Infrastructures (grant no. 101131207)
|
||||
- [IRISCC](https://cordis.europa.eu/project/id/101131261) — Integrated Research Infrastructure Services for Climate Change risks (grant no. 101131261)
|
||||
|
||||
## Italian National Recovery and Resilience Plan (PNRR)
|
||||
- **FOSSR** — Fostering Open Science in Social Science Research - PNRR Missione 4 "Istruzione e Ricerca", Componente 2 "Dalla ricerca all'impresa", Linea di investimento 3.1 "Fondo per la realizzazione di un sistema integrato di infrastrutture di ricerca e innovazione"
|
||||
|
||||
- **IT-SERR** — Italian Strengthening of the ESFRI RI RESILIENCE - PNRR Missione 4 "Istruzione e Ricerca", Componente 2 "Dalla ricerca all'impresa", Linea di investimento 3.1 "Fondo per la realizzazione di un sistema integrato di infrastrutture di ricerca e innovazione"
|
||||
|
||||
- **RAISE** — Robotics and AI for Socio-economic Empowerment - PNRR Missione 4 "Istruzione e Ricerca", Componente 2 "Dalla ricerca all'impresa", Linea di investimento 1.5 "Creazione e rafforzamento di ''ecosistemi dell'innovazione''"
|
||||
|
||||
- **ITINERIS** — Italian Integrated Environmental Research Infrastructures System - PNRR Missione 4 "Istruzione e Ricerca", Componente 2 "Dalla ricerca all'impresa", Linea di investimento 3.1 "Fondo per la realizzazione di un sistema integrato di infrastrutture di ricerca e innovazione"
|
||||
|
|
|
|||
47
README.md
47
README.md
|
|
@ -1,39 +1,56 @@
|
|||
# Keycloak Client
|
||||
|
||||
**Keycloak Clienty** provides the basic common classes for OpenId Connect (OIDC) integration and some helper abstract functions for the gCube framework integration
|
||||
> Provides the basic common classes for OpenId Connect (OIDC) integration and some helper abstract functions for the gCube framework integration
|
||||
|
||||
## Structure of the project
|
||||
[](LICENSE.md)
|
||||
[](CHANGELOG.md)
|
||||
[](CITATION.cff)
|
||||
|
||||
The source code is present in `src` folder.
|
||||
## Table of contents
|
||||
- [Overview](#overview)
|
||||
- [Documentation](#documentation)
|
||||
- [Changelog](#changelog)
|
||||
- [Authors](#authors)
|
||||
- [How to cite](#how-to-cite)
|
||||
- [License](#license)
|
||||
- [About gCube](#about-gcube)
|
||||
- [Funding](#funding)
|
||||
|
||||
## Built With
|
||||
|
||||
* [OpenJDK](https://openjdk.java.net/) - The JDK used
|
||||
* [Maven](https://maven.apache.org/) - Dependency Management
|
||||
## Overview
|
||||
|
||||
* The source code is present in `src` folder.
|
||||
|
||||
|
||||
## Documentation
|
||||
|
||||
To build the library JAR it is sufficient to type
|
||||
* To build the library JAR it is sufficient to type
|
||||
|
||||
mvn clean package
|
||||
|
||||
## Change log
|
||||
## Changelog
|
||||
|
||||
See [Releases](https://code-repo.d4science.org/gCubeSystem/authorization-client/releases).
|
||||
See [CHANGELOG.md](CHANGELOG.md).
|
||||
|
||||
## Authors
|
||||
|
||||
* **Mauro Mugnaini** ([Nubisware S.r.l.](http://www.nubisware.com))
|
||||
|
||||
|
||||
## How to Cite
|
||||
|
||||
If you use this software, please cite it using the metadata in [CITATION.cff](CITATION.cff)
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the terms specified in the [LICENSE.md](LICENSE.md) file.
|
||||
|
||||
## About the gCube Framework
|
||||
## About gCube
|
||||
|
||||
This software is part of the [gCube Framework](https://www.gcube-system.org/): an open-source software toolkit used for building and operating Hybrid Data Infrastructures enabling the dynamic deployment of [Virtual Research Environments](https://en.wikipedia.org/wiki/Virtual_research_environment) by favouring the realisation of reuse oriented policies. The gCube Framework supports the development and operation of the [D4Science Infrastructure](https://www.d4science.org).
|
||||
|
||||
## Funding
|
||||
|
||||
See [FUNDING.md](FUNDING.md)
|
||||
|
||||
This software is part of the [gCubeFramework](https://www.gcube-system.org/gCubeFramework): an
|
||||
open-source software toolkit used for building and operating Hybrid Data
|
||||
Infrastructures enabling the dynamic deployment of Virtual Research Environments
|
||||
by favouring the realisation of reuse oriented policies.
|
||||
|
||||
The projects leading to this software have received funding from a series of European Union programmes see [FUNDING.md](FUNDING.md)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
<assembly
|
||||
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
|
||||
<id>servicearchive</id>
|
||||
<formats>
|
||||
<format>tar.gz</format>
|
||||
</formats>
|
||||
<baseDirectory>/</baseDirectory>
|
||||
<fileSets>
|
||||
<fileSet>
|
||||
<directory>.</directory>
|
||||
<outputDirectory>${file.separator}</outputDirectory>
|
||||
<useDefaultExcludes>true</useDefaultExcludes>
|
||||
<includes>
|
||||
<include>README.md</include>
|
||||
<include>LICENSE.md</include>
|
||||
<include>CHANGELOG.md</include>
|
||||
<include>FUNDING.md</include>
|
||||
<include>CITATION.cff</include>
|
||||
<include>profile.xml</include>
|
||||
<include>images</include>
|
||||
<include>images/**</include>
|
||||
</includes>
|
||||
<fileMode>755</fileMode>
|
||||
<filtered>true</filtered>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
<files>
|
||||
<file>
|
||||
<source>target${file.separator}${build.finalName}.${project.packaging}</source>
|
||||
<outputDirectory>${file.separator}${artifactId}</outputDirectory>
|
||||
</file>
|
||||
</files>
|
||||
</assembly>
|
||||
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="176" height="20" role="img" aria-label="Changelog: keep a changelog"><title>Changelog: keep a changelog</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="176" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="69" height="20" fill="#555"/><rect x="69" width="107" height="20" fill="#4c1"/><rect width="176" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text aria-hidden="true" x="355" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="590">Changelog</text><text x="355" y="140" transform="scale(.1)" fill="#fff" textLength="590">Changelog</text><text aria-hidden="true" x="1215" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="970">keep a changelog</text><text x="1215" y="140" transform="scale(.1)" fill="#fff" textLength="970">keep a changelog</text></g></svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="114" height="20" role="img" aria-label="Cite: CITATION.cff"><title>Cite: CITATION.cff</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="114" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="31" height="20" fill="#555"/><rect x="31" width="83" height="20" fill="#fe7d37"/><rect width="114" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text aria-hidden="true" x="165" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="210">Cite</text><text x="165" y="140" transform="scale(.1)" fill="#fff" textLength="210">Cite</text><text aria-hidden="true" x="715" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="730">CITATION.cff</text><text x="715" y="140" transform="scale(.1)" fill="#fff" textLength="730">CITATION.cff</text></g></svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="112" height="20" role="img" aria-label="License: EUPL-1.2"><title>License: EUPL-1.2</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="112" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="51" height="20" fill="#555"/><rect x="51" width="61" height="20" fill="#007ec6"/><rect width="112" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text aria-hidden="true" x="265" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="410">License</text><text x="265" y="140" transform="scale(.1)" fill="#fff" textLength="410">License</text><text aria-hidden="true" x="805" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="510">EUPL-1.2</text><text x="805" y="140" transform="scale(.1)" fill="#fff" textLength="510">EUPL-1.2</text></g></svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
85
pom.xml
85
pom.xml
|
|
@ -12,35 +12,51 @@
|
|||
|
||||
<groupId>org.gcube.common</groupId>
|
||||
<artifactId>keycloak-client</artifactId>
|
||||
<version>2.2.0-SNAPSHOT</version>
|
||||
<version>2.4.0</version>
|
||||
|
||||
<scm>
|
||||
<connection>
|
||||
scm:git:https://code-repo.d4science.org/gCubeSystem/${project.artifactId}-jdk8.git</connection>
|
||||
<developerConnection>
|
||||
scm:git:https://code-repo.d4science.org/gCubeSystem/${project.artifactId}-jdk8.git</developerConnection>
|
||||
<url>https://code-repo.d4science.org/gCubeSystem/${project.artifactId}-jdk8</url>
|
||||
</scm>
|
||||
|
||||
<developers>
|
||||
<developer>
|
||||
<name>Mauro Mugnaini</name>
|
||||
<email>mauro.mugnaini@nubisware.com</email>
|
||||
<organization>CNR Pisa, Istituto di Scienza e Tecnologie dell'Informazione "A. Faedo"</organization>
|
||||
<roles>
|
||||
<role>architect</role>
|
||||
<role>developer</role>
|
||||
</roles>
|
||||
</developer>
|
||||
</developers>
|
||||
|
||||
<properties>
|
||||
<!-- Java -->
|
||||
<java.version>1.8</java.version>
|
||||
<maven.compiler.source>${java.version}</maven.compiler.source>
|
||||
<maven.compiler.target>${java.version}</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<jjwt.version>0.12.6</jjwt.version>
|
||||
</properties>
|
||||
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.gcube.distribution</groupId>
|
||||
<artifactId>gcube-bom</artifactId>
|
||||
<version>2.4.1-SNAPSHOT</version>
|
||||
<version>2.4.1</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<scm>
|
||||
<connection>
|
||||
scm:git:https://code-repo.d4science.org/gCubeSystem/${project.artifactId}.git</connection>
|
||||
<developerConnection>
|
||||
scm:git:https://code-repo.d4science.org/gCubeSystem/${project.artifactId}.git</developerConnection>
|
||||
<url>https://code-repo.d4science.org/gCubeSystem/${project.artifactId}</url>
|
||||
</scm>
|
||||
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
<maven.compiler.source>${java.version}</maven.compiler.source>
|
||||
<maven.compiler.target>${java.version}</maven.compiler.target>
|
||||
<jjwt.version>0.12.6</jjwt.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
|
|
@ -105,7 +121,7 @@
|
|||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<version>1.2.16</version>
|
||||
<version>1.2.17</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
|
@ -129,4 +145,37 @@
|
|||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>${maven.compiler.source}</source>
|
||||
<target>${maven.compiler.target}</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<configuration>
|
||||
<descriptors>
|
||||
<descriptor>descriptor.xml</descriptor>
|
||||
</descriptors>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>servicearchive</id>
|
||||
<phase>install</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Resource>
|
||||
<ID></ID>
|
||||
<Type>Library</Type>
|
||||
<Profile>
|
||||
<Description>${project.description}</Description>
|
||||
<Class>Common</Class>
|
||||
<Name>${project.name}</Name>
|
||||
<Version>1.0.0</Version>
|
||||
<Packages>
|
||||
<Software>
|
||||
<Name>${project.name}</Name>
|
||||
<Description>${project.description}</Description>
|
||||
<Version>${version}</Version>
|
||||
<MavenCoordinates>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>${project.artifactId}</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</MavenCoordinates>
|
||||
<Files>
|
||||
<File>${project.build.finalName}.${project.packaging}</File>
|
||||
</Files>
|
||||
</Software>
|
||||
</Packages>
|
||||
</Profile>
|
||||
</Resource>
|
||||
|
||||
|
||||
|
|
@ -35,7 +35,6 @@ import java.net.MalformedURLException;
|
|||
import java.net.URL;
|
||||
import java.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
import java.util.Collections;
|
||||
|
|
@ -66,7 +65,7 @@ public class DefaultKeycloakClient implements KeycloakClient {
|
|||
|
||||
private String customBaseURL = null;
|
||||
|
||||
private List<String> scopes = new ArrayList<>();
|
||||
private String scope = null;
|
||||
|
||||
private boolean useDynamicScopeInsteadOfCustomHeaderForContextRestricion = false;
|
||||
|
||||
|
|
@ -79,37 +78,22 @@ public class DefaultKeycloakClient implements KeycloakClient {
|
|||
}
|
||||
|
||||
@Override
|
||||
public KeycloakClient useScopes(List<String> scopes) {
|
||||
this.scopes.clear();
|
||||
this.scopes.addAll(scopes);
|
||||
public KeycloakClient useScope(String scope) {
|
||||
this.scope = scope;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeycloakClient addScopes(List<String> scopes) {
|
||||
this.scopes.addAll(scopes);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeycloakClient removeScopes(List<String> scopes) {
|
||||
this.scopes.removeAll(scopes);
|
||||
public KeycloakClient removeScope() {
|
||||
this.scope = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeycloakClient addDynamicScope(String dynamicScope, String value) {
|
||||
this.scopes.add(constructDynamicScope(dynamicScope, value));
|
||||
return this;
|
||||
}
|
||||
this.scope = (this.scope != null && !"".equals(this.scope) ? this.scope + " " : "")
|
||||
+ KeycloakClient.constructDynamicScope(dynamicScope, value);
|
||||
|
||||
protected static String constructDynamicScope(String dynamicScope, String value) {
|
||||
return dynamicScope + DEFAULT_DYNAMIC_SCOPE_SEPARATOR + value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeycloakClient removeAllScopes() {
|
||||
this.scopes.clear();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
@ -461,9 +445,7 @@ public class DefaultKeycloakClient implements KeycloakClient {
|
|||
params.put(USERNAME_PARAMETER, Arrays.asList(username));
|
||||
params.put(PASSWORD_PARAMETER, Arrays.asList(password));
|
||||
|
||||
if (scopes != null && scopes.size() > 0) {
|
||||
params.put(SCOPE_PARAMETER, new ArrayList<>(scopes));
|
||||
}
|
||||
String scopeParam = this.scope != null ? new String(this.scope) : "";
|
||||
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
logger.debug("Adding authorization header as: {}", authorization);
|
||||
|
|
@ -475,19 +457,17 @@ public class DefaultKeycloakClient implements KeycloakClient {
|
|||
|
||||
if (audience != null) {
|
||||
if (useDynamicScopeInsteadOfCustomHeaderForContextRestricion) {
|
||||
String dynamicScope = constructDynamicScope(D4S_DYNAMIC_SCOPE_NAME, audience);
|
||||
if (params.containsKey(SCOPE_PARAMETER)) {
|
||||
logger.debug("Adding d4s dynamic scope to existing scopes param: {}", dynamicScope);
|
||||
params.get(SCOPE_PARAMETER).add(dynamicScope);
|
||||
} else {
|
||||
logger.debug("Adding d4s dynamic scope as scopes param: {}", dynamicScope);
|
||||
params.put(SCOPE_PARAMETER, Collections.singletonList(dynamicScope));
|
||||
}
|
||||
String dynamicScope = KeycloakClient.constructDynamicScope(D4S_DYNAMIC_SCOPE_NAME, audience);
|
||||
logger.debug("Adding d4s dynamic scope to existing scopes param: {}", dynamicScope);
|
||||
scopeParam += (!"".equals(scopeParam) ? " " : "") + dynamicScope;
|
||||
} else {
|
||||
logger.debug("Adding d4s context header as: {}", audience);
|
||||
headers.put(D4S_CONTEXT_HEADER_NAME, audience);
|
||||
}
|
||||
}
|
||||
if (scopeParam != null && !"".equals(scopeParam)) {
|
||||
params.put(SCOPE_PARAMETER, Collections.singletonList(scopeParam));
|
||||
}
|
||||
|
||||
return performRequest(tokenURL, headers, params);
|
||||
}
|
||||
|
|
@ -501,8 +481,8 @@ public class DefaultKeycloakClient implements KeycloakClient {
|
|||
Map<String, List<String>> params = new HashMap<>();
|
||||
params.put(GRANT_TYPE_PARAMETER, Arrays.asList(CLIENT_CREDENTIALS_GRANT_TYPE));
|
||||
|
||||
if (scopes != null && scopes.size() > 0) {
|
||||
params.put(SCOPE_PARAMETER, new ArrayList<>(scopes));
|
||||
if (this.scope != null && !"".equals(this.scope)) {
|
||||
params.put(SCOPE_PARAMETER, Collections.singletonList(this.scope));
|
||||
}
|
||||
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
|
|
@ -511,7 +491,7 @@ public class DefaultKeycloakClient implements KeycloakClient {
|
|||
|
||||
if (audience != null) {
|
||||
if (useDynamicScopeInsteadOfCustomHeaderForContextRestricion) {
|
||||
String dynamicScope = constructDynamicScope(D4S_DYNAMIC_SCOPE_NAME, audience);
|
||||
String dynamicScope = KeycloakClient.constructDynamicScope(D4S_DYNAMIC_SCOPE_NAME, audience);
|
||||
if (params.containsKey(SCOPE_PARAMETER)) {
|
||||
logger.debug("Adding d4s dynamic scope to existing scopes param: {}", dynamicScope);
|
||||
params.get(SCOPE_PARAMETER).add(dynamicScope);
|
||||
|
|
@ -606,6 +586,10 @@ public class DefaultKeycloakClient implements KeycloakClient {
|
|||
}).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
if (this.scope != null && !"".equals(this.scope)) {
|
||||
params.put(SCOPE_PARAMETER, Collections.singletonList(this.scope));
|
||||
}
|
||||
|
||||
return performRequest(tokenURL, headers, params);
|
||||
}
|
||||
|
||||
|
|
@ -616,8 +600,7 @@ public class DefaultKeycloakClient implements KeycloakClient {
|
|||
}
|
||||
|
||||
protected <T> T performRequest(Class<T> returnObjectClass, URL url, Map<String, String> headers,
|
||||
Map<String, List<String>> params)
|
||||
throws KeycloakClientException {
|
||||
Map<String, List<String>> params) throws KeycloakClientException {
|
||||
|
||||
if (url == null) {
|
||||
throw new KeycloakClientException("Token URL must be not null");
|
||||
|
|
@ -650,8 +633,8 @@ public class DefaultKeycloakClient implements KeycloakClient {
|
|||
request.header(headerName, headers.get(headerName));
|
||||
}
|
||||
} else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("HTTP headers map is null");
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("HTTP headers map is null");
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
|
@ -698,6 +681,9 @@ public class DefaultKeycloakClient implements KeycloakClient {
|
|||
|
||||
return new ObjectMapper().readValue(sb.toString(), returnObjectClass);
|
||||
} catch (Exception e) {
|
||||
if (e instanceof KeycloakClientException) {
|
||||
throw (KeycloakClientException) e;
|
||||
}
|
||||
throw new KeycloakClientException("Cannot construct token response object correctly", e);
|
||||
}
|
||||
}
|
||||
|
|
@ -782,6 +768,10 @@ public class DefaultKeycloakClient implements KeycloakClient {
|
|||
Collections.singletonList(URLEncoder.encode(clientSecret, "UTF-8")));
|
||||
}
|
||||
|
||||
if (this.scope != null && !"".equals(this.scope)) {
|
||||
params.put(SCOPE_PARAMETER, Collections.singletonList(this.scope));
|
||||
}
|
||||
|
||||
return performRequest(tokenURL, null, params);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new KeycloakClientException("Cannot encode parameters", e);
|
||||
|
|
@ -802,7 +792,7 @@ public class DefaultKeycloakClient implements KeycloakClient {
|
|||
String clientSecret, String audience) throws KeycloakClientException {
|
||||
|
||||
return exchangeToken(tokenURL, oidcAccessToken, clientId, clientSecret, audience, ACCESS_TOKEN_TOKEN_TYPE,
|
||||
null);
|
||||
this.scope);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -818,7 +808,7 @@ public class DefaultKeycloakClient implements KeycloakClient {
|
|||
String clientSecret, String audience) throws KeycloakClientException {
|
||||
|
||||
return exchangeToken(tokenURL, oidcAccessToken, clientId, clientSecret, audience, REFRESH_TOKEN_TOKEN_TYPE,
|
||||
null);
|
||||
this.scope);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -843,14 +833,18 @@ public class DefaultKeycloakClient implements KeycloakClient {
|
|||
logger.info("Token to be exchanged doesn't contain 'offline_token' within scopes");
|
||||
throw new IllegalArgumentException("Orignal access token doesn't contain the 'offline_token' scope");
|
||||
}
|
||||
String scopeParam = this.scope != null ? this.scope : "";
|
||||
|
||||
if (scopeParam.indexOf(OFFLINE_ACCESS_SCOPE) < 0) {
|
||||
scopeParam += (!"".equals(scopeParam) ? scopeParam : " ") + OFFLINE_ACCESS_SCOPE;
|
||||
}
|
||||
return exchangeToken(tokenURL, oidcAccessToken, clientId, clientSecret, audience, REFRESH_TOKEN_TOKEN_TYPE,
|
||||
OFFLINE_ACCESS_SCOPE);
|
||||
scopeParam);
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries from the OIDC server an exchanged token by using provided access
|
||||
* token, for the given audience (context),
|
||||
* in URLEncoded form or not,
|
||||
* token, for the given audience (context), in URLEncoded form or not.
|
||||
*
|
||||
* @param tokenURL the token endpoint {@link URL} of the OIDC server
|
||||
* @param oidcAccessToken the auth token (the access token URLEncoded by the
|
||||
|
|
@ -858,9 +852,10 @@ public class DefaultKeycloakClient implements KeycloakClient {
|
|||
* @param clientId the client id
|
||||
* @param clientSecret the client secret
|
||||
* @param audience the audience (context) where to request the issuing
|
||||
* of the ticket (URLEncoded)
|
||||
* of the token (URLEncoded), may be null
|
||||
* @param requestedTokenType the token type (e.g. <code>refresh</code>)
|
||||
* @param scope the scope, optional can be <code>null</code>
|
||||
* @param scope the scope (as standard space separated list), optional can be <code>null</code>.
|
||||
* If provided override the scopes set as defaults for this client
|
||||
* @return the issued exchanged token
|
||||
* @throws KeycloakClientException if an error occurs, inspect the exception for
|
||||
* details
|
||||
|
|
@ -868,10 +863,6 @@ public class DefaultKeycloakClient implements KeycloakClient {
|
|||
protected TokenResponse exchangeToken(URL tokenURL, String oidcAccessToken, String clientId, String clientSecret,
|
||||
String audience, String requestedTokenType, String scope) throws KeycloakClientException {
|
||||
|
||||
if (audience == null || "".equals(audience)) {
|
||||
throw new KeycloakClientException("Audience must be not null nor empty");
|
||||
}
|
||||
|
||||
logger.debug("Exchanging token from Keycloak server with URL: {}", tokenURL);
|
||||
|
||||
Map<String, List<String>> params = new HashMap<>();
|
||||
|
|
@ -881,16 +872,19 @@ public class DefaultKeycloakClient implements KeycloakClient {
|
|||
params.put(GRANT_TYPE_PARAMETER, Arrays.asList(TOKEN_EXCHANGE_GRANT_TYPE));
|
||||
params.put(SUBJECT_TOKEN_TYPE_PARAMETER, Arrays.asList(ACCESS_TOKEN_TOKEN_TYPE));
|
||||
params.put(REQUESTED_TOKEN_TYPE_PARAMETER, Arrays.asList(requestedTokenType));
|
||||
|
||||
if (scope != null) {
|
||||
params.put(SCOPE_PARAMETER, Arrays.asList(scope));
|
||||
params.put(SCOPE_PARAMETER, Collections.singletonList(scope));
|
||||
}
|
||||
|
||||
try {
|
||||
String audienceToSend = URLEncoder.encode(checkAudience(audience), "UTF-8");
|
||||
params.put(AUDIENCE_PARAMETER, Arrays.asList(audienceToSend));
|
||||
logger.trace("audience is {}", audienceToSend);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
logger.error("Can't URL encode audience: {}", audience, e);
|
||||
if (audience != null && !"".equals(audience)) {
|
||||
try {
|
||||
String audienceToSend = URLEncoder.encode(checkAudience(audience), "UTF-8");
|
||||
params.put(AUDIENCE_PARAMETER, Arrays.asList(audienceToSend));
|
||||
logger.trace("audience is {}", audienceToSend);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
logger.error("Can't URL encode audience: {}", audience, e);
|
||||
}
|
||||
}
|
||||
|
||||
return performRequest(tokenURL, null, params);
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ public interface KeycloakClient {
|
|||
public static final String D4S_DYNAMIC_SCOPE_NAME = "d4s-context";
|
||||
public static final String D4S_DYNAMIC_SCOPE_NAME_TOKEN_CLAIM = "d4s_context";
|
||||
public static final String DEFAULT_DYNAMIC_SCOPE_SEPARATOR = ":";
|
||||
public static final String ROOT_DYNAMIC_SCOPE_FOR_ENABLING = "/*";
|
||||
|
||||
public static String DEFAULT_REALM = "d4science";
|
||||
|
||||
|
|
@ -30,38 +31,10 @@ public interface KeycloakClient {
|
|||
* Replaces the list of the provided OIDC scopes for the next OIDC token
|
||||
* requests
|
||||
*
|
||||
* @param scopes the list of scopes to use in the calls
|
||||
* @param scope the list of scopes to use in the calls as standard space separated list
|
||||
* @return the client itself
|
||||
*/
|
||||
KeycloakClient useScopes(List<String> scopes);
|
||||
|
||||
/**
|
||||
* Adds the provided OIDC scopes to the list of scopes to use for the next OIDC
|
||||
* token requests
|
||||
*
|
||||
* @param scopes the list of scopes to add
|
||||
* @return the client itself
|
||||
*/
|
||||
KeycloakClient addScopes(List<String> scopes);
|
||||
|
||||
/**
|
||||
* Adds the dynamic scope to the list of scopes to use for the next OIDC token
|
||||
* requests
|
||||
*
|
||||
* @param dynamicScope the dynamic scope that will be the prefix
|
||||
* @param value the value of the dynamic scope
|
||||
* @return the client itself
|
||||
*/
|
||||
KeycloakClient addDynamicScope(String dynamicScope, String value);
|
||||
|
||||
/**
|
||||
* Removes the provided OIDC scopes from the list of scopes to use for the next
|
||||
* OIDC token requests
|
||||
*
|
||||
* @param scopes the list of scopes to remove
|
||||
* @return the client itself
|
||||
*/
|
||||
KeycloakClient removeScopes(List<String> scopes);
|
||||
KeycloakClient useScope(String scope);
|
||||
|
||||
/**
|
||||
* Removes all the custom OIDC scopes from the list of scopes to use the next
|
||||
|
|
@ -69,7 +42,23 @@ public interface KeycloakClient {
|
|||
*
|
||||
* @return the client itself
|
||||
*/
|
||||
KeycloakClient removeAllScopes();
|
||||
KeycloakClient removeScope();
|
||||
|
||||
/**
|
||||
* Adds the dynamic scope to default scope, if present, to be used use for the next OIDC token
|
||||
* requests. If the default scope isn't set the dynamic scope will be considered the only one scope
|
||||
* to be used.
|
||||
*
|
||||
* @param dynamicScope the dynamic scope that will be the prefix
|
||||
* @param value the value of the dynamic scope
|
||||
* @return the client itself
|
||||
*/
|
||||
KeycloakClient addDynamicScope(String dynamicScope, String value);
|
||||
|
||||
|
||||
public static String constructDynamicScope(String dynamicScope, String value) {
|
||||
return dynamicScope + DEFAULT_DYNAMIC_SCOPE_SEPARATOR + value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a flag to use dynamic scope ({@link #D4S_DYNAMIC_SCOPE_NAME} =
|
||||
|
|
@ -516,8 +505,8 @@ public interface KeycloakClient {
|
|||
* @param password the user's password
|
||||
* @param audience an optional parameter to shrink the token's audience to
|
||||
* the requested one (e.g. a specific context), by
|
||||
* leveraging on the custom HTTP header and corresponding
|
||||
* mapper on Keycloak
|
||||
* leveraging on the custom HTTP header or dynamic context and corresponding
|
||||
* mappers on Keycloak
|
||||
* @return the issued token as {@link TokenResponse} object
|
||||
* @throws KeycloakClientException if something goes wrong performing the query
|
||||
*/
|
||||
|
|
@ -538,10 +527,10 @@ public interface KeycloakClient {
|
|||
* @param clientSecret the client secret
|
||||
* @param username the user's username
|
||||
* @param password the user's password
|
||||
* @param audience an optional parameter to shrink the token's audience to
|
||||
* the requested one (e.g. a specific context), by
|
||||
* leveraging on the custom HTTP header and corresponding
|
||||
* mapper on Keycloak
|
||||
* @param audience an optional parameter to shrink the token's audience to
|
||||
* the requested one (e.g. a specific context), by
|
||||
* leveraging on the custom HTTP header or dynamic context and corresponding
|
||||
* mappers on Keycloak
|
||||
* @return the issued token as {@link TokenResponse} object
|
||||
* @throws KeycloakClientException if something goes wrong performing the query
|
||||
*/
|
||||
|
|
@ -563,10 +552,10 @@ public interface KeycloakClient {
|
|||
* @param clientSecret the client secret
|
||||
* @param username the user's username
|
||||
* @param password the user's password
|
||||
* @param audience an optional parameter to shrink the token's audience to
|
||||
* the requested one (e.g. a specific context), by
|
||||
* leveraging on the custom HTTP header and corresponding
|
||||
* mapper on Keycloak
|
||||
* @param audience an optional parameter to shrink the token's audience to
|
||||
* the requested one (e.g. a specific context), by
|
||||
* leveraging on the custom HTTP header or dynamic context and corresponding
|
||||
* mappers on Keycloak
|
||||
* @param extraHeaders extra HTTP headers to add to the request
|
||||
* @return the issued token as {@link TokenResponse} object
|
||||
* @throws KeycloakClientException if something goes wrong performing the query
|
||||
|
|
@ -588,10 +577,10 @@ public interface KeycloakClient {
|
|||
* @param clientSecret the client secret
|
||||
* @param username the user's username
|
||||
* @param password the user's password
|
||||
* @param audience an optional parameter to shrink the token's audience to
|
||||
* the requested one (e.g. a specific context), by
|
||||
* leveraging on the custom HTTP header and corresponding
|
||||
* mapper on Keycloak
|
||||
* @param audience an optional parameter to shrink the token's audience to
|
||||
* the requested one (e.g. a specific context), by
|
||||
* leveraging on the custom HTTP header or dynamic context and corresponding
|
||||
* mappers on Keycloak
|
||||
* @return the issued token as {@link TokenResponse} object
|
||||
* @throws KeycloakClientException if something goes wrong performing the query
|
||||
*/
|
||||
|
|
@ -609,10 +598,10 @@ public interface KeycloakClient {
|
|||
* @param clientSecret the client secret
|
||||
* @param username the user's username
|
||||
* @param password the user's password
|
||||
* @param audience an optional parameter to shrink the token's audience to
|
||||
* the requested one (e.g. a specific context), by
|
||||
* leveraging on the custom HTTP header and corresponding
|
||||
* mapper on Keycloak
|
||||
* @param audience an optional parameter to shrink the token's audience to
|
||||
* the requested one (e.g. a specific context), by
|
||||
* leveraging on the custom HTTP header or dynamic context and corresponding
|
||||
* mappers on Keycloak
|
||||
* @param extraHeaders extra HTTP headers to add to the request
|
||||
* @return the issued token as {@link TokenResponse} object
|
||||
* @throws KeycloakClientException if something goes wrong performing the query
|
||||
|
|
@ -636,8 +625,8 @@ public interface KeycloakClient {
|
|||
* @param password the user's password
|
||||
* @param audience an optional parameter to shrink the token's audience to
|
||||
* the requested one (e.g. a specific context), by
|
||||
* leveraging on the custom HTTP header and corresponding
|
||||
* mapper on Keycloak
|
||||
* leveraging on the custom HTTP header or dynamic context and corresponding
|
||||
* mappers on Keycloak
|
||||
* @param extraHeaders extra HTTP headers to add to the request
|
||||
* @return the issued token as {@link TokenResponse} object
|
||||
* @throws KeycloakClientException if something goes wrong performing the query
|
||||
|
|
@ -658,8 +647,8 @@ public interface KeycloakClient {
|
|||
* @param password the user's password
|
||||
* @param audience an optional parameter to shrink the token's audience to
|
||||
* the requested one (e.g. a specific context), by
|
||||
* leveraging on the custom HTTP header and corresponding
|
||||
* mapper on Keycloak
|
||||
* leveraging on the custom HTTP header or dynamic context and corresponding
|
||||
* mappers on Keycloak
|
||||
* @return the issued token as {@link TokenResponse} object
|
||||
* @throws KeycloakClientException if something goes wrong performing the query
|
||||
*/
|
||||
|
|
@ -680,8 +669,8 @@ public interface KeycloakClient {
|
|||
* @param password the user's password
|
||||
* @param audience an optional parameter to shrink the token's audience to
|
||||
* the requested one (e.g. a specific context), by
|
||||
* leveraging on the custom HTTP header and corresponding
|
||||
* mapper on Keycloak
|
||||
* leveraging on the custom HTTP header or dynamic context and corresponding
|
||||
* mappers on Keycloak
|
||||
* @param extraHeaders extra HTTP headers to add to the request
|
||||
* @return the issued token as {@link TokenResponse} object
|
||||
* @throws KeycloakClientException if something goes wrong performing the query
|
||||
|
|
@ -925,7 +914,7 @@ public interface KeycloakClient {
|
|||
* @param oidcAccessToken the original access token to exchange
|
||||
* @param clientId the authorized client's id
|
||||
* @param clientSecret the authorized client's secret
|
||||
* @param audience the requested token audience
|
||||
* @param audience the requested token audience, can be <code>null</code>
|
||||
* @return the exchanged token response
|
||||
* @throws KeycloakClientException if an error occurs during the exchange
|
||||
*/
|
||||
|
|
@ -940,7 +929,7 @@ public interface KeycloakClient {
|
|||
* @param oidcAccessToken the original access token to exchange
|
||||
* @param clientId the authorized client's id
|
||||
* @param clientSecret the authorized client's secret
|
||||
* @param audience the requested token audience
|
||||
* @param audience the requested token audience, can be <code>null</code>
|
||||
* @return the exchanged token response
|
||||
* @throws KeycloakClientException if an error occurs during the exchange
|
||||
*/
|
||||
|
|
@ -956,7 +945,7 @@ public interface KeycloakClient {
|
|||
* @param oidcAccessToken the original access token to exchange
|
||||
* @param clientId the authorized client's id
|
||||
* @param clientSecret the authorized client's secret
|
||||
* @param audience the requested token audience
|
||||
* @param audience the requested token audience, can be <code>null</code>
|
||||
* @return the exchanged token response
|
||||
* @throws KeycloakClientException if an error occurs during the exchange
|
||||
*/
|
||||
|
|
@ -971,7 +960,7 @@ public interface KeycloakClient {
|
|||
* @param oidcAccessToken the original access token to exchange
|
||||
* @param clientId the authorized client's id
|
||||
* @param clientSecret the authorized client's secret
|
||||
* @param audience the requested token audience
|
||||
* @param audience the requested token audience, can be <code>null</code>
|
||||
* @return the exchanged token response
|
||||
* @throws KeycloakClientException if an error occurs during the exchange
|
||||
*/
|
||||
|
|
@ -988,7 +977,7 @@ public interface KeycloakClient {
|
|||
* @param oidcAccessToken the original access token to exchange
|
||||
* @param clientId the authorized client's id
|
||||
* @param clientSecret the authorized client's secret
|
||||
* @param audience the requested token audience
|
||||
* @param audience the requested token audience, can be <code>null</code>
|
||||
* @return the exchanged token response
|
||||
* @throws IllegalArgumentException if the original token does'nt contains the
|
||||
* <code>offline_access</code> scope within its
|
||||
|
|
@ -1009,7 +998,7 @@ public interface KeycloakClient {
|
|||
* @param oidcAccessToken the original access token to exchange
|
||||
* @param clientId the authorized client's id
|
||||
* @param clientSecret the authorized client's secret
|
||||
* @param audience the requested token audience
|
||||
* @param audience the requested token audience, can be <code>null</code>
|
||||
* @return the exchanged token response
|
||||
* @throws IllegalArgumentException if the original token does'nt contains the
|
||||
* <code>offline_access</code> scope within its
|
||||
|
|
|
|||
|
|
@ -106,7 +106,9 @@ public class ModelUtils {
|
|||
}
|
||||
|
||||
/**
|
||||
* Verifies the token validity
|
||||
* Verifies the token validity and ignores the token's expiration if the <code>checkExpiration</code> parameter is set to <code>false</code>.
|
||||
* NOTE: In the implementation library the expiration check is performed at the end, after the signature and JWT structure checks, for that reason
|
||||
* ignoring the expiration doesn't affect other checks and it is safe.
|
||||
*
|
||||
* @param token the base64 JWT token string
|
||||
* @param publicKey the public key to use for verification
|
||||
|
|
|
|||
|
|
@ -41,7 +41,8 @@ public class TestKeycloakClient {
|
|||
|
||||
protected static final String GATEWAY = "next.dev.d4science.org";
|
||||
// protected static final String GATEWAY = "next.pre.d4science.org";
|
||||
protected static final String TOKEN_RESTRICTION_VRE_CONTEXT = "%2Fgcube%2Fdevsec%2FCCP";
|
||||
protected static final String TOKEN_RESTRICTION_VRE_CONTEXT = "%2Fgcube%2Fdevsec%2FdevVRE";
|
||||
protected static final String CCP_VRE_CONTEXT = "%2Fgcube%2Fdevsec%2FCCP";
|
||||
protected static final String CLIENT_ID = "keycloak-client-unit-test";
|
||||
protected static final String CLIENT_SECRET = "ebf6f82e-9511-408e-8321-203081e472d8";
|
||||
// protected static final String CLIENT_SECRET =
|
||||
|
|
@ -235,7 +236,7 @@ public class TestKeycloakClient {
|
|||
TestModelUtils.checkAccessToken(ModelUtils.getAccessTokenFrom(oidcTR), TEST_USER_USERNAME, true);
|
||||
TestModelUtils.checkAccessToken(ModelUtils.getAccessTokenFrom(oidcRestrictedTR), TEST_USER_USERNAME, true);
|
||||
assertTrue(ModelUtils.getAccessTokenFrom(oidcTR).getAudience().length > 1);
|
||||
assertTrue(ModelUtils.getAccessTokenFrom(oidcRestrictedTR).getAudience().length == 1);
|
||||
assertEquals(1, ModelUtils.getAccessTokenFrom(oidcRestrictedTR).getAudience().length);
|
||||
assertTrue(
|
||||
TOKEN_RESTRICTION_VRE_CONTEXT.equals(ModelUtils.getAccessTokenFrom(oidcRestrictedTR).getAudience()[0]));
|
||||
}
|
||||
|
|
@ -274,7 +275,7 @@ public class TestKeycloakClient {
|
|||
|
||||
TestModelUtils.checkTokenResponse(oidcTR);
|
||||
TestModelUtils.checkAccessToken(ModelUtils.getAccessTokenFrom(oidcTR), TEST_USER_USERNAME, true);
|
||||
assertTrue(ModelUtils.getAccessTokenFrom(oidcTR).getAudience().length == 1);
|
||||
assertEquals("Audience length is not 1", 1, ModelUtils.getAccessTokenFrom(oidcTR).getAudience().length);
|
||||
// It is not possible to check programmatically if the header has been added to
|
||||
// the call, See the logs if the Header is present.
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue