smart client

pull/105/merge
Mike Derryberry 2012-06-12 16:09:01 -04:00
parent 3e810cb5dc
commit 65dc3daaf8
23 changed files with 359 additions and 128 deletions

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java"/>
<classpathentry kind="src" path="src/test/java"/>
<classpathentry kind="src" output="target/test-classes" path="src/test/java"/>
<classpathentry kind="src" path="src/test/resources"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project-modules id="moduleCoreId" project-version="1.5.0">
<wb-module deploy-name="openid-connect-client">
<wb-resource deploy-path="/" source-path="/src/main/java"/>
<wb-resource deploy-path="/" source-path="/src/main/resources"/>
<wb-resource deploy-path="/" source-path="/src/test/java"/>
<wb-resource deploy-path="/" source-path="/src/main/java"/>
<wb-resource deploy-path="/" source-path="/src/test/resources"/>
</wb-module>
</project-modules>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<beansProjectDescription>
<version>1</version>
<pluginVersion><![CDATA[2.9.1.201203220057-RELEASE]]></pluginVersion>
<configSuffixes>
<configSuffix><![CDATA[xml]]></configSuffix>
</configSuffixes>
<enableImports><![CDATA[false]]></enableImports>
<configs>
<config>spring-servlet.xml</config>
</configs>
<configSets>
</configSets>
</beansProjectDescription>

View File

