KEYCLOAK-2106 HTTP 500 for unparsable refresh tokens

This commit is contained in:
Stian Thorgersen committed 2015-11-27 08:59:23 +01:00
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);
}
}