externalized a number of strings, closes #385

pull/779/head
Justin Richer 2015-02-17 14:39:15 -05:00
parent 05f03f7c90
commit cef6cf17b6
12 changed files with 295 additions and 165 deletions

View File

@ -0,0 +1,41 @@
package org.mitre.oauth2.model;
public interface RegisteredClientFields {
public String CLIENT_SECRET_EXPIRES_AT = "client_secret_expires_at";
public String CLIENT_ID_ISSUED_AT = "client_id_issued_at";
public String REGISTRATION_CLIENT_URI = "registration_client_uri";
public String REGISTRATION_ACCESS_TOKEN = "registration_access_token";
public String REQUEST_URIS = "request_uris";
public String POST_LOGOUT_REDIRECT_URIS = "post_logout_redirect_uris";
public String INITIATE_LOGIN_URI = "initiate_login_uri";
public String DEFAULT_ACR_VALUES = "default_acr_values";
public String REQUIRE_AUTH_TIME = "require_auth_time";
public String DEFAULT_MAX_AGE = "default_max_age";
public String TOKEN_ENDPOINT_AUTH_SIGNING_ALG = "token_endpoint_auth_signing_alg";
public String ID_TOKEN_ENCRYPTED_RESPONSE_ENC = "id_token_encrypted_response_enc";
public String ID_TOKEN_ENCRYPTED_RESPONSE_ALG = "id_token_encrypted_response_alg";
public String ID_TOKEN_SIGNED_RESPONSE_ALG = "id_token_signed_response_alg";
public String USERINFO_ENCRYPTED_RESPONSE_ENC = "userinfo_encrypted_response_enc";
public String USERINFO_ENCRYPTED_RESPONSE_ALG = "userinfo_encrypted_response_alg";
public String USERINFO_SIGNED_RESPONSE_ALG = "userinfo_signed_response_alg";
public String REQUEST_OBJECT_SIGNING_ALG = "request_object_signing_alg";
public String SUBJECT_TYPE = "subject_type";
public String SECTOR_IDENTIFIER_URI = "sector_identifier_uri";
public String APPLICATION_TYPE = "application_type";
public String JWKS_URI = "jwks_uri";
public String SCOPE_SEPARATOR = " ";
public String POLICY_URI = "policy_uri";
public String RESPONSE_TYPES = "response_types";
public String GRANT_TYPES = "grant_types";
public String SCOPE = "scope";
public String TOKEN_ENDPOINT_AUTH_METHOD = "token_endpoint_auth_method";
public String TOS_URI = "tos_uri";
public String CONTACTS = "contacts";
public String LOGO_URI = "logo_uri";
public String CLIENT_URI = "client_uri";
public String CLIENT_NAME = "client_name";
public String REDIRECT_URIS = "redirect_uris";
public String CLIENT_SECRET = "client_secret";
public String CLIENT_ID = "client_id";
}

View File

