diff --git a/client/am/console/src/main/java/org/apache/syncope/client/console/clientapps/ClientAppModalPanelBuilder.java b/client/am/console/src/main/java/org/apache/syncope/client/console/clientapps/ClientAppModalPanelBuilder.java index f0dc3632eb4..4fbbfa8b682 100644 --- a/client/am/console/src/main/java/org/apache/syncope/client/console/clientapps/ClientAppModalPanelBuilder.java +++ b/client/am/console/src/main/java/org/apache/syncope/client/console/clientapps/ClientAppModalPanelBuilder.java @@ -374,6 +374,16 @@ protected void onUpdate(final AjaxRequestTarget target) { fields.add(new AjaxTripleStateButtonPanel( "field", "jwtAccessToken", new PropertyModel<>(clientAppTO, "jwtAccessToken")). addRequiredLabel()); + + AjaxDropDownChoicePanel jwtAccessTokenSigningAlg = + new AjaxDropDownChoicePanel<>( + "field", "jwtAccessTokenSigningAlg", + new PropertyModel<>(clientAppTO, "jwtAccessTokenSigningAlg"), false); + + jwtAccessTokenSigningAlg.setChoices(Stream.of(OIDCTokenSigningAlg.values()). + filter(alg -> alg != OIDCTokenSigningAlg.none).toList()); + fields.add(jwtAccessTokenSigningAlg); + fields.add(new AjaxTripleStateButtonPanel( "field", "bypassApprovalPrompt", new PropertyModel<>(clientAppTO, "bypassApprovalPrompt")). addRequiredLabel()); @@ -486,6 +496,9 @@ public void setObject(final String object) { new PropertyModel<>(clientAppTO, "accessTokenMaxActiveTokens")); fields.add(accessTokenMaxActiveTokens); + fields.add(new AjaxTripleStateButtonPanel( + "field", "renewRefreshToken", new PropertyModel<>(clientAppTO, "renewRefreshToken"))); + AjaxTextFieldPanel refreshTokenTimeToKill = new AjaxTextFieldPanel( "field", "refreshTokenTimeToKill", new PropertyModel<>(clientAppTO, "refreshTokenTimeToKill"), false); @@ -501,6 +514,19 @@ public void setObject(final String object) { "field", "deviceTokenTimeToKill", new PropertyModel<>(clientAppTO, "deviceTokenTimeToKill"), false); fields.add(deviceTokenTimeToKill); + + fields.add(new AjaxTextFieldPanel( + "field", "idTokenTimeToKill", + new PropertyModel<>(clientAppTO, "idTokenTimeToKill"), false)); + + fields.add(new AjaxTextFieldPanel( + "field", "authorizationCodeTimeToLive", + new PropertyModel<>(clientAppTO, "authorizationCodeTimeToLive"), false)); + + AjaxTextFieldPanel audience = new AjaxTextFieldPanel("panel", "audience", Model.of()); + fields.add(new MultiFieldPanel.Builder( + new PropertyModel<>(clientAppTO, "audience")).build( + "field", "audience", audience)); break; case SAML2SP: @@ -615,7 +641,7 @@ public String getObject() { addRequiredLabel()); fields.add(new AjaxTripleStateButtonPanel( - "field", "skipGeneratingSubjectConfirmationAddress", + "field", "skipGeneratingSubjectConfirmationAddress", new PropertyModel<>(clientAppTO, "skipGeneratingSubjectConfirmationAddress")). addRequiredLabel()); diff --git a/common/am/lib/src/main/java/org/apache/syncope/common/lib/to/OIDCRPClientAppTO.java b/common/am/lib/src/main/java/org/apache/syncope/common/lib/to/OIDCRPClientAppTO.java index 44754e26870..2d1c2ae9829 100644 --- a/common/am/lib/src/main/java/org/apache/syncope/common/lib/to/OIDCRPClientAppTO.java +++ b/common/am/lib/src/main/java/org/apache/syncope/common/lib/to/OIDCRPClientAppTO.java @@ -94,6 +94,16 @@ public class OIDCRPClientAppTO extends ClientAppTO { private String deviceTokenTimeToKill; + private OIDCTokenSigningAlg jwtAccessTokenSigningAlg; + + private boolean renewRefreshToken; + + private String idTokenTimeToKill; + + private String authorizationCodeTimeToLive; + + private final List audience = new ArrayList<>(); + private OIDCClientAuthenticationMethod tokenEndpointAuthenticationMethod = OIDCClientAuthenticationMethod.client_secret_basic; @@ -332,6 +342,42 @@ public void setDeviceTokenTimeToKill(final String deviceTokenTimeToKill) { this.deviceTokenTimeToKill = deviceTokenTimeToKill; } + public OIDCTokenSigningAlg getJwtAccessTokenSigningAlg() { + return jwtAccessTokenSigningAlg; + } + + public void setJwtAccessTokenSigningAlg(final OIDCTokenSigningAlg jwtAccessTokenSigningAlg) { + this.jwtAccessTokenSigningAlg = jwtAccessTokenSigningAlg; + } + + public boolean getRenewRefreshToken() { + return renewRefreshToken; + } + + public void setRenewRefreshToken(final boolean renewRefreshToken) { + this.renewRefreshToken = renewRefreshToken; + } + + public String getIdTokenTimeToKill() { + return idTokenTimeToKill; + } + + public void setIdTokenTimeToKill(final String idTokenTimeToKill) { + this.idTokenTimeToKill = idTokenTimeToKill; + } + + public String getAuthorizationCodeTimeToLive() { + return authorizationCodeTimeToLive; + } + + public void setAuthorizationCodeTimeToLive(final String authorizationCodeTimeToLive) { + this.authorizationCodeTimeToLive = authorizationCodeTimeToLive; + } + + public List getAudience() { + return audience; + } + @Override public boolean equals(final Object obj) { if (obj == null) { @@ -376,6 +422,11 @@ public boolean equals(final Object obj) { .append(this.refreshTokenTimeToKill, rhs.accessTokenTimeToKill) .append(this.refreshTokenMaxActiveTokens, rhs.refreshTokenMaxActiveTokens) .append(this.deviceTokenTimeToKill, rhs.deviceTokenTimeToKill) + .append(this.jwtAccessTokenSigningAlg, rhs.jwtAccessTokenSigningAlg) + .append(this.renewRefreshToken, rhs.renewRefreshToken) + .append(this.idTokenTimeToKill, rhs.idTokenTimeToKill) + .append(this.authorizationCodeTimeToLive, rhs.authorizationCodeTimeToLive) + .append(this.audience, rhs.audience) .isEquals(); } @@ -413,6 +464,11 @@ public int hashCode() { .append(refreshTokenTimeToKill) .append(refreshTokenMaxActiveTokens) .append(deviceTokenTimeToKill) + .append(jwtAccessTokenSigningAlg) + .append(renewRefreshToken) + .append(idTokenTimeToKill) + .append(authorizationCodeTimeToLive) + .append(audience) .toHashCode(); } } diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/am/OIDCRPClientApp.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/am/OIDCRPClientApp.java index 0eb2dbda8d3..f2e1ac10b49 100644 --- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/am/OIDCRPClientApp.java +++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/am/OIDCRPClientApp.java @@ -141,4 +141,22 @@ public interface OIDCRPClientApp extends ClientApp { String getAccessTokenMaxTimeToLive(); void setAccessTokenMaxTimeToLive(String accessTokenMaxTimeToLive); + + OIDCTokenSigningAlg getJwtAccessTokenSigningAlg(); + + void setJwtAccessTokenSigningAlg(OIDCTokenSigningAlg jwtAccessTokenSigningAlg); + + boolean getRenewRefreshToken(); + + void setRenewRefreshToken(boolean renewRefreshToken); + + String getIdTokenTimeToKill(); + + void setIdTokenTimeToKill(String idTokenTimeToKill); + + String getAuthorizationCodeTimeToLive(); + + void setAuthorizationCodeTimeToLive(String authorizationCodeTimeToLive); + + Set getAudience(); } diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/JPAOIDCRPClientApp.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/JPAOIDCRPClientApp.java index b0a368262b8..2f4c4f669a6 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/JPAOIDCRPClientApp.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/am/JPAOIDCRPClientApp.java @@ -154,6 +154,21 @@ public class JPAOIDCRPClientApp extends AbstractClientApp implements OIDCRPClien private String deviceTokenTimeToKill; + @Enumerated(EnumType.STRING) + private OIDCTokenSigningAlg jwtAccessTokenSigningAlg; + + private boolean renewRefreshToken; + + private String idTokenTimeToKill; + + private String authorizationCodeTimeToLive; + + @Lob + private String audience; + + @Transient + private Set audienceSet = new HashSet<>(); + @Override public Set getRedirectUris() { return redirectUrisSet; @@ -436,11 +451,57 @@ public void setAccessTokenMaxTimeToLive(final String accessTokenMaxTimeToLive) { this.accessTokenMaxTimeToLive = accessTokenMaxTimeToLive; } + @Override + public OIDCTokenSigningAlg getJwtAccessTokenSigningAlg() { + return jwtAccessTokenSigningAlg; + } + + @Override + public void setJwtAccessTokenSigningAlg(final OIDCTokenSigningAlg jwtAccessTokenSigningAlg) { + this.jwtAccessTokenSigningAlg = jwtAccessTokenSigningAlg; + } + + @Override + public boolean getRenewRefreshToken() { + return renewRefreshToken; + } + + @Override + public void setRenewRefreshToken(final boolean renewRefreshToken) { + this.renewRefreshToken = renewRefreshToken; + } + + @Override + public String getIdTokenTimeToKill() { + return idTokenTimeToKill; + } + + @Override + public void setIdTokenTimeToKill(final String idTokenTimeToKill) { + this.idTokenTimeToKill = idTokenTimeToKill; + } + + @Override + public String getAuthorizationCodeTimeToLive() { + return authorizationCodeTimeToLive; + } + + @Override + public void setAuthorizationCodeTimeToLive(final String authorizationCodeTimeToLive) { + this.authorizationCodeTimeToLive = authorizationCodeTimeToLive; + } + + @Override + public Set getAudience() { + return audienceSet; + } + protected void json2list(final boolean clearFirst) { if (clearFirst) { getRedirectUris().clear(); getSupportedGrantTypes().clear(); getSupportedResponseTypes().clear(); + getAudience().clear(); } if (redirectUris != null) { getRedirectUris().addAll(POJOHelper.deserialize(redirectUris, STRING_TYPEREF)); @@ -454,6 +515,9 @@ protected void json2list(final boolean clearFirst) { if (scopes != null) { getScopes().addAll(POJOHelper.deserialize(scopes, SCOPE_TYPEREF)); } + if (audience != null) { + getAudience().addAll(POJOHelper.deserialize(audience, STRING_TYPEREF)); + } } @PostLoad @@ -474,5 +538,6 @@ public void list2json() { supportedGrantTypes = POJOHelper.serialize(getSupportedGrantTypes()); supportedResponseTypes = POJOHelper.serialize(getSupportedResponseTypes()); scopes = POJOHelper.serialize(getScopes()); + audience = POJOHelper.serialize(getAudience()); } } diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/am/Neo4jOIDCRPClientApp.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/am/Neo4jOIDCRPClientApp.java index c4766924333..b421470d63c 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/am/Neo4jOIDCRPClientApp.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/entity/am/Neo4jOIDCRPClientApp.java @@ -132,6 +132,20 @@ public class Neo4jOIDCRPClientApp extends AbstractClientApp implements OIDCRPCli private String deviceTokenTimeToKill; + private OIDCTokenSigningAlg jwtAccessTokenSigningAlg; + + private boolean renewRefreshToken; + + private String idTokenTimeToKill; + + private String authorizationCodeTimeToLive; + + private String audience; + + @Transient + private Set audienceSet = new HashSet<>(); + + @Override public Set getRedirectUris() { return redirectUrisSet; @@ -414,11 +428,57 @@ public void setAccessTokenMaxTimeToLive(final String accessTokenMaxTimeToLive) { this.accessTokenMaxTimeToLive = accessTokenMaxTimeToLive; } + @Override + public OIDCTokenSigningAlg getJwtAccessTokenSigningAlg() { + return jwtAccessTokenSigningAlg; + } + + @Override + public void setJwtAccessTokenSigningAlg(final OIDCTokenSigningAlg jwtAccessTokenSigningAlg) { + this.jwtAccessTokenSigningAlg = jwtAccessTokenSigningAlg; + } + + @Override + public boolean getRenewRefreshToken() { + return renewRefreshToken; + } + + @Override + public void setRenewRefreshToken(final boolean renewRefreshToken) { + this.renewRefreshToken = renewRefreshToken; + } + + @Override + public String getIdTokenTimeToKill() { + return idTokenTimeToKill; + } + + @Override + public void setIdTokenTimeToKill(final String idTokenTimeToKill) { + this.idTokenTimeToKill = idTokenTimeToKill; + } + + @Override + public String getAuthorizationCodeTimeToLive() { + return authorizationCodeTimeToLive; + } + + @Override + public void setAuthorizationCodeTimeToLive(final String authorizationCodeTimeToLive) { + this.authorizationCodeTimeToLive = authorizationCodeTimeToLive; + } + + @Override + public Set getAudience() { + return audienceSet; + } + protected void json2list(final boolean clearFirst) { if (clearFirst) { getRedirectUris().clear(); getSupportedGrantTypes().clear(); getSupportedResponseTypes().clear(); + getAudience().clear(); } if (redirectUris != null) { getRedirectUris().addAll(POJOHelper.deserialize(redirectUris, STRING_TYPEREF)); @@ -432,6 +492,9 @@ protected void json2list(final boolean clearFirst) { if (scopes != null) { getScopes().addAll(POJOHelper.deserialize(scopes, SCOPE_TYPEREF)); } + if (audience != null) { + getAudience().addAll(POJOHelper.deserialize(audience, STRING_TYPEREF)); + } } @PostLoad @@ -448,5 +511,6 @@ public void list2json() { supportedGrantTypes = POJOHelper.serialize(getSupportedGrantTypes()); supportedResponseTypes = POJOHelper.serialize(getSupportedResponseTypes()); scopes = POJOHelper.serialize(getScopes()); + audience = POJOHelper.serialize(getAudience()); } } diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ClientAppDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ClientAppDataBinderImpl.java index 753c6a48044..6cbd1f2103d 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ClientAppDataBinderImpl.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ClientAppDataBinderImpl.java @@ -328,6 +328,12 @@ protected void doUpdate(final OIDCRPClientApp clientApp, final OIDCRPClientAppTO clientApp.setRefreshTokenMaxActiveTokens(clientAppTO.getRefreshTokenMaxActiveTokens()); clientApp.setRefreshTokenTimeToKill(clientAppTO.getRefreshTokenTimeToKill()); clientApp.setDeviceTokenTimeToKill(clientAppTO.getDeviceTokenTimeToKill()); + clientApp.setJwtAccessTokenSigningAlg(clientAppTO.getJwtAccessTokenSigningAlg()); + clientApp.setRenewRefreshToken(clientAppTO.getRenewRefreshToken()); + clientApp.setIdTokenTimeToKill(clientAppTO.getIdTokenTimeToKill()); + clientApp.setAuthorizationCodeTimeToLive(clientAppTO.getAuthorizationCodeTimeToLive()); + clientApp.getAudience().clear(); + clientApp.getAudience().addAll(clientAppTO.getAudience()); Set allowedScopes = new HashSet<>(); Stream.of(OIDCStandardScope.values()).map(OIDCStandardScope::name).forEach(allowedScopes::add); @@ -379,6 +385,11 @@ protected OIDCRPClientAppTO getOIDCClientAppTO(final OIDCRPClientApp clientApp) clientAppTO.setRefreshTokenTimeToKill(clientApp.getRefreshTokenTimeToKill()); clientAppTO.setRefreshTokenMaxActiveTokens(clientApp.getRefreshTokenMaxActiveTokens()); clientAppTO.setDeviceTokenTimeToKill(clientApp.getDeviceTokenTimeToKill()); + clientAppTO.setJwtAccessTokenSigningAlg(clientApp.getJwtAccessTokenSigningAlg()); + clientAppTO.setRenewRefreshToken(clientApp.getRenewRefreshToken()); + clientAppTO.setIdTokenTimeToKill(clientApp.getIdTokenTimeToKill()); + clientAppTO.setAuthorizationCodeTimeToLive(clientApp.getAuthorizationCodeTimeToLive()); + clientAppTO.getAudience().addAll(clientApp.getAudience()); return clientAppTO; } diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java index 56f6ccb39ec..2804010d7e3 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java @@ -979,6 +979,10 @@ protected static OIDCRPClientAppTO buildOIDCRP() { oidcrpTO.setRefreshTokenTimeToKill("P14D"); oidcrpTO.setDeviceTokenTimeToKill("PT5M"); + oidcrpTO.setRenewRefreshToken(true); + oidcrpTO.setIdTokenTimeToKill("PT5M"); + oidcrpTO.setAuthorizationCodeTimeToLive("PT30S"); + oidcrpTO.getAudience().add("https://api.apache.org"); return oidcrpTO; } diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ClientAppITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ClientAppITCase.java index de79ce4833c..62666346491 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ClientAppITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ClientAppITCase.java @@ -25,6 +25,7 @@ import static org.junit.jupiter.api.Assertions.fail; import jakarta.ws.rs.core.Response; +import java.util.List; import java.util.Set; import java.util.UUID; import org.apache.commons.lang3.StringUtils; @@ -146,6 +147,10 @@ public void readOIDCRP() { assertNotNull(found.getAccessPolicy()); assertNotNull(found.getAuthPolicy()); assertNotNull(found.getAccessTokenMaxTimeToLive()); + assertEquals(Boolean.TRUE, found.getRenewRefreshToken()); + assertEquals("PT5M", found.getIdTokenTimeToKill()); + assertEquals("PT30S", found.getAuthorizationCodeTimeToLive()); + assertEquals(List.of("https://api.apache.org"), found.getAudience()); } @Test @@ -194,6 +199,11 @@ public void updateOIDCRP() { oidcrpTO.setClientId("newClientId"); oidcrpTO.setAccessPolicy(accessPolicyTO.getKey()); oidcrpTO.setDeviceTokenTimeToKill("PT6M"); + oidcrpTO.setRenewRefreshToken(false); + oidcrpTO.setIdTokenTimeToKill("PT10M"); + oidcrpTO.setAuthorizationCodeTimeToLive("PT1M"); + oidcrpTO.getAudience().clear(); + oidcrpTO.getAudience().add("https://new-api.apache.org"); CLIENT_APP_SERVICE.update(ClientAppType.OIDCRP, oidcrpTO); OIDCRPClientAppTO updated = CLIENT_APP_SERVICE.read(ClientAppType.OIDCRP, oidcrpTO.getKey()); @@ -202,6 +212,10 @@ public void updateOIDCRP() { assertEquals("newClientId", updated.getClientId()); assertNotNull(updated.getAccessPolicy()); assertEquals("PT6M", updated.getDeviceTokenTimeToKill()); + assertEquals(Boolean.FALSE, updated.getRenewRefreshToken()); + assertEquals("PT10M", updated.getIdTokenTimeToKill()); + assertEquals("PT1M", updated.getAuthorizationCodeTimeToLive()); + assertEquals(List.of("https://new-api.apache.org"), updated.getAudience()); } @Test diff --git a/wa/starter/src/main/java/org/apache/syncope/wa/starter/mapping/OIDCRPClientAppTOMapper.java b/wa/starter/src/main/java/org/apache/syncope/wa/starter/mapping/OIDCRPClientAppTOMapper.java index b1bc7e656c6..4d30da5c5e1 100644 --- a/wa/starter/src/main/java/org/apache/syncope/wa/starter/mapping/OIDCRPClientAppTOMapper.java +++ b/wa/starter/src/main/java/org/apache/syncope/wa/starter/mapping/OIDCRPClientAppTOMapper.java @@ -20,6 +20,7 @@ import java.util.Objects; import java.util.Optional; +import java.util.Set; import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; import org.apache.syncope.common.lib.to.ClientAppTO; @@ -29,6 +30,7 @@ import org.apache.syncope.common.lib.types.OIDCTokenEncryptionAlg; import org.apache.syncope.common.lib.types.OIDCTokenSigningAlg; import org.apache.syncope.common.lib.wa.WAClientApp; +import org.apereo.cas.oidc.services.DefaultRegisteredServiceOidcIdTokenExpirationPolicy; import org.apereo.cas.services.OidcRegisteredService; import org.apereo.cas.services.RegisteredService; import org.apereo.cas.services.RegisteredServiceAccessStrategy; @@ -40,6 +42,7 @@ import org.apereo.cas.services.RegisteredServiceServiceTicketExpirationPolicy; import org.apereo.cas.services.RegisteredServiceTicketGrantingTicketExpirationPolicy; import org.apereo.cas.support.oauth.services.DefaultRegisteredServiceOAuthAccessTokenExpirationPolicy; +import org.apereo.cas.support.oauth.services.DefaultRegisteredServiceOAuthCodeExpirationPolicy; import org.apereo.cas.support.oauth.services.DefaultRegisteredServiceOAuthDeviceTokenExpirationPolicy; import org.apereo.cas.support.oauth.services.DefaultRegisteredServiceOAuthRefreshTokenExpirationPolicy; @@ -100,6 +103,13 @@ public RegisteredService map( ifPresent(v -> service.setUserInfoEncryptedResponseEncoding(v.getExternalForm())); service.setJwtAccessToken(rp.isJwtAccessToken()); + if (rp.isJwtAccessToken()) { + Optional.ofNullable(rp.getJwtAccessTokenSigningAlg()). + filter(alg -> alg != OIDCTokenSigningAlg.none). + ifPresent(alg -> service.setJwtAccessTokenSigningAlg(alg.name())); + } + + Optional.ofNullable(rp.getRenewRefreshToken()).ifPresent(service::setRenewRefreshToken); service.setBypassApprovalPrompt(rp.isBypassApprovalPrompt()); service.setGenerateRefreshToken(rp.isGenerateRefreshToken()); if (StringUtils.isNotBlank(rp.getJwksUri())) { @@ -118,6 +128,12 @@ public RegisteredService map( service.setScopes(rp.getScopes().stream().collect(Collectors.toSet())); + Set audience = rp.getAudience().stream(). + filter(StringUtils::isNotBlank).collect(Collectors.toSet()); + if (!audience.isEmpty()) { + service.setAudience(audience); + } + setPolicies(service, authPolicy, mfaPolicy, accessStrategy, attributeReleasePolicy, tgtExpirationPolicy, stExpirationPolicy, tgtProxyExpirationPolicy, stProxyExpirationPolicy); @@ -148,6 +164,23 @@ public RegisteredService map( service.setDeviceTokenExpirationPolicy(policy); }); + Optional.ofNullable(rp.getIdTokenTimeToKill()).filter(StringUtils::isNotBlank). + ifPresent(duration -> { + DefaultRegisteredServiceOidcIdTokenExpirationPolicy policy = + new DefaultRegisteredServiceOidcIdTokenExpirationPolicy(); + policy.setTimeToKill(duration); + service.setIdTokenExpirationPolicy(policy); + }); + + Optional.ofNullable(rp.getAuthorizationCodeTimeToLive()).filter(StringUtils::isNotBlank). + ifPresent(duration -> { + DefaultRegisteredServiceOAuthCodeExpirationPolicy policy = + new DefaultRegisteredServiceOAuthCodeExpirationPolicy(); + policy.setNumberOfUses(1); + policy.setTimeToLive(duration); + service.setCodeExpirationPolicy(policy); + }); + return service; } } diff --git a/wa/starter/src/test/java/org/apache/syncope/wa/starter/WAServiceRegistryTest.java b/wa/starter/src/test/java/org/apache/syncope/wa/starter/WAServiceRegistryTest.java index 69888267f6c..3cde39c9338 100644 --- a/wa/starter/src/test/java/org/apache/syncope/wa/starter/WAServiceRegistryTest.java +++ b/wa/starter/src/test/java/org/apache/syncope/wa/starter/WAServiceRegistryTest.java @@ -42,6 +42,7 @@ import org.apache.syncope.common.lib.types.OIDCGrantType; import org.apache.syncope.common.lib.types.OIDCResponseType; import org.apache.syncope.common.lib.types.OIDCSubjectType; +import org.apache.syncope.common.lib.types.OIDCTokenSigningAlg; import org.apache.syncope.common.lib.types.SAML2SPNameId; import org.apache.syncope.common.lib.wa.WAClientApp; import org.apache.syncope.common.rest.api.service.AuthModuleService; @@ -76,6 +77,12 @@ private static OIDCRPClientAppTO buildOIDCRP() { oidcrpTO.getSupportedGrantTypes().add(OIDCGrantType.password); oidcrpTO.getSupportedResponseTypes().add(OIDCResponseType.CODE); oidcrpTO.setLogoutType(LogoutType.BACK_CHANNEL); + oidcrpTO.setJwtAccessToken(true); + oidcrpTO.setJwtAccessTokenSigningAlg(OIDCTokenSigningAlg.RS256); + oidcrpTO.setRenewRefreshToken(true); + oidcrpTO.setIdTokenTimeToKill("PT5M"); + oidcrpTO.setAuthorizationCodeTimeToLive("PT30S"); + oidcrpTO.getAudience().add("https://api.example.org"); return oidcrpTO; } @@ -178,6 +185,12 @@ public void addClientApp() { assertEquals("uri1|uri2", oidc.getServiceId()); assertEquals(oidcrpto.getClientId(), oidc.getClientId()); assertEquals(oidcrpto.getClientSecret(), oidc.getClientSecret()); + assertEquals("RS256", oidc.getJwtAccessTokenSigningAlg()); + assertTrue(oidc.isRenewRefreshToken()); + assertEquals("PT5M", oidc.getIdTokenExpirationPolicy().getTimeToKill()); + assertEquals("PT30S", oidc.getCodeExpirationPolicy().getTimeToLive()); + assertEquals(1, oidc.getCodeExpirationPolicy().getNumberOfUses()); + assertEquals(Set.of("https://api.example.org"), oidc.getAudience()); assertTrue(oidc.getAuthenticationPolicy().getRequiredAuthenticationHandlers().contains("TestAuthModule")); assertTrue(((AnyAuthenticationHandlerRegisteredServiceAuthenticationPolicyCriteria) oidc. getAuthenticationPolicy().getCriteria()).isTryAll());