Skip to content

Commit

Permalink
Merge pull request #83 from consiglionazionaledellericerche/63-integr…
Browse files Browse the repository at this point in the history
…azione-con-con-lautenticazione-di-attestati-tramite-idp-sso-del-cnr

Introdotta autenticazione su attestati tramite JWT di SSO CNR.
  • Loading branch information
criluc authored Nov 17, 2023
2 parents 3a3d79e + 04d6ba1 commit 0f581e5
Show file tree
Hide file tree
Showing 8 changed files with 142 additions and 5 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [2.10.0] - 2023-11-17
### Added
- Aggiunta possibilità di comunicazione tra ePAS ed Attestati (CNR) tramite token JWT
rilascio dall'SSO del CNR.

## [2.9.2] - 2023-11-14
### Added
- Aggiunto il codice 31_2022 per la gestione delle assenze del 2022 nell'anno 2024
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.9.2
2.10.0
11 changes: 11 additions & 0 deletions app/controllers/Administration.java
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
import manager.UserManager;
import manager.attestati.dto.internal.clean.ContrattoAttestati;
import manager.attestati.service.CertificationService;
import manager.attestati.service.CertificationsComunication;
import manager.configurations.ConfigurationManager;
import manager.services.helpdesk.HelpdeskServiceManager;
import models.CompetenceCode;
Expand Down Expand Up @@ -173,6 +174,16 @@ public class Administration extends Controller {
static JwtTokenDao jwtTokenDao;
@Inject
static HelpdeskServiceManager helpdeskServiceManager;
@Inject
static CertificationsComunication certificationComunication;

/**
* Utilizzabile solo da developer e admin permette di prelevare un token del client
* utilizzato per la comunicazione con Attestati.
*/
public static void ssoToken() {
renderText(certificationComunication.getTokenBySso().getAccess_token());
}

/**
* metodo che renderizza la pagina di utilities senza parametri passati.
Expand Down
98 changes: 96 additions & 2 deletions app/manager/attestati/service/CertificationsComunication.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
import com.google.common.base.Verify;
import com.google.common.collect.Lists;
import com.google.gson.Gson;
import common.oauth2.OpenIdClientsModule;
import common.oauth2.OpenIdConnectClient;
import dao.GeneralSettingDao;
import helpers.CacheValues;
import helpers.rest.ApiRequestException;
import java.util.Arrays;
Expand Down Expand Up @@ -100,6 +103,19 @@ public class CertificationsComunication {

@Inject
private CacheValues cacheValues;
@Inject
private OpenIdClientsModule openIdClientsModule;
@Inject
private OpenIdConnectClient openIdConnectClient;
@Inject
private GeneralSettingDao generalSettingDao;

public OauthToken getToken() throws NoSuchFieldException {
if (generalSettingDao.generalSetting().isEnableSsoForAttestati()) {
return getTokenBySso();
}
return getTokenByAttestati();
}

/**
* Per l'ottenenere il Bearer Token: curl -s -X POST -H "Content-Type:
Expand All @@ -110,7 +126,7 @@ public class CertificationsComunication {
*
* @return il token
*/
public OauthToken getToken() throws NoSuchFieldException {
private OauthToken getTokenByAttestati() throws NoSuchFieldException {

final String url = AttestatiApis.getAttestatiBaseUrl();
final String user = AttestatiApis.getAttestatiUser();
Expand Down Expand Up @@ -140,6 +156,42 @@ public OauthToken getToken() throws NoSuchFieldException {

log.info("Ottenuto access-token dal server degli attestati: {}", response.getString());
return accessToken;

}

public OauthToken getTokenBySso() {
String clientId = openIdClientsModule.keycloakClientId();
String clientSecret = openIdClientsModule.keycloakClientSecret();
String url = openIdConnectClient.getConfig().getTokenEndpoint();

final Map<String, String> parameters = new HashMap<>();
parameters.put("grant_type", "client_credentials");
parameters.put("client_secret", clientSecret);
parameters.put("client_id", clientId);

WSRequest req = WS.url(url)
.setHeader("Content-Type", OAUTH_CONTENT_TYPE)
.setParameters(parameters);

HttpResponse response = req.post();

if (response.getStatus() != Http.StatusCode.OK) {
log.warn("Errore durante la richiesta del Token Oauth: {}; {} da {}",
response.getStatus(), response.getString(), url);
throw new ApiRequestException("Impossibile ottenere Token Oauth dal server " + url);
}

OauthToken accessToken = new Gson().fromJson(response.getJson(), OauthToken.class);

log.info("Ottenuto access-token dal server SSO {}: {}", url, response.getString());
return accessToken;
}

public OauthToken refreshToken(OauthToken token) throws NoSuchFieldException {
if (generalSettingDao.generalSetting().isEnableSsoForAttestati()) {
return refreshTokenBySso(token);
}
return refreshTokenByAttestati(token);
}

/**
Expand All @@ -148,7 +200,7 @@ public OauthToken getToken() throws NoSuchFieldException {
* @param token token precedente (già ottenuto dal server).
* @return Un nuovo token Oauth con validità estesa
*/
public OauthToken refreshToken(OauthToken token) throws NoSuchFieldException {
public OauthToken refreshTokenByAttestati(OauthToken token) throws NoSuchFieldException {

final String url = AttestatiApis.getAttestatiBaseUrl();

Expand Down Expand Up @@ -183,6 +235,48 @@ public OauthToken refreshToken(OauthToken token) throws NoSuchFieldException {
return accessToken;
}

/**
* Nuovo token con validità estesa.
*
* @param token token precedente (già ottenuto dal server).
* @return Un nuovo token Oauth con validità estesa
*/
public OauthToken refreshTokenBySso(OauthToken token) throws NoSuchFieldException {

if (token.refresh_token == null) {
return getTokenBySso();
}

String clientId = openIdClientsModule.keycloakClientId();
String clientSecret = openIdClientsModule.keycloakClientSecret();
String url = openIdConnectClient.getConfig().getTokenEndpoint();

final Map<String, String> parameters = new HashMap<>();
parameters.put("grant_type", REFRESHTOKEN_GRANT_TYPE);
parameters.put("client_secret", clientSecret);
parameters.put("client_id", clientId);
parameters.put("refresh_token", token.refresh_token);

WSRequest req = WS.url(url)
.setHeader("Content-Type", OAUTH_CONTENT_TYPE)
.setParameters(parameters);

log.info("Invio richiesta Refresh-Token al server SSO. Token precedente: {}. Url = {}", token
.refresh_token, url);
HttpResponse response = req.post();

if (response.getStatus() != Http.StatusCode.OK) {
log.warn("Errore durante la richiesta del Refresh-Token Oauth: {}; {}. Url = {}",
response.getStatus(), response.getString(), url);
//nel caso la risposta sia negativa effettuo una richiesta per un nuovo access token
return getToken();
}

OauthToken accessToken = new Gson().fromJson(response.getJson(), OauthToken.class);

log.info("Ottenuto refresh-token oauth dal server SSO: {}. Url = {}", response.getString(), url);
return accessToken;
}

/**
* Costruisce una WSRequest predisposta alla comunicazione con le api attestati.
Expand Down
8 changes: 7 additions & 1 deletion app/models/GeneralSetting.java
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,12 @@ public class GeneralSetting extends BaseModel {
/**
* URL base servizio epas-helpdesk-service.
*/
private String epasHelpdeskServiceUrl = "http://epas-helpdesk-service:8080/";
private String epasHelpdeskServiceUrl = "http://epas-helpdesk-service:8080/";

/**
* Indica se il servizio Attestati del CNR deve utilizzare l'SSO CNR per il rilascio del
* token oppure il token JWT direttamente rilasciato da Attestati.
*/
private boolean enableSsoForAttestati = false;

}
12 changes: 11 additions & 1 deletion app/views/Administration/_generalSetting.html
Original file line number Diff line number Diff line change
Expand Up @@ -276,5 +276,15 @@ <h2>&{actionSelected+'.table'}</h2>
#{/b.buttons}
#{/form}
#{/accordionItem}

#{accordionItem 'enableSsoForAttestati', parent:'generalSetting', title:'SSO del CNR per attestati', open:false}
#{form action:@saveGeneralSetting(), method:'POST', class:'form form-horizontal'}
#{f.hidden 'generalSetting.id' /}
#{alert color:'info'}Abilita l'utilizzo dell'SSO del CNR per il rilascio del token JWT utilizzato per le comunicazioni
tra ePAS ed Attestati (solo per il CNR)#{/alert}
#{f.booleanRadio 'generalSetting.enableSsoForAttestati' /}
#{b.buttons}
#{b.save /}
#{/b.buttons}
#{/form}
#{/accordionItem}
#{/accordionGroup}
2 changes: 2 additions & 0 deletions conf/messages.it
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,8 @@ generalSetting.epasServiceUrl=Url base del microservizio epas-service
generalSetting.epasHelpdeskServiceEnabled=Abilitazione integrazione con microservizio epas-helpdesk-service
generalSetting.epasHelpdeskServiceUrl=Url base del microservizio epas-helpdesk-service

generalSetting.enableSsoForAttestati=Abilita l'utilizzo di SSO del CNR per Attestati

group.label =Nome gruppo
group.limitType =Periodo di utililzzo limite
group.limitValue =Quantità massima
Expand Down
9 changes: 9 additions & 0 deletions db/evolutions/211.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# --- !Ups

ALTER TABLE general_setting ADD COLUMN enable_sso_for_attestati BOOLEAN DEFAULT FALSE;
ALTER TABLE general_setting_history ADD COLUMN enable_sso_for_attestati BOOLEAN DEFAULT FALSE;

# --- !Downs

ALTER TABLE general_setting DROP COLUMN enable_sso_for_attestati;
ALTER TABLE general_setting_history DROP COLUMN enable_sso_for_attestati;

0 comments on commit 0f581e5

Please sign in to comment.