@ -16,8 +16,11 @@
*******************************************************************************/
package org.mitre.oauth2.service;
import java.text.SimpleDateFormat;
import java.util.Map;
import javax.swing.text.DateFormatter;
import org.mitre.oauth2.model.OAuth2AccessTokenEntity;
import org.mitre.oauth2.model.OAuth2RefreshTokenEntity;
import org.mitre.openid.connect.model.UserInfo;
@ -27,6 +30,17 @@ import org.mitre.openid.connect.model.UserInfo;
*/
public interface IntrospectionResultAssembler {
public String TOKEN_TYPE = "token_type";
public String CLIENT_ID = "client_id";
public String USER_ID = "user_id";
public String SUB = "sub";
public String EXP = "exp";
public String EXPIRES_AT = "expires_at";
public String SCOPE_SEPARATOR = " ";
public String SCOPE = "scope";
public String ACTIVE = "active";
public DateFormatter dateFormat = new DateFormatter(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"));
/**
* Assemble a token introspection result from the given access token and user info.
*

View File

@ -30,6 +30,7 @@ import org.mitre.oauth2.model.SystemScope;
public interface SystemScopeService {
public static final String OFFLINE_ACCESS = "offline_access";
public static final Object OPENID_SCOPE = "openid";
public static final String ID_TOKEN_SCOPE = "id-token";
public static final String REGISTRATION_TOKEN_SCOPE = "registration-token";
public static final String RESOURCE_TOKEN_SCOPE = "resource-token";

View File

@ -27,6 +27,42 @@ import static org.mitre.discovery.util.JsonUtils.getAsJweEncryptionMethod;
import static org.mitre.discovery.util.JsonUtils.getAsJwsAlgorithm;
import static org.mitre.discovery.util.JsonUtils.getAsString;
import static org.mitre.discovery.util.JsonUtils.getAsStringSet;
import static org.mitre.oauth2.model.RegisteredClientFields.APPLICATION_TYPE;
import static org.mitre.oauth2.model.RegisteredClientFields.CLIENT_ID;
import static org.mitre.oauth2.model.RegisteredClientFields.CLIENT_ID_ISSUED_AT;
import static org.mitre.oauth2.model.RegisteredClientFields.CLIENT_NAME;
import static org.mitre.oauth2.model.RegisteredClientFields.CLIENT_SECRET;
import static org.mitre.oauth2.model.RegisteredClientFields.CLIENT_SECRET_EXPIRES_AT;
import static org.mitre.oauth2.model.RegisteredClientFields.CLIENT_URI;
import static org.mitre.oauth2.model.RegisteredClientFields.CONTACTS;
import static org.mitre.oauth2.model.RegisteredClientFields.DEFAULT_ACR_VALUES;
import static org.mitre.oauth2.model.RegisteredClientFields.DEFAULT_MAX_AGE;
import static org.mitre.oauth2.model.RegisteredClientFields.GRANT_TYPES;
import static org.mitre.oauth2.model.RegisteredClientFields.ID_TOKEN_ENCRYPTED_RESPONSE_ALG;
import static org.mitre.oauth2.model.RegisteredClientFields.ID_TOKEN_ENCRYPTED_RESPONSE_ENC;
import static org.mitre.oauth2.model.RegisteredClientFields.ID_TOKEN_SIGNED_RESPONSE_ALG;
import static org.mitre.oauth2.model.RegisteredClientFields.INITIATE_LOGIN_URI;
import static org.mitre.oauth2.model.RegisteredClientFields.JWKS_URI;
import static org.mitre.oauth2.model.RegisteredClientFields.LOGO_URI;
import static org.mitre.oauth2.model.RegisteredClientFields.POLICY_URI;
import static org.mitre.oauth2.model.RegisteredClientFields.POST_LOGOUT_REDIRECT_URIS;
import static org.mitre.oauth2.model.RegisteredClientFields.REDIRECT_URIS;
import static org.mitre.oauth2.model.RegisteredClientFields.REGISTRATION_ACCESS_TOKEN;
import static org.mitre.oauth2.model.RegisteredClientFields.REGISTRATION_CLIENT_URI;
import static org.mitre.oauth2.model.RegisteredClientFields.REQUEST_OBJECT_SIGNING_ALG;
import static org.mitre.oauth2.model.RegisteredClientFields.REQUEST_URIS;
import static org.mitre.oauth2.model.RegisteredClientFields.REQUIRE_AUTH_TIME;
import static org.mitre.oauth2.model.RegisteredClientFields.RESPONSE_TYPES;
import static org.mitre.oauth2.model.RegisteredClientFields.SCOPE;
import static org.mitre.oauth2.model.RegisteredClientFields.SCOPE_SEPARATOR;
import static org.mitre.oauth2.model.RegisteredClientFields.SECTOR_IDENTIFIER_URI;
import static org.mitre.oauth2.model.RegisteredClientFields.SUBJECT_TYPE;
import static org.mitre.oauth2.model.RegisteredClientFields.TOKEN_ENDPOINT_AUTH_METHOD;
import static org.mitre.oauth2.model.RegisteredClientFields.TOKEN_ENDPOINT_AUTH_SIGNING_ALG;
import static org.mitre.oauth2.model.RegisteredClientFields.TOS_URI;
import static org.mitre.oauth2.model.RegisteredClientFields.USERINFO_ENCRYPTED_RESPONSE_ALG;
import static org.mitre.oauth2.model.RegisteredClientFields.USERINFO_ENCRYPTED_RESPONSE_ENC;
import static org.mitre.oauth2.model.RegisteredClientFields.USERINFO_SIGNED_RESPONSE_ALG;
import org.mitre.oauth2.model.ClientDetailsEntity;
import org.mitre.oauth2.model.ClientDetailsEntity.AppType;
@ -47,6 +83,7 @@ import com.google.gson.JsonParser;
*/
public class ClientDetailsEntityJsonProcessor {
private static JsonParser parser = new JsonParser();
/**
@ -70,75 +107,75 @@ public class ClientDetailsEntityJsonProcessor {
// TODO: make these field names into constants
// these two fields should only be sent in the update request, and MUST match existing values
c.setClientId(getAsString(o, "client_id"));
c.setClientSecret(getAsString(o, "client_secret"));
c.setClientId(getAsString(o, CLIENT_ID));
c.setClientSecret(getAsString(o, CLIENT_SECRET));
// OAuth DynReg
c.setRedirectUris(getAsStringSet(o, "redirect_uris"));
c.setClientName(getAsString(o, "client_name"));
c.setClientUri(getAsString(o, "client_uri"));
c.setLogoUri(getAsString(o, "logo_uri"));
c.setContacts(getAsStringSet(o, "contacts"));
c.setTosUri(getAsString(o, "tos_uri"));
c.setRedirectUris(getAsStringSet(o, REDIRECT_URIS));
c.setClientName(getAsString(o, CLIENT_NAME));
c.setClientUri(getAsString(o, CLIENT_URI));
c.setLogoUri(getAsString(o, LOGO_URI));
c.setContacts(getAsStringSet(o, CONTACTS));
c.setTosUri(getAsString(o, TOS_URI));
String authMethod = getAsString(o, "token_endpoint_auth_method");
String authMethod = getAsString(o, TOKEN_ENDPOINT_AUTH_METHOD);
if (authMethod != null) {
c.setTokenEndpointAuthMethod(AuthMethod.getByValue(authMethod));
}
// scope is a space-separated string
String scope = getAsString(o, "scope");
String scope = getAsString(o, SCOPE);
if (scope != null) {
c.setScope(Sets.newHashSet(Splitter.on(" ").split(scope)));
c.setScope(Sets.newHashSet(Splitter.on(SCOPE_SEPARATOR).split(scope)));
}
c.setGrantTypes(getAsStringSet(o, "grant_types"));
c.setResponseTypes(getAsStringSet(o, "response_types"));
c.setPolicyUri(getAsString(o, "policy_uri"));
c.setJwksUri(getAsString(o, "jwks_uri"));
c.setGrantTypes(getAsStringSet(o, GRANT_TYPES));
c.setResponseTypes(getAsStringSet(o, RESPONSE_TYPES));
c.setPolicyUri(getAsString(o, POLICY_URI));
c.setJwksUri(getAsString(o, JWKS_URI));
// OIDC Additions
String appType = getAsString(o, "application_type");
String appType = getAsString(o, APPLICATION_TYPE);
if (appType != null) {
c.setApplicationType(AppType.getByValue(appType));
}
c.setSectorIdentifierUri(getAsString(o, "sector_identifier_uri"));
c.setSectorIdentifierUri(getAsString(o, SECTOR_IDENTIFIER_URI));
String subjectType = getAsString(o, "subject_type");
String subjectType = getAsString(o, SUBJECT_TYPE);
if (subjectType != null) {
c.setSubjectType(SubjectType.getByValue(subjectType));
}
c.setRequestObjectSigningAlg(getAsJwsAlgorithm(o, "request_object_signing_alg"));
c.setRequestObjectSigningAlg(getAsJwsAlgorithm(o, REQUEST_OBJECT_SIGNING_ALG));
c.setUserInfoSignedResponseAlg(getAsJwsAlgorithm(o, "userinfo_signed_response_alg"));
c.setUserInfoEncryptedResponseAlg(getAsJweAlgorithm(o, "userinfo_encrypted_response_alg"));
c.setUserInfoEncryptedResponseEnc(getAsJweEncryptionMethod(o, "userinfo_encrypted_response_enc"));
c.setUserInfoSignedResponseAlg(getAsJwsAlgorithm(o, USERINFO_SIGNED_RESPONSE_ALG));
c.setUserInfoEncryptedResponseAlg(getAsJweAlgorithm(o, USERINFO_ENCRYPTED_RESPONSE_ALG));
c.setUserInfoEncryptedResponseEnc(getAsJweEncryptionMethod(o, USERINFO_ENCRYPTED_RESPONSE_ENC));
c.setIdTokenSignedResponseAlg(getAsJwsAlgorithm(o, "id_token_signed_response_alg"));
c.setIdTokenEncryptedResponseAlg(getAsJweAlgorithm(o, "id_token_encrypted_response_alg"));
c.setIdTokenEncryptedResponseEnc(getAsJweEncryptionMethod(o, "id_token_encrypted_response_enc"));
c.setIdTokenSignedResponseAlg(getAsJwsAlgorithm(o, ID_TOKEN_SIGNED_RESPONSE_ALG));
c.setIdTokenEncryptedResponseAlg(getAsJweAlgorithm(o, ID_TOKEN_ENCRYPTED_RESPONSE_ALG));
c.setIdTokenEncryptedResponseEnc(getAsJweEncryptionMethod(o, ID_TOKEN_ENCRYPTED_RESPONSE_ENC));
c.setTokenEndpointAuthSigningAlg(getAsJwsAlgorithm(o, "token_endpoint_auth_signing_alg"));
c.setTokenEndpointAuthSigningAlg(getAsJwsAlgorithm(o, TOKEN_ENDPOINT_AUTH_SIGNING_ALG));
if (o.has("default_max_age")) {
if (o.get("default_max_age").isJsonPrimitive()) {
c.setDefaultMaxAge(o.get("default_max_age").getAsInt());
if (o.has(DEFAULT_MAX_AGE)) {
if (o.get(DEFAULT_MAX_AGE).isJsonPrimitive()) {
c.setDefaultMaxAge(o.get(DEFAULT_MAX_AGE).getAsInt());
}
}
if (o.has("require_auth_time")) {
if (o.get("require_auth_time").isJsonPrimitive()) {
c.setRequireAuthTime(o.get("require_auth_time").getAsBoolean());
if (o.has(REQUIRE_AUTH_TIME)) {
if (o.get(REQUIRE_AUTH_TIME).isJsonPrimitive()) {
c.setRequireAuthTime(o.get(REQUIRE_AUTH_TIME).getAsBoolean());
}
}
c.setDefaultACRvalues(getAsStringSet(o, "default_acr_values"));
c.setInitiateLoginUri(getAsString(o, "initiate_login_uri"));
c.setPostLogoutRedirectUris(getAsStringSet(o, "post_logout_redirect_uris"));
c.setRequestUris(getAsStringSet(o, "request_uris"));
c.setDefaultACRvalues(getAsStringSet(o, DEFAULT_ACR_VALUES));
c.setInitiateLoginUri(getAsString(o, INITIATE_LOGIN_URI));
c.setPostLogoutRedirectUris(getAsStringSet(o, POST_LOGOUT_REDIRECT_URIS));
c.setRequestUris(getAsStringSet(o, REQUEST_URIS));
return c;
} else {
@ -164,10 +201,10 @@ public class ClientDetailsEntityJsonProcessor {
RegisteredClient rc = new RegisteredClient(c);
// get any fields from the registration
rc.setRegistrationAccessToken(getAsString(o, "registration_access_token"));
rc.setRegistrationClientUri(getAsString(o, "registration_client_uri"));
rc.setClientIdIssuedAt(getAsDate(o, "client_id_issued_at"));
rc.setClientSecretExpiresAt(getAsDate(o, "client_secret_expires_at"));
rc.setRegistrationAccessToken(getAsString(o, REGISTRATION_ACCESS_TOKEN));
rc.setRegistrationClientUri(getAsString(o, REGISTRATION_CLIENT_URI));
rc.setClientIdIssuedAt(getAsDate(o, CLIENT_ID_ISSUED_AT));
rc.setClientSecretExpiresAt(getAsDate(o, CLIENT_SECRET_EXPIRES_AT));
return rc;
} else {
@ -184,65 +221,65 @@ public class ClientDetailsEntityJsonProcessor {
public static JsonObject serialize(RegisteredClient c) {
JsonObject o = new JsonObject();
o.addProperty("client_id", c.getClientId());
o.addProperty(CLIENT_ID, c.getClientId());
if (c.getClientSecret() != null) {
o.addProperty("client_secret", c.getClientSecret());
o.addProperty(CLIENT_SECRET, c.getClientSecret());
if (c.getClientSecretExpiresAt() == null) {
o.addProperty("client_secret_expires_at", 0); // TODO: do we want to let secrets expire?
o.addProperty(CLIENT_SECRET_EXPIRES_AT, 0); // TODO: do we want to let secrets expire?
} else {
o.addProperty("client_secret_expires_at", c.getClientSecretExpiresAt().getTime() / 1000L);
o.addProperty(CLIENT_SECRET_EXPIRES_AT, c.getClientSecretExpiresAt().getTime() / 1000L);
}
}
if (c.getClientIdIssuedAt() != null) {
o.addProperty("client_id_issued_at", c.getClientIdIssuedAt().getTime() / 1000L);
o.addProperty(CLIENT_ID_ISSUED_AT, c.getClientIdIssuedAt().getTime() / 1000L);
} else if (c.getCreatedAt() != null) {
o.addProperty("client_id_issued_at", c.getCreatedAt().getTime() / 1000L);
o.addProperty(CLIENT_ID_ISSUED_AT, c.getCreatedAt().getTime() / 1000L);
}
if (c.getRegistrationAccessToken() != null) {
o.addProperty("registration_access_token", c.getRegistrationAccessToken());
o.addProperty(REGISTRATION_ACCESS_TOKEN, c.getRegistrationAccessToken());
}
if (c.getRegistrationClientUri() != null) {
o.addProperty("registration_client_uri", c.getRegistrationClientUri());
o.addProperty(REGISTRATION_CLIENT_URI, c.getRegistrationClientUri());
}
// add in all other client properties
// OAuth DynReg
o.add("redirect_uris", getAsArray(c.getRedirectUris()));
o.addProperty("client_name", c.getClientName());
o.addProperty("client_uri", c.getClientUri());
o.addProperty("logo_uri", c.getLogoUri());
o.add("contacts", getAsArray(c.getContacts()));
o.addProperty("tos_uri", c.getTosUri());
o.addProperty("token_endpoint_auth_method", c.getTokenEndpointAuthMethod() != null ? c.getTokenEndpointAuthMethod().getValue() : null);
o.addProperty("scope", c.getScope() != null ? Joiner.on(" ").join(c.getScope()) : null);
o.add("grant_types", getAsArray(c.getGrantTypes()));
o.add("response_types", getAsArray(c.getResponseTypes()));
o.addProperty("policy_uri", c.getPolicyUri());
o.addProperty("jwks_uri", c.getJwksUri());
o.add(REDIRECT_URIS, getAsArray(c.getRedirectUris()));
o.addProperty(CLIENT_NAME, c.getClientName());
o.addProperty(CLIENT_URI, c.getClientUri());
o.addProperty(LOGO_URI, c.getLogoUri());
o.add(CONTACTS, getAsArray(c.getContacts()));
o.addProperty(TOS_URI, c.getTosUri());
o.addProperty(TOKEN_ENDPOINT_AUTH_METHOD, c.getTokenEndpointAuthMethod() != null ? c.getTokenEndpointAuthMethod().getValue() : null);
o.addProperty(SCOPE, c.getScope() != null ? Joiner.on(SCOPE_SEPARATOR).join(c.getScope()) : null);
o.add(GRANT_TYPES, getAsArray(c.getGrantTypes()));
o.add(RESPONSE_TYPES, getAsArray(c.getResponseTypes()));
o.addProperty(POLICY_URI, c.getPolicyUri());
o.addProperty(JWKS_URI, c.getJwksUri());
// OIDC Registration
o.addProperty("application_type", c.getApplicationType() != null ? c.getApplicationType().getValue() : null);
o.addProperty("sector_identifier_uri", c.getSectorIdentifierUri());
o.addProperty("subject_type", c.getSubjectType() != null ? c.getSubjectType().getValue() : null);
o.addProperty("request_object_signing_alg", c.getRequestObjectSigningAlg() != null ? c.getRequestObjectSigningAlg().getName() : null);
o.addProperty("userinfo_signed_response_alg", c.getUserInfoSignedResponseAlg() != null ? c.getUserInfoSignedResponseAlg().getName() : null);
o.addProperty("userinfo_encrypted_response_alg", c.getUserInfoEncryptedResponseAlg() != null ? c.getUserInfoEncryptedResponseAlg().getName() : null);
o.addProperty("userinfo_encrypted_response_enc", c.getUserInfoEncryptedResponseEnc() != null ? c.getUserInfoEncryptedResponseEnc().getName() : null);
o.addProperty("id_token_signed_response_alg", c.getIdTokenSignedResponseAlg() != null ? c.getIdTokenSignedResponseAlg().getName() : null);
o.addProperty("id_token_encrypted_response_alg", c.getIdTokenEncryptedResponseAlg() != null ? c.getIdTokenEncryptedResponseAlg().getName() : null);
o.addProperty("id_token_encrypted_response_enc", c.getIdTokenEncryptedResponseEnc() != null ? c.getIdTokenEncryptedResponseEnc().getName() : null);
o.addProperty("token_endpoint_auth_signing_alg", c.getTokenEndpointAuthSigningAlg() != null ? c.getTokenEndpointAuthSigningAlg().getName() : null);
o.addProperty("default_max_age", c.getDefaultMaxAge());
o.addProperty("require_auth_time", c.getRequireAuthTime());
o.add("default_acr_values", getAsArray(c.getDefaultACRvalues()));
o.addProperty("initiate_login_uri", c.getInitiateLoginUri());
o.add("post_logout_redirect_uris", getAsArray(c.getPostLogoutRedirectUris()));
o.add("request_uris", getAsArray(c.getRequestUris()));
o.addProperty(APPLICATION_TYPE, c.getApplicationType() != null ? c.getApplicationType().getValue() : null);
o.addProperty(SECTOR_IDENTIFIER_URI, c.getSectorIdentifierUri());
o.addProperty(SUBJECT_TYPE, c.getSubjectType() != null ? c.getSubjectType().getValue() : null);
o.addProperty(REQUEST_OBJECT_SIGNING_ALG, c.getRequestObjectSigningAlg() != null ? c.getRequestObjectSigningAlg().getName() : null);
o.addProperty(USERINFO_SIGNED_RESPONSE_ALG, c.getUserInfoSignedResponseAlg() != null ? c.getUserInfoSignedResponseAlg().getName() : null);
o.addProperty(USERINFO_ENCRYPTED_RESPONSE_ALG, c.getUserInfoEncryptedResponseAlg() != null ? c.getUserInfoEncryptedResponseAlg().getName() : null);
o.addProperty(USERINFO_ENCRYPTED_RESPONSE_ENC, c.getUserInfoEncryptedResponseEnc() != null ? c.getUserInfoEncryptedResponseEnc().getName() : null);
o.addProperty(ID_TOKEN_SIGNED_RESPONSE_ALG, c.getIdTokenSignedResponseAlg() != null ? c.getIdTokenSignedResponseAlg().getName() : null);
o.addProperty(ID_TOKEN_ENCRYPTED_RESPONSE_ALG, c.getIdTokenEncryptedResponseAlg() != null ? c.getIdTokenEncryptedResponseAlg().getName() : null);
o.addProperty(ID_TOKEN_ENCRYPTED_RESPONSE_ENC, c.getIdTokenEncryptedResponseEnc() != null ? c.getIdTokenEncryptedResponseEnc().getName() : null);
o.addProperty(TOKEN_ENDPOINT_AUTH_SIGNING_ALG, c.getTokenEndpointAuthSigningAlg() != null ? c.getTokenEndpointAuthSigningAlg().getName() : null);
o.addProperty(DEFAULT_MAX_AGE, c.getDefaultMaxAge());
o.addProperty(REQUIRE_AUTH_TIME, c.getRequireAuthTime());
o.add(DEFAULT_ACR_VALUES, getAsArray(c.getDefaultACRvalues()));
o.addProperty(INITIATE_LOGIN_URI, c.getInitiateLoginUri());
o.add(POST_LOGOUT_REDIRECT_URIS, getAsArray(c.getPostLogoutRedirectUris()));
o.add(REQUEST_URIS, getAsArray(c.getRequestUris()));
return o;
}

View File

@ -19,10 +19,8 @@ package org.mitre.oauth2.service.impl;
import static com.google.common.collect.Maps.newLinkedHashMap;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Map;
import javax.swing.text.DateFormatter;
import org.mitre.oauth2.model.OAuth2AccessTokenEntity;
import org.mitre.oauth2.model.OAuth2RefreshTokenEntity;
@ -43,22 +41,20 @@ public class DefaultIntrospectionResultAssembler implements IntrospectionResultA
private static Logger log = LoggerFactory.getLogger(DefaultIntrospectionResultAssembler.class);
private static DateFormatter dateFormat = new DateFormatter(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"));
@Override
public Map<String, Object> assembleFrom(OAuth2AccessTokenEntity accessToken, UserInfo userInfo) {
Map<String, Object> result = newLinkedHashMap();
OAuth2Authentication authentication = accessToken.getAuthenticationHolder().getAuthentication();
result.put("active", true);
result.put(ACTIVE, true);
result.put("scope", Joiner.on(" ").join(accessToken.getScope()));
result.put(SCOPE, Joiner.on(SCOPE_SEPARATOR).join(accessToken.getScope()));
if (accessToken.getExpiration() != null) {
try {
result.put("expires_at", dateFormat.valueToString(accessToken.getExpiration()));
result.put("exp", accessToken.getExpiration().getTime() / 1000L);
result.put(EXPIRES_AT, dateFormat.valueToString(accessToken.getExpiration()));
result.put(EXP, accessToken.getExpiration().getTime() / 1000L);
} catch (ParseException e) {
log.error("Parse exception in token introspection", e);
}
@ -66,17 +62,17 @@ public class DefaultIntrospectionResultAssembler implements IntrospectionResultA
if (userInfo != null) {
// if we have a UserInfo, use that for the subject
result.put("sub", userInfo.getSub());
result.put(SUB, userInfo.getSub());
} else {
// otherwise, use the authentication's username
result.put("sub", authentication.getName());
result.put(SUB, authentication.getName());
}
result.put("user_id", authentication.getName());
result.put(USER_ID, authentication.getName());
result.put("client_id", authentication.getOAuth2Request().getClientId());
result.put(CLIENT_ID, authentication.getOAuth2Request().getClientId());
result.put("token_type", accessToken.getTokenType());
result.put(TOKEN_TYPE, accessToken.getTokenType());
return result;
}
@ -87,14 +83,14 @@ public class DefaultIntrospectionResultAssembler implements IntrospectionResultA
Map<String, Object> result = newLinkedHashMap();
OAuth2Authentication authentication = refreshToken.getAuthenticationHolder().getAuthentication();
result.put("active", true);
result.put(ACTIVE, true);
result.put("scope", Joiner.on(" ").join(authentication.getOAuth2Request().getScope()));
result.put(SCOPE, Joiner.on(SCOPE_SEPARATOR).join(authentication.getOAuth2Request().getScope()));
if (refreshToken.getExpiration() != null) {
try {
result.put("expires_at", dateFormat.valueToString(refreshToken.getExpiration()));
result.put("exp", refreshToken.getExpiration().getTime() / 1000L);
result.put(EXPIRES_AT, dateFormat.valueToString(refreshToken.getExpiration()));
result.put(EXP, refreshToken.getExpiration().getTime() / 1000L);
} catch (ParseException e) {
log.error("Parse exception in token introspection", e);
}
@ -103,15 +99,15 @@ public class DefaultIntrospectionResultAssembler implements IntrospectionResultA
if (userInfo != null) {
// if we have a UserInfo, use that for the subject
result.put("sub", userInfo.getSub());
result.put(SUB, userInfo.getSub());
} else {
// otherwise, use the authentication's username
result.put("sub", authentication.getName());
result.put(SUB, authentication.getName());
}
result.put("user_id", authentication.getName());
result.put(USER_ID, authentication.getName());
result.put("client_id", authentication.getOAuth2Request().getClientId());
result.put(CLIENT_ID, authentication.getOAuth2Request().getClientId());
return result;
}

View File

@ -19,6 +19,8 @@
*/
package org.mitre.oauth2.web;
import static org.mitre.openid.connect.request.ConnectRequestParameters.*;
import java.security.Principal;
import java.util.Date;
import java.util.HashMap;
@ -62,6 +64,7 @@ import com.google.gson.JsonObject;
@SessionAttributes("authorizationRequest")
public class OAuthConfirmationController {
@Autowired
private ClientDetailsEntityService clientService;
@ -94,17 +97,17 @@ public class OAuthConfirmationController {
// Check the "prompt" parameter to see if we need to do special processing
String prompt = (String)authRequest.getExtensions().get("prompt");
List<String> prompts = Splitter.on(" ").splitToList(Strings.nullToEmpty(prompt));
if (prompts.contains("none")) {
String prompt = (String)authRequest.getExtensions().get(PROMPT);
List<String> prompts = Splitter.on(PROMPT_SEPARATOR).splitToList(Strings.nullToEmpty(prompt));
if (prompts.contains(PROMPT_NONE)) {
// we're not supposed to prompt, so "return an error"
logger.info("Client requested no prompt, returning 403 from confirmation endpoint");
model.put("code", HttpStatus.FORBIDDEN);
return HttpCodeView.VIEWNAME;
}
if (prompts.contains("consent")) {
model.put("consent", true);
if (prompts.contains(PROMPT_CONSENT)) {
model.put(PROMPT_CONSENT, true);
}
//AuthorizationRequest clientAuth = (AuthorizationRequest) model.remove("authorizationRequest");
@ -190,7 +193,7 @@ public class OAuthConfirmationController {
}
// if the client is over a week old and has more than one registration, don't give such a big warning
// instead, tag as "Generally Recognized As Safe (gras)
// instead, tag as "Generally Recognized As Safe" (gras)
Date lastWeek = new Date(System.currentTimeMillis() - (60 * 60 * 24 * 7 * 1000));
if (count > 1 && client.getCreatedAt() != null && client.getCreatedAt().before(lastWeek)) {
model.put("gras", true);
@ -199,7 +202,7 @@ public class OAuthConfirmationController {
}
// inject a random value for CSRF purposes
model.put("csrf", authRequest.getExtensions().get("csrf"));
model.put("csrf", authRequest.getExtensions().get(CSRF));
return "approve";
}

View File

@ -19,6 +19,8 @@
*/
package org.mitre.openid.connect.filter;
import static org.mitre.openid.connect.request.ConnectRequestParameters.*;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
@ -57,6 +59,7 @@ import com.google.common.base.Strings;
@Component("authRequestFilter")
public class AuthorizationRequestFilter extends GenericFilterBean {
private Logger logger = LoggerFactory.getLogger(AuthorizationRequestFilter.class);
public final static String PROMPTED = "PROMPT_FILTER_PROMPTED";
@ -99,19 +102,19 @@ public class AuthorizationRequestFilter extends GenericFilterBean {
// save the login hint to the session
if (authRequest.getExtensions().get("login_hint") != null) {
session.setAttribute("login_hint", authRequest.getExtensions().get("login_hint"));
if (authRequest.getExtensions().get(LOGIN_HINT) != null) {
session.setAttribute(LOGIN_HINT, authRequest.getExtensions().get(LOGIN_HINT));
} else {
session.removeAttribute("login_hint");
session.removeAttribute(LOGIN_HINT);
}
if (authRequest.getExtensions().get("prompt") != null) {
if (authRequest.getExtensions().get(PROMPT) != null) {
// we have a "prompt" parameter
String prompt = (String)authRequest.getExtensions().get("prompt");
String prompt = (String)authRequest.getExtensions().get(PROMPT);
List<String> prompts = Splitter.on(" ").splitToList(Strings.nullToEmpty(prompt));
if (prompts.contains("none")) {
if (prompts.contains(PROMPT_NONE)) {
logger.info("Client requested no prompt");
// see if the user's logged in
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
@ -126,7 +129,7 @@ public class AuthorizationRequestFilter extends GenericFilterBean {
response.sendError(HttpServletResponse.SC_FORBIDDEN, "Access Denied");
return;
}
} else if (prompts.contains("login")) {
} else if (prompts.contains(PROMPT_LOGIN)) {
// first see if the user's already been prompted in this session
if (session.getAttribute(PROMPTED) == null) {
@ -157,12 +160,12 @@ public class AuthorizationRequestFilter extends GenericFilterBean {
chain.doFilter(req, res);
}
} else if (authRequest.getExtensions().get("max_age") != null ||
} else if (authRequest.getExtensions().get(MAX_AGE) != null ||
(client != null && client.getDefaultMaxAge() != null)) {
// default to the client's stored value, check the string parameter
Integer max = (client != null ? client.getDefaultMaxAge() : null);
String maxAge = (String) authRequest.getExtensions().get("max_age");
String maxAge = (String) authRequest.getExtensions().get(MAX_AGE);
if (maxAge != null) {
max = Integer.parseInt(maxAge);
}

View File

@ -14,7 +14,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*******************************************************************************/
package org.mitre.openid.connect;
package org.mitre.openid.connect.request;
import static org.mitre.openid.connect.request.ConnectRequestParameters.*;
import java.text.ParseException;
import java.util.Collections;
@ -99,31 +101,31 @@ public class ConnectOAuth2RequestFactory extends DefaultOAuth2RequestFactory {
//Add extension parameters to the 'extensions' map
if (inputParams.containsKey("prompt")) {
request.getExtensions().put("prompt", inputParams.get("prompt"));
if (inputParams.containsKey(PROMPT)) {
request.getExtensions().put(PROMPT, inputParams.get(PROMPT));
}
if (inputParams.containsKey("nonce")) {
request.getExtensions().put("nonce", inputParams.get("nonce"));
if (inputParams.containsKey(NONCE)) {
request.getExtensions().put(NONCE, inputParams.get(NONCE));
}
if (inputParams.containsKey("claims")) {
JsonObject claimsRequest = parseClaimRequest(inputParams.get("claims"));
if (inputParams.containsKey(CLAIMS)) {
JsonObject claimsRequest = parseClaimRequest(inputParams.get(CLAIMS));
if (claimsRequest != null) {
request.getExtensions().put("claims", claimsRequest.toString());
request.getExtensions().put(CLAIMS, claimsRequest.toString());
}
}
if (inputParams.containsKey("max_age")) {
request.getExtensions().put("max_age", inputParams.get("max_age"));
if (inputParams.containsKey(MAX_AGE)) {
request.getExtensions().put(MAX_AGE, inputParams.get(MAX_AGE));
}
if (inputParams.containsKey("login_hint")) {
request.getExtensions().put("login_hint", inputParams.get("login_hint"));
if (inputParams.containsKey(LOGIN_HINT)) {
request.getExtensions().put(LOGIN_HINT, inputParams.get(LOGIN_HINT));
}
if (inputParams.containsKey("request")) {
request.getExtensions().put("request", inputParams.get("request"));
processRequestObject(inputParams.get("request"), request);
if (inputParams.containsKey(REQUEST)) {
request.getExtensions().put(REQUEST, inputParams.get(REQUEST));
processRequestObject(inputParams.get(REQUEST), request);
}
if (request.getClientId() != null) {
@ -135,8 +137,8 @@ public class ConnectOAuth2RequestFactory extends DefaultOAuth2RequestFactory {
request.setScope(clientScopes);
}
if (request.getExtensions().get("max_age") == null && client.getDefaultMaxAge() != null) {
request.getExtensions().put("max_age", client.getDefaultMaxAge().toString());
if (request.getExtensions().get(MAX_AGE) == null && client.getDefaultMaxAge() != null) {
request.getExtensions().put(MAX_AGE, client.getDefaultMaxAge().toString());
}
} catch (OAuth2Exception e) {
logger.error("Caught OAuth2 exception trying to test client scopes and max age:", e);
@ -146,7 +148,7 @@ public class ConnectOAuth2RequestFactory extends DefaultOAuth2RequestFactory {
// add CSRF protection to the request on first parse
String csrf = UUID.randomUUID().toString();
request.getExtensions().put("csrf", csrf);
request.getExtensions().put(CSRF, csrf);
@ -172,7 +174,7 @@ public class ConnectOAuth2RequestFactory extends DefaultOAuth2RequestFactory {
// need to check clientId first so that we can load the client to check other fields
if (request.getClientId() == null) {
request.setClientId(signedJwt.getJWTClaimsSet().getStringClaim("client_id"));
request.setClientId(signedJwt.getJWTClaimsSet().getStringClaim(CLIENT_ID));
}
ClientDetailsEntity client = clientDetailsService.loadClientByClientId(request.getClientId());
@ -234,7 +236,7 @@ public class ConnectOAuth2RequestFactory extends DefaultOAuth2RequestFactory {
// need to check clientId first so that we can load the client to check other fields
if (request.getClientId() == null) {
request.setClientId(plainJwt.getJWTClaimsSet().getStringClaim("client_id"));
request.setClientId(plainJwt.getJWTClaimsSet().getStringClaim(CLIENT_ID));
}
ClientDetailsEntity client = clientDetailsService.loadClientByClientId(request.getClientId());
@ -267,7 +269,7 @@ public class ConnectOAuth2RequestFactory extends DefaultOAuth2RequestFactory {
// need to check clientId first so that we can load the client to check other fields
if (request.getClientId() == null) {
request.setClientId(encryptedJWT.getJWTClaimsSet().getStringClaim("client_id"));
request.setClientId(encryptedJWT.getJWTClaimsSet().getStringClaim(CLIENT_ID));
}
ClientDetailsEntity client = clientDetailsService.loadClientByClientId(request.getClientId());
@ -288,7 +290,7 @@ public class ConnectOAuth2RequestFactory extends DefaultOAuth2RequestFactory {
ReadOnlyJWTClaimsSet claims = jwt.getJWTClaimsSet();
Set<String> responseTypes = OAuth2Utils.parseParameterList(claims.getStringClaim("response_type"));
Set<String> responseTypes = OAuth2Utils.parseParameterList(claims.getStringClaim(RESPONSE_TYPE));
if (responseTypes != null && !responseTypes.isEmpty()) {
if (!responseTypes.equals(request.getResponseTypes())) {
logger.info("Mismatch between request object and regular parameter for response_type, using request object");
@ -296,7 +298,7 @@ public class ConnectOAuth2RequestFactory extends DefaultOAuth2RequestFactory {
request.setResponseTypes(responseTypes);
}
String redirectUri = claims.getStringClaim("redirect_uri");
String redirectUri = claims.getStringClaim(REDIRECT_URI);
if (redirectUri != null) {
if (!redirectUri.equals(request.getRedirectUri())) {
logger.info("Mismatch between request object and regular parameter for redirect_uri, using request object");
@ -304,7 +306,7 @@ public class ConnectOAuth2RequestFactory extends DefaultOAuth2RequestFactory {
request.setRedirectUri(redirectUri);
}
String state = claims.getStringClaim("state");
String state = claims.getStringClaim(STATE);
if(state != null) {
if (!state.equals(request.getState())) {
logger.info("Mismatch between request object and regular parameter for state, using request object");
@ -312,28 +314,28 @@ public class ConnectOAuth2RequestFactory extends DefaultOAuth2RequestFactory {
request.setState(state);
}
String nonce = claims.getStringClaim("nonce");
String nonce = claims.getStringClaim(NONCE);
if(nonce != null) {
if (!nonce.equals(request.getExtensions().get("nonce"))) {
if (!nonce.equals(request.getExtensions().get(NONCE))) {
logger.info("Mismatch between request object and regular parameter for nonce, using request object");
}
request.getExtensions().put("nonce", nonce);
request.getExtensions().put(NONCE, nonce);
}
String display = claims.getStringClaim("display");
String display = claims.getStringClaim(DISPLAY);
if (display != null) {
if (!display.equals(request.getExtensions().get("display"))) {
if (!display.equals(request.getExtensions().get(DISPLAY))) {
logger.info("Mismatch between request object and regular parameter for display, using request object");
}
request.getExtensions().put("display", display);
request.getExtensions().put(DISPLAY, display);
}
String prompt = claims.getStringClaim("prompt");
String prompt = claims.getStringClaim(PROMPT);
if (prompt != null) {
if (!prompt.equals(request.getExtensions().get("prompt"))) {
if (!prompt.equals(request.getExtensions().get(PROMPT))) {
logger.info("Mismatch between request object and regular parameter for prompt, using request object");
}
request.getExtensions().put("prompt", prompt);
request.getExtensions().put(PROMPT, prompt);
}
Set<String> scope = OAuth2Utils.parseParameterList(claims.getStringClaim("scope"));
@ -344,21 +346,21 @@ public class ConnectOAuth2RequestFactory extends DefaultOAuth2RequestFactory {
request.setScope(scope);
}
JsonObject claimRequest = parseClaimRequest(claims.getStringClaim("claims"));
JsonObject claimRequest = parseClaimRequest(claims.getStringClaim(CLAIMS));
if (claimRequest != null) {
if (!claimRequest.equals(parseClaimRequest(request.getExtensions().get("claims").toString()))) {
if (!claimRequest.equals(parseClaimRequest(request.getExtensions().get(CLAIMS).toString()))) {
logger.info("Mismatch between request object and regular parameter for claims, using request object");
}
// we save the string because the object might not be a Java Serializable, and we can parse it easily enough anyway
request.getExtensions().put("claims", claimRequest.toString());
request.getExtensions().put(CLAIMS, claimRequest.toString());
}
String loginHint = claims.getStringClaim("login_hint");
String loginHint = claims.getStringClaim(LOGIN_HINT);
if (loginHint != null) {
if (!loginHint.equals(request.getExtensions().get("login_hint"))) {
if (!loginHint.equals(request.getExtensions().get(LOGIN_HINT))) {
logger.info("Mistmatch between request object and regular parameter for login_hint, using requst object");
}
request.getExtensions().put("login_hint", loginHint);
request.getExtensions().put(LOGIN_HINT, loginHint);
}
} catch (ParseException e) {

View File

@ -0,0 +1,29 @@
package org.mitre.openid.connect.request;
public interface ConnectRequestParameters {
public String CLIENT_ID = "client_id";
public String RESPONSE_TYPE = "response_type";
public String REDIRECT_URI = "redirect_uri";
public String STATE = "state";
public String DISPLAY = "display";
public String REQUEST = "request";
public String LOGIN_HINT = "login_hint";
public String MAX_AGE = "max_age";
public String CLAIMS = "claims";
public String NONCE = "nonce";
public String PROMPT = "prompt";
// prompt values
public String PROMPT_LOGIN = "login";
public String PROMPT_NONE = "none";
public String PROMPT_CONSENT = "consent";
public String PROMPT_SEPARATOR = " ";
// extensions
public String CSRF = "csrf";
public String APPROVED_SITE = "approved_site";
}

View File

@ -25,6 +25,7 @@ import org.mitre.jwt.signer.service.impl.SymmetricKeyJWTValidatorCacheService;
import org.mitre.oauth2.model.ClientDetailsEntity;
import org.mitre.oauth2.model.OAuth2AccessTokenEntity;
import org.mitre.oauth2.service.ClientDetailsEntityService;
import org.mitre.oauth2.service.SystemScopeService;
import org.mitre.openid.connect.config.ConfigurationPropertiesBean;
import org.mitre.openid.connect.model.UserInfo;
import org.mitre.openid.connect.service.ApprovedSiteService;
@ -113,7 +114,7 @@ public class ConnectTokenEnhancer implements TokenEnhancer {
* Also, there must be a user authentication involved in the request for it to be considered
* OIDC and not OAuth, so we check for that as well.
*/
if (originalAuthRequest.getScope().contains("openid")
if (originalAuthRequest.getScope().contains(SystemScopeService.OPENID_SCOPE)
&& !authentication.isClientOnly()) {
String username = authentication.getName();

View File

@ -16,6 +16,8 @@
*******************************************************************************/
package org.mitre.openid.connect.token;
import static org.mitre.openid.connect.request.ConnectRequestParameters.*;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
@ -101,8 +103,8 @@ public class TofuUserApprovalHandler implements UserApprovalHandler {
// check the value of the CSRF parameter
if (authorizationRequest.getExtensions().get("csrf") != null) {
if (authorizationRequest.getExtensions().get("csrf").equals(authorizationRequest.getApprovalParameters().get("csrf"))) {
if (authorizationRequest.getExtensions().get(CSRF) != null) {
if (authorizationRequest.getExtensions().get(CSRF).equals(authorizationRequest.getApprovalParameters().get(CSRF))) {
// make sure the user is actually authenticated
return userAuthentication.isAuthenticated();
@ -139,9 +141,9 @@ public class TofuUserApprovalHandler implements UserApprovalHandler {
boolean alreadyApproved = false;
// find out if we're supposed to force a prompt on the user or not
String prompt = (String) authorizationRequest.getExtensions().get("prompt");
List<String> prompts = Splitter.on(" ").splitToList(Strings.nullToEmpty(prompt));
if (!prompts.contains("consent")) {
String prompt = (String) authorizationRequest.getExtensions().get(PROMPT);
List<String> prompts = Splitter.on(PROMPT_SEPARATOR).splitToList(Strings.nullToEmpty(prompt));
if (!prompts.contains(PROMPT_SEPARATOR)) {
// if the prompt parameter is set to "consent" then we can't use approved sites or whitelisted sites
// otherwise, we need to check them below
@ -157,7 +159,7 @@ public class TofuUserApprovalHandler implements UserApprovalHandler {
ap.setAccessDate(new Date());
approvedSiteService.save(ap);
authorizationRequest.getExtensions().put("approved_site", ap.getId());
authorizationRequest.getExtensions().put(APPROVED_SITE, ap.getId());
authorizationRequest.setApproved(true);
alreadyApproved = true;
@ -172,7 +174,7 @@ public class TofuUserApprovalHandler implements UserApprovalHandler {
//Create an approved site
ApprovedSite newSite = approvedSiteService.createApprovedSite(clientId, userId, null, ws.getAllowedScopes(), ws);
authorizationRequest.getExtensions().put("approved_site", newSite.getId());
authorizationRequest.getExtensions().put(APPROVED_SITE, newSite.getId());
authorizationRequest.setApproved(true);
setAuthTime(authorizationRequest);
@ -194,8 +196,8 @@ public class TofuUserApprovalHandler implements UserApprovalHandler {
// This must be re-parsed here because SECOAUTH forces us to call things in a strange order
if (Boolean.parseBoolean(authorizationRequest.getApprovalParameters().get("user_oauth_approval"))
&& authorizationRequest.getExtensions().get("csrf") != null
&& authorizationRequest.getExtensions().get("csrf").equals(authorizationRequest.getApprovalParameters().get("csrf"))) {
&& authorizationRequest.getExtensions().get(CSRF) != null
&& authorizationRequest.getExtensions().get(CSRF).equals(authorizationRequest.getApprovalParameters().get(CSRF))) {
authorizationRequest.setApproved(true);
@ -247,7 +249,7 @@ public class TofuUserApprovalHandler implements UserApprovalHandler {
}
ApprovedSite newSite = approvedSiteService.createApprovedSite(clientId, userId, timeout, allowedScopes, null);
authorizationRequest.getExtensions().put("approved_site", newSite.getId());
authorizationRequest.getExtensions().put(APPROVED_SITE, newSite.getId());
}
setAuthTime(authorizationRequest);

View File

@ -35,6 +35,7 @@ import javax.swing.text.DateFormatter;
import org.junit.Test;
import org.mitre.oauth2.model.OAuth2AccessTokenEntity;
import org.mitre.oauth2.model.OAuth2RefreshTokenEntity;
import org.mitre.oauth2.service.IntrospectionResultAssembler;
import org.mitre.openid.connect.model.UserInfo;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.OAuth2Request;
@ -43,7 +44,7 @@ import com.google.common.collect.ImmutableMap;
public class TestDefaultIntrospectionResultAssembler {
private DefaultIntrospectionResultAssembler assembler = new DefaultIntrospectionResultAssembler();
private IntrospectionResultAssembler assembler = new DefaultIntrospectionResultAssembler();
private static DateFormatter dateFormat = new DateFormatter(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"));