it spits out JWTs! and id tokens! JWT still needs to handle nulls

pull/59/head
Justin Richer 2012-03-21 17:59:48 -04:00
parent ebe72412fe
commit c59d3fe963
9 changed files with 88 additions and 16 deletions

View File

@ -124,6 +124,11 @@ public class Jwt {
*/ */
public static Jwt parse(String s) { public static Jwt parse(String s) {
// null string is a null token
if (s == null) {
return null;
}
// split on the dots // split on the dots
List<String> parts = Lists.newArrayList(Splitter.on(".").split(s)); List<String> parts = Lists.newArrayList(Splitter.on(".").split(s));

View File

@ -4,6 +4,7 @@
package org.mitre.oauth2.model; package org.mitre.oauth2.model;
import java.util.Date; import java.util.Date;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -44,8 +45,8 @@ import org.springframework.security.oauth2.provider.OAuth2Authentication;
@NamedQuery(name = "OAuth2AccessTokenEntity.getByClient", query = "select a from OAuth2AccessTokenEntity a where a.client = :client"), @NamedQuery(name = "OAuth2AccessTokenEntity.getByClient", query = "select a from OAuth2AccessTokenEntity a where a.client = :client"),
@NamedQuery(name = "OAuth2AccessTokenEntity.getExpired", query = "select a from OAuth2AccessTokenEntity a where a.expiration is not null and a.expiration < current_timestamp") @NamedQuery(name = "OAuth2AccessTokenEntity.getExpired", query = "select a from OAuth2AccessTokenEntity a where a.expiration is not null and a.expiration < current_timestamp")
}) })
@JsonSerialize(using = OAuth2AccessTokenSerializer.class) //@JsonSerialize(using = OAuth2AccessTokenSerializer.class)
@JsonDeserialize(using = OAuth2AccessTokenDeserializer.class) //@JsonDeserialize(using = OAuth2AccessTokenDeserializer.class)
public class OAuth2AccessTokenEntity extends OAuth2AccessToken { public class OAuth2AccessTokenEntity extends OAuth2AccessToken {
public static String ID_TOKEN = "id_token"; public static String ID_TOKEN = "id_token";
@ -67,7 +68,7 @@ public class OAuth2AccessTokenEntity extends OAuth2AccessToken {
// we ignore the "value" field in the superclass because we can't cleanly override it // we ignore the "value" field in the superclass because we can't cleanly override it
super(null); super(null);
setJwt(new Jwt()); // give us a blank jwt to work with at least setJwt(new Jwt()); // give us a blank jwt to work with at least
setIdToken(new IdToken()); // and a blank IdToken //setIdToken(new IdToken()); // ID Tokens aren't there unless we need them
} }
/** /**
@ -76,7 +77,7 @@ public class OAuth2AccessTokenEntity extends OAuth2AccessToken {
@Override @Override
@Transient @Transient
public Map<String, Object> getAdditionalInformation() { public Map<String, Object> getAdditionalInformation() {
Map<String, Object> map = super.getAdditionalInformation(); Map<String, Object> map = new HashMap<String, Object>(); //super.getAdditionalInformation();
map.put(ID_TOKEN, getIdTokenString()); map.put(ID_TOKEN, getIdTokenString());
return map; return map;
} }
@ -265,7 +266,11 @@ public class OAuth2AccessTokenEntity extends OAuth2AccessToken {
*/ */
@Basic @Basic
public String getIdTokenString() { public String getIdTokenString() {
return idToken.toString(); if (idToken != null) {
return idToken.toString();
} else {
return null;
}
} }
/** /**

View File

@ -82,10 +82,15 @@ public class IdToken extends Jwt {
* *
*/ */
public static IdToken parse(String s) { public static IdToken parse(String s) {
// TODO: this code was copied nearly verbatim from Jwt.parse, and // TODO: this code was copied nearly verbatim from Jwt.parse, and
// we should figure out how to re-use and abstract bits, likely // we should figure out how to re-use and abstract bits, likely
// null string is a null token
if (s == null) {
return null;
}
// split on the dots // split on the dots
List<String> parts = Lists.newArrayList(Splitter.on(".").split(s)); List<String> parts = Lists.newArrayList(Splitter.on(".").split(s));

View File

@ -121,7 +121,11 @@ public class IdTokenClaims extends JwtClaims {
} }
} }
//
// FIXME:
// This doesn't handle loading JsonNull values from the claims set, and this is endemic to the whole claims structure!!!!
//
/** /**
* Load this IdToken from a JSON Object * Load this IdToken from a JSON Object
*/ */

View File

@ -23,4 +23,9 @@ public interface OAuth2TokenEntityService extends AuthorizationServerTokenServic
public List<OAuth2RefreshTokenEntity> getRefreshTokensForClient(ClientDetailsEntity client); public List<OAuth2RefreshTokenEntity> getRefreshTokensForClient(ClientDetailsEntity client);
public void clearExpiredTokens(); public void clearExpiredTokens();
public OAuth2AccessTokenEntity saveAccessToken(OAuth2AccessTokenEntity accessToken);
public OAuth2RefreshTokenEntity saveRefreshToken(OAuth2RefreshTokenEntity refreshToken);
} }

View File

