introduced Utility class to gether static methods; modified jwt signing and validation service interface, imps, and endpoint using; ...
parent
e8de5b4a8f
commit
95be182866
|
@ -30,9 +30,11 @@ public interface JwtSigningAndValidationService {
|
||||||
*
|
*
|
||||||
* @param jwt
|
* @param jwt
|
||||||
* the JWT to check the issuer of
|
* the JWT to check the issuer of
|
||||||
* @return true if the JWT was issued by this AS, false if not
|
* @param expectedIssuer
|
||||||
|
* the expected issuer
|
||||||
|
* @return true if the JWT was issued by this expected issuer, false if not
|
||||||
*/
|
*/
|
||||||
public boolean validateIssuedJwt(Jwt jwt);
|
public boolean validateIssuedJwt(Jwt jwt, String expectedIssuer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks the signature of the given JWT against all configured signers,
|
* Checks the signature of the given JWT against all configured signers,
|
||||||
|
|
|
@ -3,6 +3,7 @@ package org.mitre.jwt.signer.service.impl;
|
||||||
import java.security.PublicKey;
|
import java.security.PublicKey;
|
||||||
import java.security.interfaces.RSAPublicKey;
|
import java.security.interfaces.RSAPublicKey;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -19,6 +20,7 @@ import org.springframework.beans.factory.InitializingBean;
|
||||||
public class JwtSigningAndValidationServiceDefault implements
|
public class JwtSigningAndValidationServiceDefault implements
|
||||||
JwtSigningAndValidationService, InitializingBean {
|
JwtSigningAndValidationService, InitializingBean {
|
||||||
|
|
||||||
|
|
||||||
private List<? extends JwtSigner> signers = new ArrayList<JwtSigner>();
|
private List<? extends JwtSigner> signers = new ArrayList<JwtSigner>();
|
||||||
|
|
||||||
private static Log logger = LogFactory
|
private static Log logger = LogFactory
|
||||||
|
@ -40,7 +42,7 @@ public class JwtSigningAndValidationServiceDefault implements
|
||||||
List<? extends JwtSigner> signer) {
|
List<? extends JwtSigner> signer) {
|
||||||
setSigners(signer);
|
setSigners(signer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
*
|
*
|
||||||
|
@ -55,6 +57,7 @@ public class JwtSigningAndValidationServiceDefault implements
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info("JwtSigningAndValidationServiceDefault is open for business");
|
logger.info("JwtSigningAndValidationServiceDefault is open for business");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -111,8 +114,14 @@ public class JwtSigningAndValidationServiceDefault implements
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isJwtExpired(Jwt jwt) {
|
public boolean isJwtExpired(Jwt jwt) {
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return false;
|
Date expiration = jwt.getClaims().getExpiration();
|
||||||
|
|
||||||
|
if (expiration != null)
|
||||||
|
return new Date().after(expiration);
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -125,6 +134,9 @@ public class JwtSigningAndValidationServiceDefault implements
|
||||||
this.signers = signers;
|
this.signers = signers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see java.lang.Object#toString()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "JwtSigningAndValidationServiceDefault [signers=" + signers
|
return "JwtSigningAndValidationServiceDefault [signers=" + signers
|
||||||
|
@ -139,15 +151,11 @@ public class JwtSigningAndValidationServiceDefault implements
|
||||||
* (org.mitre.jwt.model.Jwt)
|
* (org.mitre.jwt.model.Jwt)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean validateIssuedJwt(Jwt jwt) {
|
public boolean validateIssuedJwt(Jwt jwt, String expectedIssuer) {
|
||||||
|
|
||||||
// TODO Verify this is correct...
|
|
||||||
|
|
||||||
for (JwtSigner signer : signers) {
|
|
||||||
if (signer.verify(jwt.toString()))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (jwt.getClaims().getIssuer() == expectedIssuer)
|
||||||
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
package org.mitre.openid.connect.web;
|
package org.mitre.openid.connect.web;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import org.mitre.jwt.signer.service.JwtSigningAndValidationService;
|
import org.mitre.jwt.signer.service.JwtSigningAndValidationService;
|
||||||
import org.mitre.openid.connect.exception.ExpiredTokenException;
|
import org.mitre.openid.connect.exception.ExpiredTokenException;
|
||||||
import org.mitre.openid.connect.exception.InvalidJwtIssuerException;
|
import org.mitre.openid.connect.exception.InvalidJwtIssuerException;
|
||||||
import org.mitre.openid.connect.exception.InvalidJwtSignatureException;
|
import org.mitre.openid.connect.exception.InvalidJwtSignatureException;
|
||||||
import org.mitre.openid.connect.model.IdToken;
|
import org.mitre.openid.connect.model.IdToken;
|
||||||
import org.mitre.openid.connect.model.IdTokenClaims;
|
import org.mitre.util.Utility;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
@ -18,9 +20,8 @@ public class CheckIDEndpoint {
|
||||||
@Autowired
|
@Autowired
|
||||||
JwtSigningAndValidationService jwtSignerService;
|
JwtSigningAndValidationService jwtSignerService;
|
||||||
|
|
||||||
|
|
||||||
@RequestMapping("/checkid")
|
@RequestMapping("/checkid")
|
||||||
public ModelAndView checkID(@RequestParam("id_token") String tokenString, ModelAndView mav) {
|
public ModelAndView checkID(@RequestParam("id_token") String tokenString, ModelAndView mav, HttpServletRequest request) {
|
||||||
|
|
||||||
if (!jwtSignerService.validateSignature(tokenString)) {
|
if (!jwtSignerService.validateSignature(tokenString)) {
|
||||||
// can't validate
|
// can't validate
|
||||||
|
@ -37,7 +38,7 @@ public class CheckIDEndpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
// check the issuer (sanity check)
|
// check the issuer (sanity check)
|
||||||
if (!jwtSignerService.validateIssuedJwt(token)) {
|
if (!jwtSignerService.validateIssuedJwt(token, Utility.findBaseUrl(request))) {
|
||||||
throw new InvalidJwtIssuerException(); // TODO: create a view for this exception
|
throw new InvalidJwtIssuerException(); // TODO: create a view for this exception
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,17 +3,15 @@ package org.mitre.swd.web;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.servlet.ServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.mitre.util.Utility;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.servlet.ModelAndView;
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
public class SimpleWebDiscoveryEndpoint {
|
public class SimpleWebDiscoveryEndpoint {
|
||||||
|
@ -22,7 +20,7 @@ public class SimpleWebDiscoveryEndpoint {
|
||||||
params={"principal", "service=http://openid.net/specs/connect/1.0/issuer"})
|
params={"principal", "service=http://openid.net/specs/connect/1.0/issuer"})
|
||||||
public ModelAndView openIdConnectIssuerDiscovery(@RequestParam("principal") String principal, ModelAndView modelAndView, HttpServletRequest request) {
|
public ModelAndView openIdConnectIssuerDiscovery(@RequestParam("principal") String principal, ModelAndView modelAndView, HttpServletRequest request) {
|
||||||
|
|
||||||
String baseUrl = findBaseUrl(request);
|
String baseUrl = Utility.findBaseUrl(request);
|
||||||
|
|
||||||
// look up user, see if they're local
|
// look up user, see if they're local
|
||||||
// if so, return this server
|
// if so, return this server
|
||||||
|
@ -42,7 +40,7 @@ public class SimpleWebDiscoveryEndpoint {
|
||||||
@RequestMapping("/.well-known/openid-configuration")
|
@RequestMapping("/.well-known/openid-configuration")
|
||||||
public ModelAndView providerConfiguration(ModelAndView modelAndView, HttpServletRequest request) {
|
public ModelAndView providerConfiguration(ModelAndView modelAndView, HttpServletRequest request) {
|
||||||
|
|
||||||
String baseUrl = findBaseUrl(request);
|
String baseUrl = Utility.findBaseUrl(request);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* version string Version of the provider response. "3.0" is the default.
|
* version string Version of the provider response. "3.0" is the default.
|
||||||
|
@ -90,17 +88,5 @@ public class SimpleWebDiscoveryEndpoint {
|
||||||
|
|
||||||
return modelAndView;
|
return modelAndView;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private String findBaseUrl(HttpServletRequest request) {
|
|
||||||
String baseUrl = String.format("%s://%s%s", request.getScheme(), request.getServerName(), request.getContextPath());
|
|
||||||
|
|
||||||
if ((request.getScheme().equals("http") && request.getServerPort() != 80)
|
|
||||||
|| (request.getScheme().equals("https") && request.getServerPort() != 443)) {
|
|
||||||
// nonstandard port, need to include it
|
|
||||||
baseUrl = String.format("%s://%s:%d%s", request.getScheme(), request.getServerName(), request.getServerPort(), request.getContextPath());
|
|
||||||
}
|
|
||||||
return baseUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
package org.mitre.util;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A collection of utility methods.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class Utility {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the base URL from a HttpServletRequest
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String findBaseUrl(HttpServletRequest request) {
|
||||||
|
String issuer = String.format("%s://%s%s", request.getScheme(),
|
||||||
|
request.getServerName(), request.getContextPath());
|
||||||
|
|
||||||
|
if ((request.getScheme().equals("http") && request.getServerPort() != 80)
|
||||||
|
|| (request.getScheme().equals("https") && request
|
||||||
|
.getServerPort() != 443)) {
|
||||||
|
// nonstandard port, need to include it
|
||||||
|
issuer = String.format("%s://%s:%d%s", request.getScheme(),
|
||||||
|
request.getServerName(), request.getServerPort(),
|
||||||
|
request.getContextPath());
|
||||||
|
}
|
||||||
|
return issuer;
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,7 +11,7 @@
|
||||||
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.1.xsd
|
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.1.xsd
|
||||||
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd
|
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd
|
||||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
|
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
|
||||||
http://www.mitre.org/schema/openid-connect/jwt-signer http://www.mitre.org/schema/openid-connect/jwt-signer/jwt-signer.xsd
|
http://www.mitre.org/schema/openid-connect/jwt-signer http://www.mitre.org/schema/openid-connect/jwt-signer/jwt-signer-1.0.xsd
|
||||||
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
|
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
|
||||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
|
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
|
||||||
|
|
||||||
|
@ -73,6 +73,8 @@
|
||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
<!-- TODO: working remove red X's see: http://forum.springsource.org/showthread.php?123193-STS-not-respecting-META-INF-spring-schemas-for-validation&p=401926#post401926 -->
|
||||||
|
|
||||||
<jwt-signer:keystore id="defaultKeystore" location="classpath:keystore.jks" password="changeit" />
|
<jwt-signer:keystore id="defaultKeystore" location="classpath:keystore.jks" password="changeit" />
|
||||||
|
|
||||||
<jwt-signer:service id="defaultSignerService">
|
<jwt-signer:service id="defaultSignerService">
|
||||||
|
|
|
@ -158,9 +158,8 @@ public class JwtTest {
|
||||||
String jwtString = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjEzMDA4MTkzODAsImlzcyI6ImpvZSIsImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.iGBPJj47S5q_HAhSoQqAdcS6A_1CFj3zrLaImqNbt9E";
|
String jwtString = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjEzMDA4MTkzODAsImlzcyI6ImpvZSIsImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.iGBPJj47S5q_HAhSoQqAdcS6A_1CFj3zrLaImqNbt9E";
|
||||||
|
|
||||||
boolean valid = signer.verify(jwtString);
|
boolean valid = signer.verify(jwtString);
|
||||||
|
|
||||||
assertThat(valid, equalTo(Boolean.TRUE));
|
assertThat(valid, equalTo(Boolean.TRUE));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue