converted bearer assertion framework to nimbus-jose

pull/306/merge
Justin Richer 2013-02-19 14:23:07 -05:00
parent 910a6cf1a0
commit c7d1b47b38
3 changed files with 46 additions and 44 deletions

View File

@ -5,10 +5,11 @@ package org.mitre.openid.connect.assertion;
import java.util.Collection;
import org.mitre.jwt.model.Jwt;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import com.nimbusds.jwt.JWT;
/**
* @author jricher
*
@ -16,16 +17,27 @@ import org.springframework.security.core.GrantedAuthority;
public class JwtBearerAssertionAuthenticationToken extends AbstractAuthenticationToken {
private String clientId;
private Jwt jwt;
private JWT jwt;
public JwtBearerAssertionAuthenticationToken(String clientId, Jwt jwt) {
/**
* Create an unauthenticated token with the given client ID and jwt
* @param clientId
* @param jwt
*/
public JwtBearerAssertionAuthenticationToken(String clientId, JWT jwt) {
super(null);
this.clientId = clientId;
this.jwt = jwt;
setAuthenticated(false);
}
public JwtBearerAssertionAuthenticationToken(String clientId, Jwt jwt, Collection<? extends GrantedAuthority> authorities) {
/**
* Create an authenticated token with the given clientID, jwt, and authorities set
* @param clientId
* @param jwt
* @param authorities
*/
public JwtBearerAssertionAuthenticationToken(String clientId, JWT jwt, Collection<? extends GrantedAuthority> authorities) {
super(authorities);
this.clientId = clientId;
this.jwt = jwt;
@ -65,14 +77,14 @@ public class JwtBearerAssertionAuthenticationToken extends AbstractAuthenticatio
/**
* @return the jwt
*/
public Jwt getJwt() {
public JWT getJwt() {
return jwt;
}
/**
* @param jwt the jwt to set
*/
public void setJwt(Jwt jwt) {
public void setJwt(JWT jwt) {
this.jwt = jwt;
}

View File

@ -3,39 +3,25 @@
*/
package org.mitre.openid.connect.assertion;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.interfaces.RSAPublicKey;
import java.text.ParseException;
import java.util.Date;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import org.mitre.jwt.model.Jwt;
import org.mitre.jwt.model.JwtClaims;
import org.mitre.jwt.model.JwtHeader;
import org.mitre.jwt.signer.JwsAlgorithm;
import org.mitre.jwt.signer.JwtSigner;
import org.mitre.jwt.signer.impl.RsaSigner;
import org.mitre.jwt.signer.service.JwtSigningAndValidationService;
import org.mitre.jwt.signer.service.impl.DefaultJwtSigningAndValidationService;
import org.mitre.key.fetch.KeyFetcher;
import org.mitre.oauth2.exception.ClientNotFoundException;
import org.mitre.oauth2.model.ClientDetailsEntity;
import org.mitre.oauth2.service.ClientDetailsEntityService;
import org.mitre.openid.connect.config.ConfigurationPropertiesBean;
import org.mitre.openid.connect.config.OIDCServerConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import com.nimbusds.jose.JOSEException;
@ -43,7 +29,7 @@ import com.nimbusds.jose.JWSObject;
import com.nimbusds.jose.JWSVerifier;
import com.nimbusds.jose.crypto.RSASSAVerifier;
import com.nimbusds.jwt.JWT;
import com.nimbusds.jwt.JWTParser;
import com.nimbusds.jwt.ReadOnlyJWTClaimsSet;
/**
* @author jricher
@ -79,8 +65,8 @@ public class JwtBearerAuthenticationProvider implements AuthenticationProvider {
try {
ClientDetailsEntity client = clientService.loadClientByClientId(jwtAuth.getClientId());
Jwt jwt = jwtAuth.getJwt();
JwtClaims jwtClaims = jwt.getClaims();
JWT jwt = jwtAuth.getJwt();
ReadOnlyJWTClaimsSet jwtClaims = jwt.getJWTClaimsSet();
// check the signature with nimbus
JWSVerifier verifier = getVerifierForClient(client);
@ -90,20 +76,22 @@ public class JwtBearerAuthenticationProvider implements AuthenticationProvider {
}
// check the issuer
if (jwtClaims.getIssuer() == null) {
if (jwtClaims.getIssuerClaim() == null) {
throw new AuthenticationServiceException("Assertion Token Issuer is null");
} else if (!jwtClaims.getIssuer().equals(client.getClientId())){
throw new AuthenticationServiceException("Issuers do not match, expected " + client.getClientId() + " got " + jwtClaims.getIssuer());
} else if (!jwtClaims.getIssuerClaim().equals(client.getClientId())){
throw new AuthenticationServiceException("Issuers do not match, expected " + client.getClientId() + " got " + jwtClaims.getIssuerClaim());
}
// check expiration
if (jwtClaims.getExpiration() == null) {
/*
* FIXME: re-institute date check for Nimbus
if (jwtClaims.getExpirationTimeClaim() == null) {
throw new AuthenticationServiceException("Assertion Token does not have required expiration claim");
} else {
// it's not null, see if it's expired
Date now = new Date(System.currentTimeMillis() - (timeSkewAllowance * 1000));
if (now.after(jwtClaims.getExpiration())) {
throw new AuthenticationServiceException("Assertion Token is expired: " + jwtClaims.getExpiration());
if (now.after(jwtClaims.getExpirationTimeClaim())) {
throw new AuthenticationServiceException("Assertion Token is expired: " + jwtClaims.getExpirationTimeClaim());
}
}
@ -115,13 +103,6 @@ public class JwtBearerAuthenticationProvider implements AuthenticationProvider {
}
}
// check audience
if (jwtClaims.getAudience() == null) {
throw new AuthenticationServiceException("Assertion token audience is null");
} else if (!jwtClaims.getAudience().contains(config.getIssuer())) {
throw new AuthenticationServiceException("Audience does not match, expected " + config.getIssuer() + " got " + jwtClaims.getAudience());
}
// check issued at
if (jwtClaims.getIssuedAt() != null) {
// since it's not null, see if it was issued in the future
@ -130,7 +111,16 @@ public class JwtBearerAuthenticationProvider implements AuthenticationProvider {
throw new AuthenticationServiceException("Assertion Token was issued in the future: " + jwtClaims.getIssuedAt());
}
}
*/
// check audience
if (jwtClaims.getAudienceClaim() == null) {
throw new AuthenticationServiceException("Assertion token audience is null");
} else if (!Arrays.asList(jwtClaims.getAudienceClaim()).contains(config.getIssuer())) { // FIXME: change back to list.contains() check after Nimbus update
throw new AuthenticationServiceException("Audience does not match, expected " + config.getIssuer() + " got " + jwtClaims.getAudienceClaim());
}
// IFF we managed to get all the way down here, the token is valid
return new JwtBearerAssertionAuthenticationToken(client.getClientId(), jwt, client.getAuthorities());

View File

@ -4,20 +4,20 @@
package org.mitre.openid.connect.assertion;
import java.io.IOException;
import java.text.ParseException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.mitre.jwt.model.Jwt;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import com.google.common.base.Strings;
import com.nimbusds.jwt.JWT;
import com.nimbusds.jwt.JWTParser;
/**
* Filter to check client authentication via JWT Bearer assertions.
@ -48,14 +48,14 @@ public class JwtBearerClientAssertionTokenEndpointFilter extends ClientCredentia
String assertion = request.getParameter("client_assertion");
try {
Jwt jwt = Jwt.parse(assertion);
JWT jwt = JWTParser.parse(assertion);
String clientId = jwt.getClaims().getSubject();
String clientId = jwt.getJWTClaimsSet().getSubjectClaim();
Authentication authRequest = new JwtBearerAssertionAuthenticationToken(clientId, jwt);
return this.getAuthenticationManager().authenticate(authRequest);
} catch (IllegalArgumentException e) {
} catch (ParseException e) {
throw new BadCredentialsException("Invalid JWT credential: " + assertion);
}
}