@ -336,4 +336,22 @@ public class DefaultOAuth2ProviderTokenService implements OAuth2TokenEntityServi
return null; return null;
} }
/* (non-Javadoc)
* @see org.mitre.oauth2.service.OAuth2TokenEntityService#saveAccessToken(org.mitre.oauth2.model.OAuth2AccessTokenEntity)
*/
@Override
public OAuth2AccessTokenEntity saveAccessToken(OAuth2AccessTokenEntity accessToken) {
return tokenRepository.saveAccessToken(accessToken);
}
/* (non-Javadoc)
* @see org.mitre.oauth2.service.OAuth2TokenEntityService#saveRefreshToken(org.mitre.oauth2.model.OAuth2RefreshTokenEntity)
*/
@Override
public OAuth2RefreshTokenEntity saveRefreshToken(OAuth2RefreshTokenEntity refreshToken) {
return tokenRepository.saveRefreshToken(refreshToken);
}
} }

View File

@ -3,6 +3,7 @@
*/ */
package org.mitre.openid.connect.token; package org.mitre.openid.connect.token;
import java.util.Date;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -47,7 +48,7 @@ public class ConnectAuthCodeTokenGranter implements TokenGranter {
@Autowired @Autowired
private ClientCredentialsChecker clientCredentialsChecker; private ClientCredentialsChecker clientCredentialsChecker;
private String issuer;
//TODO: Do we need to modify/update this? //TODO: Do we need to modify/update this?
@Autowired @Autowired
@ -56,7 +57,6 @@ public class ConnectAuthCodeTokenGranter implements TokenGranter {
@Autowired @Autowired
private IdTokenGeneratorService idTokenService; private IdTokenGeneratorService idTokenService;
/** /**
* Default empty constructor * Default empty constructor
*/ */
@ -137,7 +137,15 @@ public class ConnectAuthCodeTokenGranter implements TokenGranter {
//TODO: should not need cast //TODO: should not need cast
OAuth2AccessTokenEntity token = (OAuth2AccessTokenEntity) tokenServices.createAccessToken(new OAuth2Authentication(authorizationRequest, userAuth)); OAuth2AccessTokenEntity token = (OAuth2AccessTokenEntity) tokenServices.createAccessToken(new OAuth2Authentication(authorizationRequest, userAuth));
//set audience, auth time, issuer token.getJwt().getClaims().setAudience(clientId);
//TODO: need to get base url, but Utility.findBaseUrl() needs access to a request object, which we don't have
//See github issue #1
token.getJwt().getClaims().setIssuer(issuer);
token.getJwt().getClaims().setIssuedAt(new Date());
// handle expiration
//token.getJwt().getClaims().setExpiration(token.getExpiration());
/** /**
* Authorization request scope MUST include "openid", but access token request * Authorization request scope MUST include "openid", but access token request
@ -146,15 +154,19 @@ public class ConnectAuthCodeTokenGranter implements TokenGranter {
*/ */
if (authorizationRequest.getScope().contains("openid")) { if (authorizationRequest.getScope().contains("openid")) {
String userId = parameters.get("user_id"); String userId = userAuth.getName();
//TODO: need to get base url, but Utility.findBaseUrl() needs access to a request object, which we don't have //TODO: need to get base url, but Utility.findBaseUrl() needs access to a request object, which we don't have
//See github issue #1 //See github issue #1
IdToken idToken = idTokenService.generateIdToken(userId, "http://id.mitre.org/openidconnect"); IdToken idToken = idTokenService.generateIdToken(userId, issuer);
idToken.getClaims().setAudience(clientId); idToken.getClaims().setAudience(clientId);
idToken.getClaims().setIssuedAt(new Date());
// TODO: expiration? other fields?
token.setIdToken(idToken); token.setIdToken(idToken);
} }
tokenServices.saveAccessToken(token);
return token; return token;
} }
@ -194,5 +206,19 @@ public class ConnectAuthCodeTokenGranter implements TokenGranter {
public void setTokenServices(OAuth2TokenEntityService tokenServices) { public void setTokenServices(OAuth2TokenEntityService tokenServices) {
this.tokenServices = tokenServices; this.tokenServices = tokenServices;
} }
/**
* @return the issuer
*/
public String getIssuer() {
return issuer;
}
/**
* @param issuer the issuer to set
*/
public void setIssuer(String issuer) {
this.issuer = issuer;
}
} }

View File

@ -53,4 +53,8 @@
<oauth:authorization-code authorization-code-services-ref="authCodeServices"/> <oauth:authorization-code authorization-code-services-ref="authCodeServices"/>
</oauth:authorization-server> </oauth:authorization-server>
<beans:bean id="connectAuthCodeTokenGranter" class="org.mitre.openid.connect.token.ConnectAuthCodeTokenGranter">
<beans:property name="issuer" value="http://localhost/" />
</beans:bean>
</beans:beans> </beans:beans>

View File

@ -5,9 +5,9 @@
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="DB_URL" /> <property name="url" value="jdbc:mysql://localhost/oic" />
<property name="username" value="DB_USER" /> <property name="username" value="oic" />
<property name="password" value="DB_PASSWORD" /> <property name="password" value="oic" />
</bean> </bean>
</beans> </beans>