@ -28,6 +28,7 @@ import java.security.SecureRandom;
import java.security.Signature;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
@ -42,9 +43,16 @@ import javax.servlet.http.HttpServletResponse;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.Validate;
import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.mitre.openid.connect.model.IdToken;
import org.mitre.jwt.model.Jwt;
import org.mitre.jwt.model.JwtHeader;
import org.mitre.jwt.model.JwtClaims;
import org.mitre.jwt.signer.AbstractJwtSigner;
import org.mitre.jwt.signer.impl.HmacSigner;
import org.mitre.jwt.signer.service.impl.DynamicJwtSigningAndValidationService;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.Authentication;
@ -60,6 +68,7 @@ import org.springframework.web.util.WebUtils;
import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
/**
@ -376,11 +385,12 @@ public class AbstractOIDCAuthenticationFilter extends
* authentication
* @return The authenticated user token, or null if authentication is
* incomplete.
* @throws Exception
* @throws UnsupportedEncodingException
*/
protected Authentication handleAuthorizationGrantResponse(
String authorizationGrant, HttpServletRequest request,
OIDCServerConfiguration serverConfig) {
OIDCServerConfiguration serverConfig) throws Exception {
final boolean debug = logger.isDebugEnabled();
@ -457,42 +467,45 @@ public class AbstractOIDCAuthenticationFilter extends
// Extract the id_token to insert into the
// OpenIdConnectAuthenticationToken
Cookie nonceSignatureCookie = WebUtils.getCookie(request,
NONCE_SIGNATURE_COOKIE_NAME);
IdToken idToken = null;
DynamicJwtSigningAndValidationService dynamic = new DynamicJwtSigningAndValidationService(null, null, null);
OIDCServerConfiguration oidc = new OIDCServerConfiguration();
if (jsonRoot.getAsJsonObject().get("id_token") != null) {
try {
idToken = IdToken.parse(jsonRoot.getAsJsonObject()
.get("id_token").getAsString());
if(dynamic.validateSignature(jsonRoot.getAsJsonObject().get("id_token").getAsString())
&&
dynamic.validateIssuedJwt(idToken, oidc.getIssuer())
&&
dynamic.validateAudience(idToken, oidc.getClientId())
&&
dynamic.isJwtExpired(idToken)
&&
dynamic.validateIssuedAt(idToken)
&&
dynamic.validateNonce(idToken, nonceSignatureCookie.getValue())){
try {
idToken = IdToken.parse(jsonRoot.getAsJsonObject().get("id_token").getAsString());
} catch (Exception e) {
List<String> parts = Lists.newArrayList(Splitter.on(".")
.split(jsonRoot.getAsJsonObject().get("id_token")
.getAsString()));
// I suspect this could happen
if (parts.size() != 3) {
throw new IllegalArgumentException(
"Invalid JWT format.");
logger.error("Problem parsing id_token: " + e);
// e.printStackTrace();
throw new AuthenticationServiceException(
"Problem parsing id_token return from Token endpoint: "
+ e);
}
String h64 = parts.get(0);
String c64 = parts.get(1);
String s64 = parts.get(2);
logger.debug("h64 = " + h64);
logger.debug("c64 = " + c64);
logger.debug("s64 = " + s64);
} catch (Exception e) {
// I suspect this could happen
logger.error("Problem parsing id_token: " + e);
// e.printStackTrace();
throw new AuthenticationServiceException(
"Problem parsing id_token return from Token endpoint: "
+ e);
}
else{
throw new AuthenticationServiceException("Problem verifying id_token");
}
} else {
@ -505,100 +518,58 @@ public class AbstractOIDCAuthenticationFilter extends
"Token Endpoint did not return a token_id");
}
// Handle Check ID Endpoint interaction
httpClient = new DefaultHttpClient();
httpClient.getParams().setParameter("http.socket.timeout",
new Integer(httpSocketTimeout));
factory = new HttpComponentsClientHttpRequestFactory(httpClient);
restTemplate = new RestTemplate(factory);
form = new LinkedMultiValueMap<String, String>();
form.add("access_token", jsonRoot.getAsJsonObject().get("id_token")
.getAsString());
jsonString = null;
try {
jsonString = restTemplate.postForObject(
serverConfig.getCheckIDEndpointURI(), form,
String.class);
} catch (HttpClientErrorException httpClientErrorException) {
// Handle error
logger.error("Check ID Endpoint error response: "
+ httpClientErrorException.getStatusText() + " : "
+ httpClientErrorException.getMessage());
throw new AuthenticationServiceException("Unable check token.");
}
jsonRoot = new JsonParser().parse(jsonString);
// String iss = jsonRoot.getAsJsonObject().get("iss")
// .getAsString();
String userId = jsonRoot.getAsJsonObject().get("user_id")
.getAsString();
//String userId = jsonRoot.getAsJsonObject().get("user_id")
// .getAsString();
// String aud = jsonRoot.getAsJsonObject().get("aud")
// .getAsString();
String nonce = jsonRoot.getAsJsonObject().get("nonce")
.getAsString();
//String nonce = jsonRoot.getAsJsonObject().get("nonce")
// .getAsString();
// String exp = jsonRoot.getAsJsonObject().get("exp")
// .getAsString();
// Compare returned ID Token to signed session cookie
// to detect ID Token replay by third parties.
Cookie nonceSignatureCookie = WebUtils.getCookie(request,
NONCE_SIGNATURE_COOKIE_NAME);
if (nonceSignatureCookie != null) {
String sigText = nonceSignatureCookie.getValue();
String sigText = nonceSignatureCookie.getValue();
if (sigText != null && !sigText.isEmpty()) {
if (sigText != null && !sigText.isEmpty()) {
if (!verify(signer, publicKey, nonce, sigText)) {
logger.error("Possible replay attack detected! "
+ "The comparison of the nonce in the returned "
+ "ID Token to the signed session "
+ NONCE_SIGNATURE_COOKIE_NAME + " failed.");
throw new AuthenticationServiceException(
"Possible replay attack detected! "
+ "The comparison of the nonce in the returned "
+ "ID Token to the signed session "
+ NONCE_SIGNATURE_COOKIE_NAME
+ " failed.");
}
} else {
logger.error(NONCE_SIGNATURE_COOKIE_NAME
+ " was found, but was null or empty.");
if (!verify(signer, publicKey, idToken.getClaims().getNonce(), sigText)) {
logger.error("Possible replay attack detected! "
+ "The comparison of the nonce in the returned "
+ "ID Token to the signed session "
+ NONCE_SIGNATURE_COOKIE_NAME + " failed.");
throw new AuthenticationServiceException(
NONCE_SIGNATURE_COOKIE_NAME
+ " was found, but was null or empty.");
"Possible replay attack detected! "
+ "The comparison of the nonce in the returned "
+ "ID Token to the signed session "
+ NONCE_SIGNATURE_COOKIE_NAME
+ " failed.");
}
} else {
logger.error(NONCE_SIGNATURE_COOKIE_NAME
+ " cookie was not found.");
+ " was found, but was null or empty.");
throw new AuthenticationServiceException(
NONCE_SIGNATURE_COOKIE_NAME + " cookie was not found.");
NONCE_SIGNATURE_COOKIE_NAME
+ " was found, but was null or empty.");
}
// Create an Authentication object for the token, and
// return.
OpenIdConnectAuthenticationToken token = new OpenIdConnectAuthenticationToken(
userId, idToken);
idToken.getTokenClaims().getUserId(), idToken);
Authentication authentication = this.getAuthenticationManager()
.authenticate(token);

