Fix NPE with exp claim in NimbusJwtDecoderJwkSupport
Fixes gh-5168
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.springframework.security.oauth2.core;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.security.core.SpringSecurityCoreVersion;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -38,14 +39,23 @@ public abstract class AbstractOAuth2Token implements Serializable {
|
||||
* Sub-class constructor.
|
||||
*
|
||||
* @param tokenValue the token value
|
||||
* @param issuedAt the time at which the token was issued
|
||||
* @param expiresAt the expiration time on or after which the token MUST NOT be accepted
|
||||
*/
|
||||
protected AbstractOAuth2Token(String tokenValue, Instant issuedAt, Instant expiresAt) {
|
||||
protected AbstractOAuth2Token(String tokenValue) {
|
||||
this(tokenValue, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sub-class constructor.
|
||||
*
|
||||
* @param tokenValue the token value
|
||||
* @param issuedAt the time at which the token was issued, may be null
|
||||
* @param expiresAt the expiration time on or after which the token MUST NOT be accepted, may be null
|
||||
*/
|
||||
protected AbstractOAuth2Token(String tokenValue, @Nullable Instant issuedAt, @Nullable Instant expiresAt) {
|
||||
Assert.hasText(tokenValue, "tokenValue cannot be empty");
|
||||
Assert.notNull(issuedAt, "issuedAt cannot be null");
|
||||
Assert.notNull(expiresAt, "expiresAt cannot be null");
|
||||
Assert.isTrue(expiresAt.isAfter(issuedAt), "expiresAt must be after issuedAt");
|
||||
if (issuedAt != null && expiresAt != null) {
|
||||
Assert.isTrue(expiresAt.isAfter(issuedAt), "expiresAt must be after issuedAt");
|
||||
}
|
||||
this.tokenValue = tokenValue;
|
||||
this.issuedAt = issuedAt;
|
||||
this.expiresAt = expiresAt;
|
||||
@@ -63,18 +73,18 @@ public abstract class AbstractOAuth2Token implements Serializable {
|
||||
/**
|
||||
* Returns the time at which the token was issued.
|
||||
*
|
||||
* @return the time the token was issued
|
||||
* @return the time the token was issued or null
|
||||
*/
|
||||
public Instant getIssuedAt() {
|
||||
public @Nullable Instant getIssuedAt() {
|
||||
return this.issuedAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the expiration time on or after which the token MUST NOT be accepted.
|
||||
*
|
||||
* @return the expiration time of the token
|
||||
* @return the expiration time of the token or null
|
||||
*/
|
||||
public Instant getExpiresAt() {
|
||||
public @Nullable Instant getExpiresAt() {
|
||||
return this.expiresAt;
|
||||
}
|
||||
|
||||
@@ -92,17 +102,17 @@ public abstract class AbstractOAuth2Token implements Serializable {
|
||||
if (!this.getTokenValue().equals(that.getTokenValue())) {
|
||||
return false;
|
||||
}
|
||||
if (!this.getIssuedAt().equals(that.getIssuedAt())) {
|
||||
if (this.getIssuedAt() != null ? !this.getIssuedAt().equals(that.getIssuedAt()) : that.getIssuedAt() != null) {
|
||||
return false;
|
||||
}
|
||||
return this.getExpiresAt().equals(that.getExpiresAt());
|
||||
return this.getExpiresAt() != null ? this.getExpiresAt().equals(that.getExpiresAt()) : that.getExpiresAt() == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = this.getTokenValue().hashCode();
|
||||
result = 31 * result + this.getIssuedAt().hashCode();
|
||||
result = 31 * result + this.getExpiresAt().hashCode();
|
||||
result = 31 * result + (this.getIssuedAt() != null ? this.getIssuedAt().hashCode() : 0);
|
||||
result = 31 * result + (this.getExpiresAt() != null ? this.getExpiresAt().hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,16 +51,6 @@ public class OAuth2AccessTokenTests {
|
||||
new OAuth2AccessToken(TOKEN_TYPE, null, ISSUED_AT, EXPIRES_AT);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void constructorWhenIssuedAtIsNullThenThrowIllegalArgumentException() {
|
||||
new OAuth2AccessToken(TOKEN_TYPE, TOKEN_VALUE, null, EXPIRES_AT);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void constructorWhenExpiresAtIsNullThenThrowIllegalArgumentException() {
|
||||
new OAuth2AccessToken(TOKEN_TYPE, TOKEN_VALUE, ISSUED_AT, null);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void constructorWhenIssuedAtAfterExpiresAtThenThrowIllegalArgumentException() {
|
||||
new OAuth2AccessToken(TOKEN_TYPE, TOKEN_VALUE, Instant.from(EXPIRES_AT).plusSeconds(1), EXPIRES_AT);
|
||||
|
||||
@@ -82,16 +82,6 @@ public class OidcIdTokenTests {
|
||||
new OidcIdToken(null, Instant.ofEpochMilli(IAT_VALUE), Instant.ofEpochMilli(EXP_VALUE), CLAIMS);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void constructorWhenIssuedAtIsNullThenThrowIllegalArgumentException() {
|
||||
new OidcIdToken(ID_TOKEN_VALUE, null, Instant.ofEpochMilli(EXP_VALUE), CLAIMS);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void constructorWhenExpiresAtIsNullThenThrowIllegalArgumentException() {
|
||||
new OidcIdToken(ID_TOKEN_VALUE, Instant.ofEpochMilli(IAT_VALUE), null, CLAIMS);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void constructorWhenClaimsIsEmptyThenThrowIllegalArgumentException() {
|
||||
new OidcIdToken(ID_TOKEN_VALUE, Instant.ofEpochMilli(IAT_VALUE),
|
||||
|
||||
Reference in New Issue
Block a user