KEYCLOAK-2106 HTTP 500 for unparsable refresh tokens
This commit is contained in:
1 parent
5ea880cfff
commit
c83e3bd2d1
20 files changed
+201
-149
No files matched your search
@@ -2,6 +2,7 @@ package org.keycloak;
|
||||
|
||||
import org.keycloak.common.VerificationException;
|
||||
import org.keycloak.jose.jws.JWSInput;
|
||||
import org.keycloak.jose.jws.JWSInputException;
|
||||
import org.keycloak.jose.jws.crypto.RSAProvider;
|
||||
import org.keycloak.representations.AccessToken;
|
||||
import org.keycloak.util.TokenUtil;
|
||||
@@ -22,7 +23,7 @@ public class RSATokenVerifier {
|
||||
JWSInput input = null;
|
||||
try {
|
||||
input = new JWSInput(tokenString);
|
||||
} catch (Exception e) {
|
||||
} catch (JWSInputException e) {
|
||||
throw new VerificationException("Couldn't parse token", e);
|
||||
}
|
||||
if (!isPublicKeyValid(input, realmKey)) throw new VerificationException("Invalid token signature.");
|
||||
@@ -30,7 +31,7 @@ public class RSATokenVerifier {
|
||||
AccessToken token;
|
||||
try {
|
||||
token = input.readJsonContent(AccessToken.class);
|
||||
} catch (IOException e) {
|
||||
} catch (JWSInputException e) {
|
||||
throw new VerificationException("Couldn't parse token signature", e);
|
||||
}
|
||||
String user = token.getSubject();
|
||||
|
||||
@@ -21,14 +21,14 @@ public class JWSInput {
|
||||
byte[] signature;
|
||||
|
||||
|
||||
public JWSInput(String wire) {
|
||||
this.wireString = wire;
|
||||
String[] parts = wire.split("\\.");
|
||||
if (parts.length < 2 || parts.length > 3) throw new IllegalArgumentException("Parsing error");
|
||||
encodedHeader = parts[0];
|
||||
encodedContent = parts[1];
|
||||
encodedSignatureInput = encodedHeader + '.' + encodedContent;
|
||||
public JWSInput(String wire) throws JWSInputException {
|
||||
try {
|
||||
this.wireString = wire;
|
||||
String[] parts = wire.split("\\.");
|
||||
if (parts.length < 2 || parts.length > 3) throw new IllegalArgumentException("Parsing error");
|
||||
encodedHeader = parts[0];
|
||||
encodedContent = parts[1];
|
||||
encodedSignatureInput = encodedHeader + '.' + encodedContent;
|
||||
content = Base64Url.decode(encodedContent);
|
||||
if (parts.length > 2) {
|
||||
encodedSignature = parts[2];
|
||||
@@ -37,8 +37,8 @@ public class JWSInput {
|
||||
}
|
||||
byte[] headerBytes = Base64Url.decode(encodedHeader);
|
||||
header = JsonSerialization.readValue(headerBytes, JWSHeader.class);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (Throwable t) {
|
||||
throw new JWSInputException(t);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,8 +80,12 @@ public class JWSInput {
|
||||
return header.getAlgorithm().getProvider().verify(this, key);
|
||||
}
|
||||
|
||||
public <T> T readJsonContent(Class<T> type) throws IOException {
|
||||
return JsonSerialization.readValue(content, type);
|
||||
public <T> T readJsonContent(Class<T> type) throws JWSInputException {
|
||||
try {
|
||||
return JsonSerialization.readValue(content, type);
|
||||
} catch (IOException e) {
|
||||
throw new JWSInputException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public String readContentAsString() {
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package org.keycloak.jose.jws;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public class JWSInputException extends Exception {
|
||||
|
||||
public JWSInputException(String s) {
|
||||
super(s);
|
||||
}
|
||||
|
||||
public JWSInputException() {
|
||||
}
|
||||
|
||||
public JWSInputException(Throwable throwable) {
|
||||
super(throwable);
|
||||
}
|
||||
}
|
||||
@@ -64,7 +64,7 @@ public class RSAProvider implements SignatureProvider {
|
||||
verifier.update(input.getEncodedSignatureInput().getBytes("UTF-8"));
|
||||
return verifier.verify(input.getSignature());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import java.io.IOException;
|
||||
|
||||
import org.keycloak.OAuth2Constants;
|
||||
import org.keycloak.jose.jws.JWSInput;
|
||||
import org.keycloak.jose.jws.JWSInputException;
|
||||
import org.keycloak.representations.RefreshToken;
|
||||
|
||||
/**
|
||||
@@ -41,11 +42,15 @@ public class TokenUtil {
|
||||
* @param decodedToken
|
||||
* @return
|
||||
*/
|
||||
public static RefreshToken getRefreshToken(byte[] decodedToken) throws IOException {
|
||||
return JsonSerialization.readValue(decodedToken, RefreshToken.class);
|
||||
public static RefreshToken getRefreshToken(byte[] decodedToken) throws JWSInputException {
|
||||
try {
|
||||
return JsonSerialization.readValue(decodedToken, RefreshToken.class);
|
||||
} catch (IOException e) {
|
||||
throw new JWSInputException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static RefreshToken getRefreshToken(String refreshToken) throws IOException {
|
||||
public static RefreshToken getRefreshToken(String refreshToken) throws JWSInputException {
|
||||
byte[] encodedContent = new JWSInput(refreshToken).getContent();
|
||||
return getRefreshToken(encodedContent);
|
||||
}
|
||||
@@ -56,13 +61,9 @@ public class TokenUtil {
|
||||
* @param refreshToken
|
||||
* @return
|
||||
*/
|
||||
public static boolean isOfflineToken(String refreshToken) {
|
||||
try {
|
||||
RefreshToken token = getRefreshToken(refreshToken);
|
||||
return token.getType().equals(TOKEN_TYPE_OFFLINE);
|
||||
} catch (IOException ioe) {
|
||||
throw new RuntimeException(ioe);
|
||||
}
|
||||
public static boolean isOfflineToken(String refreshToken) throws JWSInputException {
|
||||
RefreshToken token = getRefreshToken(refreshToken);
|
||||
return token.getType().equals(TOKEN_TYPE_OFFLINE);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user