View File

@ -97,9 +97,14 @@ public class OIDCAuthenticationFilter extends AbstractOIDCAuthenticationFilter {
} else if (StringUtils.isNotBlank(request.getParameter("code"))) {
return handleAuthorizationGrantResponse(
request.getParameter("code"), new SanatizedRequest(request,
new String[] { "code" }), oidcServerConfig);
try {
return handleAuthorizationGrantResponse(
request.getParameter("code"), new SanatizedRequest(request,
new String[] { "code" }), oidcServerConfig);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {

View File

@ -108,10 +108,15 @@ public class OIDCAuthenticationUsingChooserFilter extends
Cookie issuerCookie = WebUtils.getCookie(request,
ISSUER_COOKIE_NAME);
return handleAuthorizationGrantResponse(
request.getParameter("code"), new SanatizedRequest(request,
new String[] { "code" }),
oidcServerConfigs.get(issuerCookie.getValue()));
try {
return handleAuthorizationGrantResponse(
request.getParameter("code"), new SanatizedRequest(request,
new String[] { "code" }),
oidcServerConfigs.get(issuerCookie.getValue()));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {

View File

@ -16,19 +16,19 @@
package org.mitre.openid.connect.client;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.Key;
import org.mitre.jwt.signer.service.impl.DynamicJwtSigningAndValidationService;
import org.mitre.util.Utility;
import com.google.gson.JsonObject;
/**
* @author nemonik
*
*/
public class OIDCServerConfiguration {
DynamicJwtSigningAndValidationService dynamic;
private String authorizationEndpointURI;
@ -40,6 +40,8 @@ public class OIDCServerConfiguration {
private String clientId;
private String issuer;
private String x509EncryptUrl;
private String x509SigningUrl;
@ -63,6 +65,10 @@ public class OIDCServerConfiguration {
public String getClientId() {
return clientId;
}
public String getIssuer() {
return issuer;
}
public String getClientSecret() {
return clientSecret;
@ -84,6 +90,10 @@ public class OIDCServerConfiguration {
this.clientId = clientId;
}
public void setIssuer(String issuer) {
this.issuer = issuer;
}
public void setClientSecret(String clientSecret) {
this.clientSecret = clientSecret;
}
@ -169,11 +179,18 @@ public class OIDCServerConfiguration {
+ authorizationEndpointURI + ", tokenEndpointURI="
+ tokenEndpointURI + ", checkIDEndpointURI="
+ checkIDEndpointURI + ", clientSecret=" + clientSecret
+ ", clientId=" + clientId + ", x509EncryptedUrl="
+ ", clientId=" + clientId + ", issuer=" + issuer
+", x509EncryptedUrl="
+ x509EncryptUrl + ", jwkEncryptedUrl="
+ jwkEncryptUrl + ", x509SigningUrl="
+ x509SigningUrl + ", jwkSigningUrl="
+ jwkSigningUrl + "]";
}
public DynamicJwtSigningAndValidationService getDynamic() throws Exception{
dynamic = new DynamicJwtSigningAndValidationService(getX509SigningUrl(), getJwkSigningUrl(), getClientSecret());
return dynamic;
}
}
}

View File

@ -0,0 +1,39 @@
package org.mitre.openid.connect.client;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import org.mitre.openid.connect.model.IdToken;
import org.springframework.security.core.userdetails.AuthenticationUserDetailsService;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
public class OIDCUserDetailService implements UserDetailsService,
AuthenticationUserDetailsService<OpenIdConnectAuthenticationToken> {
public IdToken retrieveToken(URL url) throws IOException{
String str = new BufferedReader(new InputStreamReader(url.openStream())).toString();
IdToken idToken = IdToken.parse(str);
return idToken;
}
@Override
public UserDetails loadUserDetails(OpenIdConnectAuthenticationToken token)
throws UsernameNotFoundException {
// TODO Auto-generated method stub
return null;
}
@Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException {
// TODO Auto-generated method stub
return null;
}
}

View File

@ -101,4 +101,14 @@ public class OIDCServerConfigurationTest extends TestCase {
Key key3 = oidc.getEncryptionKey();
assertEquals(key3, null);
}
@Test
public void testGetDynamic() throws Exception {
oidc.setX509SigningUrl(x509Url.getPath());
oidc.setJwkSigningUrl(jwkUrl.getPath());
oidc.setClientSecret("foo");
assertEquals(oidc.getDynamic().getSigningX509Url(), x509Url.getPath());
assertEquals(oidc.getDynamic().getSigningJwkUrl(), jwkUrl.getPath());
assertEquals(oidc.getDynamic().getClientSecret(), "foo");
}
}

View File

@ -0,0 +1,8 @@
{"jwk":
[
{"alg":"RSA",
"mod": "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw",
"exp":"AQAB",
"kid":"2011-04-29"}
]
}

View File

@ -0,0 +1,8 @@
{"jwk":
[
{"alg":"RSA",
"mod": "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw",
"exp":"AQAB",
"kid":"2011-04-29"}
]
}

View File

@ -0,0 +1,15 @@
-----BEGIN CERTIFICATE-----
MIICxDCCAi0CBECcV/wwDQYJKoZIhvcNAQEEBQAwgagxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIEwVU
ZXhhczEPMA0GA1UEBxMGQXVzdGluMSowKAYDVQQKEyFUaGUgVW5pdmVyc2l0eSBvZiBUZXhhcyBh
dCBBdXN0aW4xKDAmBgNVBAsTH0luZm9ybWF0aW9uIFRlY2hub2xvZ3kgU2VydmljZXMxIjAgBgNV
BAMTGXhtbGdhdGV3YXkuaXRzLnV0ZXhhcy5lZHUwHhcNMDQwNTA4MDM0NjA0WhcNMDQwODA2MDM0
NjA0WjCBqDELMAkGA1UEBhMCVVMxDjAMBgNVBAgTBVRleGFzMQ8wDQYDVQQHEwZBdXN0aW4xKjAo
BgNVBAoTIVRoZSBVbml2ZXJzaXR5IG9mIFRleGFzIGF0IEF1c3RpbjEoMCYGA1UECxMfSW5mb3Jt
YXRpb24gVGVjaG5vbG9neSBTZXJ2aWNlczEiMCAGA1UEAxMZeG1sZ2F0ZXdheS5pdHMudXRleGFz
LmVkdTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAsmc+6+NjLmanvh+FvBziYdBwTiz+d/DZ
Uy2jyvij6f8Xly6zkhHLSsuBzw08wPzr2K+F359bf9T3uiZMuao//FBGtDrTYpvQwkn4PFZwSeY2
Ynw4edxp1JEWT2zfOY+QJDfNgpsYQ9hrHDwqnpbMVVqjdBq5RgTKGhFBj9kxEq0CAwEAATANBgkq
hkiG9w0BAQQFAAOBgQCPYGXF6oRbnjti3CPtjfwORoO7ab1QzNS9Z2rLMuPnt6POlm1A3UPEwCS8
6flTlAqg19Sh47H7+Iq/LuzotKvUE5ugK52QRNMa4c0OSaO5UEM5EfVox1pT9tZV1Z3whYYMhThg
oC4y/On0NUVMN5xfF/GpSACga/bVjoNvd8HWEg==
-----END CERTIFICATE-----

View File

@ -0,0 +1,15 @@
-----BEGIN CERTIFICATE-----
MIICxDCCAi0CBECcV/wwDQYJKoZIhvcNAQEEBQAwgagxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIEwVU
ZXhhczEPMA0GA1UEBxMGQXVzdGluMSowKAYDVQQKEyFUaGUgVW5pdmVyc2l0eSBvZiBUZXhhcyBh
dCBBdXN0aW4xKDAmBgNVBAsTH0luZm9ybWF0aW9uIFRlY2hub2xvZ3kgU2VydmljZXMxIjAgBgNV
BAMTGXhtbGdhdGV3YXkuaXRzLnV0ZXhhcy5lZHUwHhcNMDQwNTA4MDM0NjA0WhcNMDQwODA2MDM0
NjA0WjCBqDELMAkGA1UEBhMCVVMxDjAMBgNVBAgTBVRleGFzMQ8wDQYDVQQHEwZBdXN0aW4xKjAo
BgNVBAoTIVRoZSBVbml2ZXJzaXR5IG9mIFRleGFzIGF0IEF1c3RpbjEoMCYGA1UECxMfSW5mb3Jt
YXRpb24gVGVjaG5vbG9neSBTZXJ2aWNlczEiMCAGA1UEAxMZeG1sZ2F0ZXdheS5pdHMudXRleGFz
LmVkdTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAsmc+6+NjLmanvh+FvBziYdBwTiz+d/DZ
Uy2jyvij6f8Xly6zkhHLSsuBzw08wPzr2K+F359bf9T3uiZMuao//FBGtDrTYpvQwkn4PFZwSeY2
Ynw4edxp1JEWT2zfOY+QJDfNgpsYQ9hrHDwqnpbMVVqjdBq5RgTKGhFBj9kxEq0CAwEAATANBgkq
hkiG9w0BAQQFAAOBgQCPYGXF6oRbnjti3CPtjfwORoO7ab1QzNS9Z2rLMuPnt6POlm1A3UPEwCS8
6flTlAqg19Sh47H7+Iq/LuzotKvUE5ugK52QRNMa4c0OSaO5UEM5EfVox1pT9tZV1Z3whYYMhThg
oC4y/On0NUVMN5xfF/GpSACga/bVjoNvd8HWEg==
-----END CERTIFICATE-----

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java"/>
<classpathentry kind="src" path="src/test/java"/>
<classpathentry kind="src" output="target/test-classes" path="src/test/java"/>
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
@ -11,4 +11,3 @@
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>

View File

@ -2,6 +2,5 @@
<project-modules id="moduleCoreId" project-version="1.5.0">
<wb-module deploy-name="openid-connect-common">
<wb-resource deploy-path="/" source-path="/src/main/java"/>
<wb-resource deploy-path="/" source-path="/src/test/java"/>
</wb-module>
</project-modules>

View File

@ -15,12 +15,7 @@
******************************************************************************/
package org.mitre.jwt.model;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import com.google.gson.JsonElement;

View File

@ -17,7 +17,6 @@ package org.mitre.jwt.signer.service;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.util.List;
import java.util.Map;
import org.mitre.jwt.model.Jwt;
@ -72,6 +71,39 @@ public interface JwtSigningAndValidationService {
* @return the signed jwt
* @throws NoSuchAlgorithmException
*/
public boolean validateIssuedAt(Jwt jwt);
/**
* Checks to see when this JWT was issued
*
* @param jwt
* the JWT to check
* @return true if the issued at is valid, false if not
* @throws NoSuchAlgorithmException
*/
public boolean validateAudience(Jwt jwt, String clientId);
/**
* Checks the audience that the given JWT against the client_id of the Client
*
* @param jwt
* @param clientId
* the string representation of the client_id
* @return true if the audience matches the clinet_id, false if otherwise
* @throws NoSuchAlgorithmException
*/
public boolean validateNonce(Jwt jwt, String nonce);
/**
* Checks to see if the nonce parameter sent in the Authorization Request
* is equal to the nonce parameter in the id token
*
* @param jwt
* @param nonce
* the string representation of the Nonce
* @return true if both nonce parameters are equal, false if otherwise
* @throws NoSuchAlgorithmException
*/
public void signJwt(Jwt jwt) throws NoSuchAlgorithmException;
/**

View File

@ -50,5 +50,36 @@ public abstract class AbstractJwtSigningAndValidationService implements JwtSigni
return false;
}
@Override
public boolean validateIssuedAt(Jwt jwt) {
Date issuedAt = jwt.getClaims().getIssuedAt();
if (issuedAt != null)
return new Date().before(issuedAt);
else
return false;
}
@Override
public boolean validateAudience(Jwt jwt, String clientId) {
if(jwt.getClaims().getAudience().equals(clientId)){
return true;
}
else{
return false;
}
}
@Override
public boolean validateNonce(Jwt jwt, String nonce) {
if(jwt.getClaims().getNonce().equals(nonce)){
return true;
}
else{
return false;
}
}
}

View File

@ -5,6 +5,7 @@ import java.net.URL;
import java.security.Key;
import java.security.PublicKey;
import java.security.interfaces.RSAPublicKey;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@ -33,9 +34,6 @@ public class DynamicJwtSigningAndValidationService extends AbstractJwtSigningAnd
private Map<String, ? extends JwtSigner> signers;
private String signingAlgorithm;
public DynamicJwtSigningAndValidationService(String x509SigningUrl, String jwkSigningUrl, String clientSecret) throws Exception {
setX509SigningUrl(x509SigningUrl);
setJwkSigningUrl(jwkSigningUrl);
@ -143,4 +141,35 @@ public class DynamicJwtSigningAndValidationService extends AbstractJwtSigningAnd
return signer;
}
}
@Override
public boolean validateIssuedAt(Jwt jwt) {
Date issuedAt = jwt.getClaims().getIssuedAt();
if (issuedAt != null)
return new Date().before(issuedAt);
else
return false;
}
@Override
public boolean validateAudience(Jwt jwt, String clientId) {
if(jwt.getClaims().getAudience().equals(clientId)){
return true;
}
else{
return false;
}
}
@Override
public boolean validateNonce(Jwt jwt, String nonce) {
if(jwt.getClaims().getNonce().equals(nonce)){
return true;
}
else{
return false;
}
}
}

View File

@ -17,7 +17,7 @@ package org.mitre.jwt.signer.service.impl;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.interfaces.RSAPublicKey;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@ -163,4 +163,35 @@ public class JwtSigningAndValidationServiceDefault extends AbstractJwtSigningAnd
public Map<String, ? extends JwtSigner> getSigners() {
return signers;
}
@Override
public boolean validateIssuedAt(Jwt jwt) {
Date issuedAt = jwt.getClaims().getIssuedAt();
if (issuedAt != null)
return new Date().before(issuedAt);
else
return false;
}
@Override
public boolean validateAudience(Jwt jwt, String clientId) {
if(clientId.equals(jwt.getClaims().getAudience())){
return true;
}
else{
return false;
}
}
@Override
public boolean validateNonce(Jwt jwt, String nonce) {
if(nonce.equals(jwt.getClaims().getNonce())){
return true;
}
else{
return false;
}
}
}

View File

@ -18,6 +18,7 @@
*/
package org.mitre.openid.connect.token;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.Map;
import java.util.Set;
@ -30,6 +31,7 @@ import org.mitre.openid.connect.config.ConfigurationPropertiesBean;
import org.mitre.openid.connect.model.IdToken;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.exceptions.InvalidClientException;
import org.springframework.security.oauth2.common.exceptions.InvalidGrantException;
@ -112,10 +114,13 @@ public class ConnectAuthCodeTokenGranter implements TokenGranter {
* @param parameters
* @param clientId
* @param scope
* @throws NoSuchAlgorithmException
* @throws AuthenticationException
* @throws InvalidGrantException
*/
@Override
public OAuth2AccessToken grant(String grantType,
Map<String, String> parameters, String clientId, Set<String> scope) {
Map<String, String> parameters, String clientId, Set<String> scope) throws NoSuchAlgorithmException, InvalidGrantException, AuthenticationException {
if (!GRANT_TYPE.equals(grantType)) {
return null;

View File

@ -15,6 +15,8 @@
******************************************************************************/
package org.mitre.openid.connect.web;
import java.security.NoSuchAlgorithmException;
import javax.servlet.http.HttpServletRequest;
import org.mitre.jwt.signer.service.JwtSigningAndValidationService;
@ -44,7 +46,7 @@ public class CheckIDEndpoint {
@PreAuthorize("hasRole('ROLE_USER')")
@RequestMapping("/checkid")
public ModelAndView checkID(@RequestParam("access_token") String tokenString, ModelAndView mav, HttpServletRequest request) {
public ModelAndView checkID(@RequestParam("access_token") String tokenString, ModelAndView mav, HttpServletRequest request) throws NoSuchAlgorithmException {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

View File

@ -21,6 +21,7 @@ import static org.junit.Assert.assertThat;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.X509Certificate;
@ -198,7 +199,7 @@ public class JwtTest {
}
@Test
public void testToStringPlaintext() {
public void testToStringPlaintext() throws NoSuchAlgorithmException {
Jwt jwt = new Jwt();
jwt.getHeader().setAlgorithm("none");
jwt.getClaims().setExpiration(new Date(1300819380L * 1000L));