Skip to content

Commit 1c79c6a

Browse files
committed
handle entity statement exp
1 parent e8bef4f commit 1c79c6a

4 files changed

Lines changed: 56 additions & 3 deletions

File tree

documentation/docs/next-version.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ layout: ddoc
33
title: Next version
44
---
55

6-
The next version **6.4.0-SNAPSHOT** is under development.
6+
The next version **6.4.1-SNAPSHOT** is under development.
77
Maven artifacts are built via Github Actions and available in the [Central Portal Snapshots repository](https://central.sonatype.com/repository/maven-snapshots).
88

99
The source code can be cloned and locally built via Maven:
@@ -13,3 +13,5 @@ git clone git@github.com:pac4j/pac4j.git
1313
cd pac4j
1414
mvn clean install
1515
```
16+
17+
You'd better fork the project if you want to submit pull requests.

documentation/docs/release-notes.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ title: Release notes:
77

88
**v6.4.1**:
99
- Ensures proper initialization of `SAML2Configuration`
10+
- Expires the entity statement after `validityInDays` in `DefaultEntityConfigurationGenerator`
1011

1112
**v6.4.0**:
1213
- Upgrade to Shiro v2.1 for security reasons. Defaults remain the ones of Shiro v1.13 though and will change in a future major version.

pac4j-oidc/src/main/java/org/pac4j/oidc/federation/entity/DefaultEntityConfigurationGenerator.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
import com.nimbusds.jose.jwk.JWKSet;
55
import com.nimbusds.jwt.JWTClaimsSet;
66
import com.nimbusds.oauth2.sdk.auth.ClientAuthenticationMethod;
7+
import lombok.AccessLevel;
78
import lombok.RequiredArgsConstructor;
9+
import lombok.Setter;
810
import lombok.extern.slf4j.Slf4j;
911
import lombok.val;
1012
import org.apache.commons.lang3.StringUtils;
@@ -39,6 +41,9 @@ public class DefaultEntityConfigurationGenerator extends InitializableObject imp
3941

4042
private String data;
4143

44+
@Setter(AccessLevel.PACKAGE)
45+
private Date expirationDate;
46+
4247
@Override
4348
public String getContentType() {
4449
return CONTENT_TYPE;
@@ -51,6 +56,16 @@ public String generateEntityStatement() {
5156
return data;
5257
}
5358

59+
@Override
60+
protected boolean shouldInitialize(final boolean forceReinit) {
61+
val now = new Date();
62+
if (expirationDate == null || expirationDate.before(now)) {
63+
return true;
64+
}
65+
66+
return super.shouldInitialize(forceReinit);
67+
}
68+
5469
@Override
5570
protected void internalInit(final boolean forceReinit) {
5671
val config = client.getConfiguration();
@@ -87,14 +102,14 @@ protected String buildConfig(final JWK signingKey) {
87102

88103
val now = new Date();
89104
long validityMs = (long) federation.getValidityInDays() * 24 * 60 * 60 * 1000L;
90-
val exp = new Date(now.getTime() + validityMs);
105+
expirationDate = new Date(now.getTime() + validityMs);
91106

92107
val claimsBuilder = new JWTClaimsSet.Builder()
93108
.issuer(entityId)
94109
.subject(entityId)
95110
.jwtID(UUID.randomUUID().toString())
96111
.issueTime(now)
97-
.expirationTime(exp)
112+
.expirationTime(expirationDate)
98113
.notBeforeTime(now);
99114

100115
val rpMetadata = new LinkedHashMap<String, Object>();

pac4j-oidc/src/test/java/org/pac4j/oidc/federation/entity/DefaultEntityConfigurationGeneratorTests.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
import java.nio.file.Files;
2727
import java.nio.file.Path;
28+
import java.util.Date;
2829
import java.util.List;
2930
import java.util.Map;
3031
import java.util.function.Consumer;
@@ -79,6 +80,40 @@ public void testGetContentType() {
7980
assertEquals("application/entity-statement+jwt", generator.getContentType());
8081
}
8182

83+
@Test
84+
public void testShouldNotInitializeAgainWhenAlreadyInitializedAndNotExpired() throws Exception {
85+
val jwksFile = tmp.resolve("not-expired.jwks");
86+
federation.getJwks().setJwksResource(new FileSystemResource(jwksFile.toFile()));
87+
val generator = newGenerator();
88+
89+
val firstEntityStatement = generator.generateEntityStatement();
90+
assertEquals(1, generator.getNbAttempts());
91+
92+
generator.setExpirationDate(new Date(System.currentTimeMillis() + 60_000L));
93+
assertFalse(generator.shouldInitialize(false));
94+
95+
val secondEntityStatement = generator.generateEntityStatement();
96+
assertEquals(firstEntityStatement, secondEntityStatement);
97+
assertEquals(1, generator.getNbAttempts());
98+
}
99+
100+
@Test
101+
public void testShouldInitializeAgainWhenAlreadyInitializedAndExpired() throws Exception {
102+
val jwksFile = tmp.resolve("expired.jwks");
103+
federation.getJwks().setJwksResource(new FileSystemResource(jwksFile.toFile()));
104+
val generator = newGenerator();
105+
106+
val firstEntityStatement = generator.generateEntityStatement();
107+
assertEquals(1, generator.getNbAttempts());
108+
109+
generator.setExpirationDate(new Date(System.currentTimeMillis() - 1_000L));
110+
assertTrue(generator.shouldInitialize(false));
111+
112+
val secondEntityStatement = generator.generateEntityStatement();
113+
assertNotEquals(firstEntityStatement, secondEntityStatement);
114+
assertEquals(2, generator.getNbAttempts());
115+
}
116+
82117
@Test
83118
public void testGenerateEntityStatementWithoutJwksAndWithoutKeystore() {
84119
federation.setJwks(null);

0 commit comments

Comments
 (0)