formatting cleanup
parent
e2349984b8
commit
685960358c
|
@ -32,21 +32,21 @@ import com.google.gson.JsonObject;
|
||||||
|
|
||||||
public class OAuth2AccessTokenImpl implements OAuth2AccessToken {
|
public class OAuth2AccessTokenImpl implements OAuth2AccessToken {
|
||||||
|
|
||||||
private JsonObject token;
|
private JsonObject introspectionResponse;
|
||||||
private String tokenString;
|
private String tokenString;
|
||||||
private Set<String> scopes = new HashSet<String>();
|
private Set<String> scopes = new HashSet<String>();
|
||||||
private Date expireDate;
|
private Date expireDate;
|
||||||
|
|
||||||
|
|
||||||
public OAuth2AccessTokenImpl(JsonObject token, String tokenString) {
|
public OAuth2AccessTokenImpl(JsonObject introspectionResponse, String tokenString) {
|
||||||
this.token = token;
|
this.setIntrospectionResponse(introspectionResponse);
|
||||||
this.tokenString = tokenString;
|
this.tokenString = tokenString;
|
||||||
if (token.get("scope") != null) {
|
if (introspectionResponse.get("scope") != null) {
|
||||||
scopes = Sets.newHashSet(Splitter.on(" ").split(token.get("scope").getAsString()));
|
scopes = Sets.newHashSet(Splitter.on(" ").split(introspectionResponse.get("scope").getAsString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (token.get("exp") != null) {
|
if (introspectionResponse.get("exp") != null) {
|
||||||
expireDate = new Date(token.get("exp").getAsLong() * 1000L);
|
expireDate = new Date(introspectionResponse.get("exp").getAsLong() * 1000L);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,4 +97,20 @@ public class OAuth2AccessTokenImpl implements OAuth2AccessToken {
|
||||||
return tokenString;
|
return tokenString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the token
|
||||||
|
*/
|
||||||
|
public JsonObject getIntrospectionResponse() {
|
||||||
|
return introspectionResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param token the token to set
|
||||||
|
*/
|
||||||
|
public void setIntrospectionResponse(JsonObject token) {
|
||||||
|
this.introspectionResponse = token;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -311,16 +311,16 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle Token Endpoint interaction
|
// Handle Token Endpoint interaction
|
||||||
|
|
||||||
HttpClient httpClient = HttpClientBuilder.create()
|
HttpClient httpClient = HttpClientBuilder.create()
|
||||||
.useSystemProperties()
|
.useSystemProperties()
|
||||||
.setDefaultRequestConfig(
|
.setDefaultRequestConfig(
|
||||||
RequestConfig.custom()
|
RequestConfig.custom()
|
||||||
.setSocketTimeout(httpSocketTimeout)
|
.setSocketTimeout(httpSocketTimeout)
|
||||||
.build()
|
.build()
|
||||||
)
|
)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);
|
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);
|
||||||
|
|
||||||
RestTemplate restTemplate;
|
RestTemplate restTemplate;
|
||||||
|
@ -363,7 +363,7 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi
|
||||||
|
|
||||||
// needs to be wired in to the bean
|
// needs to be wired in to the bean
|
||||||
signer = authenticationSignerService;
|
signer = authenticationSignerService;
|
||||||
|
|
||||||
if (alg == null) {
|
if (alg == null) {
|
||||||
alg = authenticationSignerService.getDefaultSigningAlgorithm();
|
alg = authenticationSignerService.getDefaultSigningAlgorithm();
|
||||||
}
|
}
|
||||||
|
@ -475,39 +475,39 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi
|
||||||
JwtSigningAndValidationService jwtValidator = null;
|
JwtSigningAndValidationService jwtValidator = null;
|
||||||
|
|
||||||
Algorithm tokenAlg = idToken.getHeader().getAlgorithm();
|
Algorithm tokenAlg = idToken.getHeader().getAlgorithm();
|
||||||
|
|
||||||
Algorithm clientAlg = clientConfig.getIdTokenSignedResponseAlg();
|
Algorithm clientAlg = clientConfig.getIdTokenSignedResponseAlg();
|
||||||
|
|
||||||
if (clientAlg != null) {
|
if (clientAlg != null) {
|
||||||
if (!clientAlg.equals(tokenAlg)) {
|
if (!clientAlg.equals(tokenAlg)) {
|
||||||
throw new AuthenticationServiceException("Token algorithm " + tokenAlg + " does not match expected algorithm " + clientAlg);
|
throw new AuthenticationServiceException("Token algorithm " + tokenAlg + " does not match expected algorithm " + clientAlg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (idToken instanceof PlainJWT) {
|
if (idToken instanceof PlainJWT) {
|
||||||
|
|
||||||
if (clientAlg == null) {
|
if (clientAlg == null) {
|
||||||
throw new AuthenticationServiceException("Unsigned ID tokens can only be used if explicitly configured in client.");
|
throw new AuthenticationServiceException("Unsigned ID tokens can only be used if explicitly configured in client.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tokenAlg != null && !tokenAlg.equals(JWSAlgorithm.NONE)) {
|
if (tokenAlg != null && !tokenAlg.equals(Algorithm.NONE)) {
|
||||||
throw new AuthenticationServiceException("Unsigned token received, expected signature with " + tokenAlg);
|
throw new AuthenticationServiceException("Unsigned token received, expected signature with " + tokenAlg);
|
||||||
}
|
}
|
||||||
} else if (idToken instanceof SignedJWT) {
|
} else if (idToken instanceof SignedJWT) {
|
||||||
|
|
||||||
SignedJWT signedIdToken = (SignedJWT)idToken;
|
SignedJWT signedIdToken = (SignedJWT)idToken;
|
||||||
|
|
||||||
if (tokenAlg.equals(JWSAlgorithm.HS256)
|
if (tokenAlg.equals(JWSAlgorithm.HS256)
|
||||||
|| tokenAlg.equals(JWSAlgorithm.HS384)
|
|| tokenAlg.equals(JWSAlgorithm.HS384)
|
||||||
|| tokenAlg.equals(JWSAlgorithm.HS512)) {
|
|| tokenAlg.equals(JWSAlgorithm.HS512)) {
|
||||||
|
|
||||||
// generate one based on client secret
|
// generate one based on client secret
|
||||||
jwtValidator = symmetricCacheService.getSymmetricValidtor(clientConfig.getClient());
|
jwtValidator = symmetricCacheService.getSymmetricValidtor(clientConfig.getClient());
|
||||||
} else {
|
} else {
|
||||||
// otherwise load from the server's public key
|
// otherwise load from the server's public key
|
||||||
jwtValidator = validationServices.getValidator(serverConfig.getJwksUri());
|
jwtValidator = validationServices.getValidator(serverConfig.getJwksUri());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (jwtValidator != null) {
|
if (jwtValidator != null) {
|
||||||
if(!jwtValidator.validateSignature(signedIdToken)) {
|
if(!jwtValidator.validateSignature(signedIdToken)) {
|
||||||
throw new AuthenticationServiceException("Signature validation failed");
|
throw new AuthenticationServiceException("Signature validation failed");
|
||||||
|
@ -564,20 +564,20 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi
|
||||||
|
|
||||||
// compare the nonce to our stored claim
|
// compare the nonce to our stored claim
|
||||||
String nonce = idClaims.getStringClaim("nonce");
|
String nonce = idClaims.getStringClaim("nonce");
|
||||||
|
|
||||||
if (serverConfig.isNonceEnabled()) {
|
if (serverConfig.isNonceEnabled()) {
|
||||||
if (Strings.isNullOrEmpty(nonce)) {
|
if (Strings.isNullOrEmpty(nonce)) {
|
||||||
|
|
||||||
logger.error("ID token did not contain a nonce claim.");
|
logger.error("ID token did not contain a nonce claim.");
|
||||||
|
|
||||||
throw new AuthenticationServiceException("ID token did not contain a nonce claim.");
|
throw new AuthenticationServiceException("ID token did not contain a nonce claim.");
|
||||||
}
|
}
|
||||||
|
|
||||||
String storedNonce = getStoredNonce(session);
|
String storedNonce = getStoredNonce(session);
|
||||||
if (!nonce.equals(storedNonce)) {
|
if (!nonce.equals(storedNonce)) {
|
||||||
logger.error("Possible replay attack detected! The comparison of the nonce in the returned "
|
logger.error("Possible replay attack detected! The comparison of the nonce in the returned "
|
||||||
+ "ID Token to the session " + NONCE_SESSION_VARIABLE + " failed. Expected " + storedNonce + " got " + nonce + ".");
|
+ "ID Token to the session " + NONCE_SESSION_VARIABLE + " failed. Expected " + storedNonce + " got " + nonce + ".");
|
||||||
|
|
||||||
throw new AuthenticationServiceException(
|
throw new AuthenticationServiceException(
|
||||||
"Possible replay attack detected! The comparison of the nonce in the returned "
|
"Possible replay attack detected! The comparison of the nonce in the returned "
|
||||||
+ "ID Token to the session " + NONCE_SESSION_VARIABLE + " failed. Expected " + storedNonce + " got " + nonce + ".");
|
+ "ID Token to the session " + NONCE_SESSION_VARIABLE + " failed. Expected " + storedNonce + " got " + nonce + ".");
|
||||||
|
|
|
@ -64,19 +64,19 @@ public class UserInfoFetcher {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
// if we got this far, try to actually get the userinfo
|
// if we got this far, try to actually get the userinfo
|
||||||
HttpClient httpClient = HttpClientBuilder.create()
|
HttpClient httpClient = HttpClientBuilder.create()
|
||||||
.useSystemProperties()
|
.useSystemProperties()
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);
|
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);
|
||||||
|
|
||||||
String userInfoString = null;
|
String userInfoString = null;
|
||||||
|
|
||||||
if (serverConfiguration.getUserInfoTokenMethod() == null || serverConfiguration.getUserInfoTokenMethod().equals(UserInfoTokenMethod.HEADER)) {
|
if (serverConfiguration.getUserInfoTokenMethod() == null || serverConfiguration.getUserInfoTokenMethod().equals(UserInfoTokenMethod.HEADER)) {
|
||||||
RestTemplate restTemplate = new RestTemplate(factory) {
|
RestTemplate restTemplate = new RestTemplate(factory) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ClientHttpRequest createRequest(URI url, HttpMethod method) throws IOException {
|
protected ClientHttpRequest createRequest(URI url, HttpMethod method) throws IOException {
|
||||||
ClientHttpRequest httpRequest = super.createRequest(url, method);
|
ClientHttpRequest httpRequest = super.createRequest(url, method);
|
||||||
|
@ -84,19 +84,19 @@ public class UserInfoFetcher {
|
||||||
return httpRequest;
|
return httpRequest;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
userInfoString = restTemplate.getForObject(serverConfiguration.getUserInfoUri(), String.class);
|
userInfoString = restTemplate.getForObject(serverConfiguration.getUserInfoUri(), String.class);
|
||||||
|
|
||||||
} else if (serverConfiguration.getUserInfoTokenMethod().equals(UserInfoTokenMethod.FORM)) {
|
} else if (serverConfiguration.getUserInfoTokenMethod().equals(UserInfoTokenMethod.FORM)) {
|
||||||
MultiValueMap<String, String> form = new LinkedMultiValueMap<String, String>();
|
MultiValueMap<String, String> form = new LinkedMultiValueMap<String, String>();
|
||||||
form.add("access_token", token.getAccessTokenValue());
|
form.add("access_token", token.getAccessTokenValue());
|
||||||
|
|
||||||
RestTemplate restTemplate = new RestTemplate(factory);
|
RestTemplate restTemplate = new RestTemplate(factory);
|
||||||
userInfoString = restTemplate.postForObject(serverConfiguration.getUserInfoUri(), form, String.class);
|
userInfoString = restTemplate.postForObject(serverConfiguration.getUserInfoUri(), form, String.class);
|
||||||
} else if (serverConfiguration.getUserInfoTokenMethod().equals(UserInfoTokenMethod.QUERY)) {
|
} else if (serverConfiguration.getUserInfoTokenMethod().equals(UserInfoTokenMethod.QUERY)) {
|
||||||
URIBuilder builder = new URIBuilder(serverConfiguration.getUserInfoUri());
|
URIBuilder builder = new URIBuilder(serverConfiguration.getUserInfoUri());
|
||||||
builder.setParameter("access_token", token.getAccessTokenValue());
|
builder.setParameter("access_token", token.getAccessTokenValue());
|
||||||
|
|
||||||
RestTemplate restTemplate = new RestTemplate(factory);
|
RestTemplate restTemplate = new RestTemplate(factory);
|
||||||
userInfoString = restTemplate.getForObject(builder.toString(), String.class);
|
userInfoString = restTemplate.getForObject(builder.toString(), String.class);
|
||||||
}
|
}
|
||||||
|
@ -105,7 +105,7 @@ public class UserInfoFetcher {
|
||||||
if (!Strings.isNullOrEmpty(userInfoString)) {
|
if (!Strings.isNullOrEmpty(userInfoString)) {
|
||||||
|
|
||||||
JsonObject userInfoJson = new JsonParser().parse(userInfoString).getAsJsonObject();
|
JsonObject userInfoJson = new JsonParser().parse(userInfoString).getAsJsonObject();
|
||||||
|
|
||||||
UserInfo userInfo = DefaultUserInfo.fromJson(userInfoJson);
|
UserInfo userInfo = DefaultUserInfo.fromJson(userInfoJson);
|
||||||
|
|
||||||
return userInfo;
|
return userInfo;
|
||||||
|
|
|
@ -203,19 +203,19 @@ public class DynamicRegistrationClientConfigurationService implements ClientConf
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (knownClient.getClientId() == null) {
|
if (knownClient.getClientId() == null) {
|
||||||
|
|
||||||
// load this client's information from the server
|
// load this client's information from the server
|
||||||
HttpHeaders headers = new HttpHeaders();
|
HttpHeaders headers = new HttpHeaders();
|
||||||
headers.set("Authorization", String.format("%s %s", OAuth2AccessToken.BEARER_TYPE, knownClient.getRegistrationAccessToken()));
|
headers.set("Authorization", String.format("%s %s", OAuth2AccessToken.BEARER_TYPE, knownClient.getRegistrationAccessToken()));
|
||||||
headers.setAccept(Lists.newArrayList(MediaType.APPLICATION_JSON));
|
headers.setAccept(Lists.newArrayList(MediaType.APPLICATION_JSON));
|
||||||
|
|
||||||
HttpEntity<String> entity = new HttpEntity<String>(headers);
|
HttpEntity<String> entity = new HttpEntity<String>(headers);
|
||||||
|
|
||||||
String registered = restTemplate.exchange(knownClient.getRegistrationClientUri(), HttpMethod.GET, entity, String.class).getBody();
|
String registered = restTemplate.exchange(knownClient.getRegistrationClientUri(), HttpMethod.GET, entity, String.class).getBody();
|
||||||
// TODO: handle HTTP errors
|
// TODO: handle HTTP errors
|
||||||
|
|
||||||
RegisteredClient client = ClientDetailsEntityJsonProcessor.parseRegistered(registered);
|
RegisteredClient client = ClientDetailsEntityJsonProcessor.parseRegistered(registered);
|
||||||
|
|
||||||
return client;
|
return client;
|
||||||
} else {
|
} else {
|
||||||
// it's got a client ID from the store, don't bother trying to load it
|
// it's got a client ID from the store, don't bother trying to load it
|
||||||
|
|
|
@ -32,73 +32,73 @@ import com.google.gson.JsonObject;
|
||||||
public class TestOAuth2AccessTokenImpl {
|
public class TestOAuth2AccessTokenImpl {
|
||||||
|
|
||||||
private static String tokenString = "thisisatokenstring";
|
private static String tokenString = "thisisatokenstring";
|
||||||
|
|
||||||
private static Set<String> scopes = ImmutableSet.of("bar", "foo");
|
private static Set<String> scopes = ImmutableSet.of("bar", "foo");
|
||||||
private static String scopeString = "foo bar";
|
private static String scopeString = "foo bar";
|
||||||
|
|
||||||
private static Date exp = new Date(123 * 1000L);
|
private static Date exp = new Date(123 * 1000L);
|
||||||
private static Long expVal = 123L;
|
private static Long expVal = 123L;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFullToken() {
|
public void testFullToken() {
|
||||||
|
|
||||||
|
|
||||||
JsonObject tokenObj = new JsonObject();
|
JsonObject tokenObj = new JsonObject();
|
||||||
tokenObj.addProperty("active", true);
|
tokenObj.addProperty("active", true);
|
||||||
tokenObj.addProperty("scope", scopeString);
|
tokenObj.addProperty("scope", scopeString);
|
||||||
tokenObj.addProperty("exp", expVal);
|
tokenObj.addProperty("exp", expVal);
|
||||||
tokenObj.addProperty("sub", "subject");
|
tokenObj.addProperty("sub", "subject");
|
||||||
tokenObj.addProperty("client_id", "123-456-789");
|
tokenObj.addProperty("client_id", "123-456-789");
|
||||||
|
|
||||||
OAuth2AccessTokenImpl tok = new OAuth2AccessTokenImpl(tokenObj, tokenString);
|
OAuth2AccessTokenImpl tok = new OAuth2AccessTokenImpl(tokenObj, tokenString);
|
||||||
|
|
||||||
assertThat(tok.getScope(), is(equalTo(scopes)));
|
assertThat(tok.getScope(), is(equalTo(scopes)));
|
||||||
assertThat(tok.getExpiration(), is(equalTo(exp)));
|
assertThat(tok.getExpiration(), is(equalTo(exp)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNullExp() {
|
public void testNullExp() {
|
||||||
|
|
||||||
|
|
||||||
JsonObject tokenObj = new JsonObject();
|
JsonObject tokenObj = new JsonObject();
|
||||||
tokenObj.addProperty("active", true);
|
tokenObj.addProperty("active", true);
|
||||||
tokenObj.addProperty("scope", scopeString);
|
tokenObj.addProperty("scope", scopeString);
|
||||||
tokenObj.addProperty("sub", "subject");
|
tokenObj.addProperty("sub", "subject");
|
||||||
tokenObj.addProperty("client_id", "123-456-789");
|
tokenObj.addProperty("client_id", "123-456-789");
|
||||||
|
|
||||||
OAuth2AccessTokenImpl tok = new OAuth2AccessTokenImpl(tokenObj, tokenString);
|
OAuth2AccessTokenImpl tok = new OAuth2AccessTokenImpl(tokenObj, tokenString);
|
||||||
|
|
||||||
assertThat(tok.getScope(), is(equalTo(scopes)));
|
assertThat(tok.getScope(), is(equalTo(scopes)));
|
||||||
assertThat(tok.getExpiration(), is(equalTo(null)));
|
assertThat(tok.getExpiration(), is(equalTo(null)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNullScopes() {
|
public void testNullScopes() {
|
||||||
|
|
||||||
|
|
||||||
JsonObject tokenObj = new JsonObject();
|
JsonObject tokenObj = new JsonObject();
|
||||||
tokenObj.addProperty("active", true);
|
tokenObj.addProperty("active", true);
|
||||||
tokenObj.addProperty("exp", expVal);
|
tokenObj.addProperty("exp", expVal);
|
||||||
tokenObj.addProperty("sub", "subject");
|
tokenObj.addProperty("sub", "subject");
|
||||||
tokenObj.addProperty("client_id", "123-456-789");
|
tokenObj.addProperty("client_id", "123-456-789");
|
||||||
|
|
||||||
OAuth2AccessTokenImpl tok = new OAuth2AccessTokenImpl(tokenObj, tokenString);
|
OAuth2AccessTokenImpl tok = new OAuth2AccessTokenImpl(tokenObj, tokenString);
|
||||||
|
|
||||||
assertThat(tok.getScope(), is(equalTo(Collections.EMPTY_SET)));
|
assertThat(tok.getScope(), is(equalTo(Collections.EMPTY_SET)));
|
||||||
assertThat(tok.getExpiration(), is(equalTo(exp)));
|
assertThat(tok.getExpiration(), is(equalTo(exp)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNullScopesNullExp() {
|
public void testNullScopesNullExp() {
|
||||||
|
|
||||||
|
|
||||||
JsonObject tokenObj = new JsonObject();
|
JsonObject tokenObj = new JsonObject();
|
||||||
tokenObj.addProperty("active", true);
|
tokenObj.addProperty("active", true);
|
||||||
tokenObj.addProperty("sub", "subject");
|
tokenObj.addProperty("sub", "subject");
|
||||||
tokenObj.addProperty("client_id", "123-456-789");
|
tokenObj.addProperty("client_id", "123-456-789");
|
||||||
|
|
||||||
OAuth2AccessTokenImpl tok = new OAuth2AccessTokenImpl(tokenObj, tokenString);
|
OAuth2AccessTokenImpl tok = new OAuth2AccessTokenImpl(tokenObj, tokenString);
|
||||||
|
|
||||||
assertThat(tok.getScope(), is(equalTo(Collections.EMPTY_SET)));
|
assertThat(tok.getScope(), is(equalTo(Collections.EMPTY_SET)));
|
||||||
assertThat(tok.getExpiration(), is(equalTo(null)));
|
assertThat(tok.getExpiration(), is(equalTo(null)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,11 +82,11 @@ public class TestPlainAuthRequestUrlBuilder {
|
||||||
|
|
||||||
urlBuilder.buildAuthRequestUrl(serverConfig, clientConfig, "example.com", "", "", options);
|
urlBuilder.buildAuthRequestUrl(serverConfig, clientConfig, "example.com", "", "", options);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void buildAuthRequestUrl_withNoNonce() {
|
public void buildAuthRequestUrl_withNoNonce() {
|
||||||
Mockito.when(serverConfig.isNonceEnabled()).thenReturn(false);
|
Mockito.when(serverConfig.isNonceEnabled()).thenReturn(false);
|
||||||
|
|
||||||
String expectedUrl = "https://server.example.com/authorize?" +
|
String expectedUrl = "https://server.example.com/authorize?" +
|
||||||
"response_type=code" +
|
"response_type=code" +
|
||||||
"&client_id=s6BhdRkqt3" +
|
"&client_id=s6BhdRkqt3" +
|
||||||
|
@ -100,7 +100,7 @@ public class TestPlainAuthRequestUrlBuilder {
|
||||||
String actualUrl = urlBuilder.buildAuthRequestUrl(serverConfig, clientConfig, "https://client.example.org/", null, "af0ifjsldkj", options);
|
String actualUrl = urlBuilder.buildAuthRequestUrl(serverConfig, clientConfig, "https://client.example.org/", null, "af0ifjsldkj", options);
|
||||||
|
|
||||||
assertThat(actualUrl, equalTo(expectedUrl));
|
assertThat(actualUrl, equalTo(expectedUrl));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,7 +115,7 @@ public class DefaultJwtSigningAndValidationService implements JwtSigningAndValid
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String getDefaultSignerKeyId() {
|
public String getDefaultSignerKeyId() {
|
||||||
return defaultSignerKeyId;
|
return defaultSignerKeyId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -188,7 +188,7 @@ public class DefaultJwtSigningAndValidationService implements JwtSigningAndValid
|
||||||
logger.warn("Unknown key type: " + jwk);
|
logger.warn("Unknown key type: " + jwk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (defaultSignerKeyId == null && keys.size() == 1) {
|
if (defaultSignerKeyId == null && keys.size() == 1) {
|
||||||
// if there's only one key, it's the default
|
// if there's only one key, it's the default
|
||||||
setDefaultSignerKeyId(keys.keySet().iterator().next());
|
setDefaultSignerKeyId(keys.keySet().iterator().next());
|
||||||
|
|
|
@ -33,7 +33,7 @@ import org.springframework.security.oauth2.provider.OAuth2Authentication;
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "authentication_holder")
|
@Table(name = "authentication_holder")
|
||||||
@NamedQueries ({
|
@NamedQueries ({
|
||||||
@NamedQuery(name = "AuthenticationHolderEntity.getAll", query = "select a from AuthenticationHolderEntity a"),
|
@NamedQuery(name = "AuthenticationHolderEntity.getAll", query = "select a from AuthenticationHolderEntity a"),
|
||||||
@NamedQuery(name = "AuthenticationHolderEntity.getByAuthentication", query = "select a from AuthenticationHolderEntity a where a.authentication = :authentication"),
|
@NamedQuery(name = "AuthenticationHolderEntity.getByAuthentication", query = "select a from AuthenticationHolderEntity a where a.authentication = :authentication"),
|
||||||
@NamedQuery(name = "AuthenticationHolderEntity.getUnusedAuthenticationHolders", query = "select a from AuthenticationHolderEntity a where a.id not in (select t.authenticationHolder.id from OAuth2AccessTokenEntity t) and a.id not in (select r.authenticationHolder.id from OAuth2RefreshTokenEntity r)")
|
@NamedQuery(name = "AuthenticationHolderEntity.getUnusedAuthenticationHolders", query = "select a from AuthenticationHolderEntity a where a.id not in (select t.authenticationHolder.id from OAuth2AccessTokenEntity t) and a.id not in (select r.authenticationHolder.id from OAuth2RefreshTokenEntity r)")
|
||||||
})
|
})
|
||||||
|
|
|
@ -353,8 +353,8 @@ public class ClientDetailsEntity implements ClientDetails {
|
||||||
public boolean isSecretRequired() {
|
public boolean isSecretRequired() {
|
||||||
if (getTokenEndpointAuthMethod() != null &&
|
if (getTokenEndpointAuthMethod() != null &&
|
||||||
(getTokenEndpointAuthMethod().equals(AuthMethod.SECRET_BASIC) ||
|
(getTokenEndpointAuthMethod().equals(AuthMethod.SECRET_BASIC) ||
|
||||||
getTokenEndpointAuthMethod().equals(AuthMethod.SECRET_POST) ||
|
getTokenEndpointAuthMethod().equals(AuthMethod.SECRET_POST) ||
|
||||||
getTokenEndpointAuthMethod().equals(AuthMethod.SECRET_JWT))) {
|
getTokenEndpointAuthMethod().equals(AuthMethod.SECRET_JWT))) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -22,7 +22,7 @@ import org.mitre.oauth2.model.AuthenticationHolderEntity;
|
||||||
import org.springframework.security.oauth2.provider.OAuth2Authentication;
|
import org.springframework.security.oauth2.provider.OAuth2Authentication;
|
||||||
|
|
||||||
public interface AuthenticationHolderRepository {
|
public interface AuthenticationHolderRepository {
|
||||||
public List<AuthenticationHolderEntity> getAll();
|
public List<AuthenticationHolderEntity> getAll();
|
||||||
|
|
||||||
public AuthenticationHolderEntity getById(Long id);
|
public AuthenticationHolderEntity getById(Long id);
|
||||||
|
|
||||||
|
|
|
@ -16,33 +16,33 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.mitre.oauth2.service;
|
package org.mitre.oauth2.service;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.mitre.oauth2.model.OAuth2AccessTokenEntity;
|
import org.mitre.oauth2.model.OAuth2AccessTokenEntity;
|
||||||
import org.mitre.oauth2.model.OAuth2RefreshTokenEntity;
|
import org.mitre.oauth2.model.OAuth2RefreshTokenEntity;
|
||||||
import org.mitre.openid.connect.model.UserInfo;
|
import org.mitre.openid.connect.model.UserInfo;
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Strategy interface for assembling a token introspection result.
|
* Strategy interface for assembling a token introspection result.
|
||||||
*/
|
*/
|
||||||
public interface IntrospectionResultAssembler {
|
public interface IntrospectionResultAssembler {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assemble a token introspection result from the given access token and user info.
|
* Assemble a token introspection result from the given access token and user info.
|
||||||
*
|
*
|
||||||
* @param accessToken the access token
|
* @param accessToken the access token
|
||||||
* @param userInfo the user info
|
* @param userInfo the user info
|
||||||
* @return the token introspection result
|
* @return the token introspection result
|
||||||
*/
|
*/
|
||||||
Map<String, Object> assembleFrom(OAuth2AccessTokenEntity accessToken, UserInfo userInfo);
|
Map<String, Object> assembleFrom(OAuth2AccessTokenEntity accessToken, UserInfo userInfo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assemble a token introspection result from the given refresh token and user info.
|
* Assemble a token introspection result from the given refresh token and user info.
|
||||||
*
|
*
|
||||||
* @param refreshToken the refresh token
|
* @param refreshToken the refresh token
|
||||||
* @param userInfo the user info
|
* @param userInfo the user info
|
||||||
* @return the token introspection result
|
* @return the token introspection result
|
||||||
*/
|
*/
|
||||||
Map<String, Object> assembleFrom(OAuth2RefreshTokenEntity refreshToken, UserInfo userInfo);
|
Map<String, Object> assembleFrom(OAuth2RefreshTokenEntity refreshToken, UserInfo userInfo);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,6 +63,6 @@ public interface OAuth2TokenEntityService extends AuthorizationServerTokenServic
|
||||||
public Set<OAuth2AccessTokenEntity> getAllAccessTokensForUser(String name);
|
public Set<OAuth2AccessTokenEntity> getAllAccessTokensForUser(String name);
|
||||||
|
|
||||||
public Set<OAuth2RefreshTokenEntity> getAllRefreshTokensForUser(String name);
|
public Set<OAuth2RefreshTokenEntity> getAllRefreshTokensForUser(String name);
|
||||||
|
|
||||||
public OAuth2AccessTokenEntity getRegistrationAccessTokenForClient(ClientDetailsEntity client);
|
public OAuth2AccessTokenEntity getRegistrationAccessTokenForClient(ClientDetailsEntity client);
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ import com.google.common.base.Strings;
|
||||||
public class DefaultClientUserDetailsService implements UserDetailsService {
|
public class DefaultClientUserDetailsService implements UserDetailsService {
|
||||||
|
|
||||||
private static GrantedAuthority ROLE_CLIENT = new SimpleGrantedAuthority("ROLE_CLIENT");
|
private static GrantedAuthority ROLE_CLIENT = new SimpleGrantedAuthority("ROLE_CLIENT");
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ClientDetailsEntityService clientDetailsService;
|
private ClientDetailsEntityService clientDetailsService;
|
||||||
|
|
||||||
|
@ -57,17 +57,17 @@ public class DefaultClientUserDetailsService implements UserDetailsService {
|
||||||
if (client != null) {
|
if (client != null) {
|
||||||
|
|
||||||
String password = Strings.nullToEmpty(client.getClientSecret());
|
String password = Strings.nullToEmpty(client.getClientSecret());
|
||||||
|
|
||||||
if (client.getTokenEndpointAuthMethod() != null &&
|
if (client.getTokenEndpointAuthMethod() != null &&
|
||||||
(client.getTokenEndpointAuthMethod().equals(AuthMethod.PRIVATE_KEY) ||
|
(client.getTokenEndpointAuthMethod().equals(AuthMethod.PRIVATE_KEY) ||
|
||||||
client.getTokenEndpointAuthMethod().equals(AuthMethod.SECRET_JWT))) {
|
client.getTokenEndpointAuthMethod().equals(AuthMethod.SECRET_JWT))) {
|
||||||
|
|
||||||
// Issue a random password each time to prevent password auth from being used (or skipped)
|
// Issue a random password each time to prevent password auth from being used (or skipped)
|
||||||
// for private key or shared key clients, see #715
|
// for private key or shared key clients, see #715
|
||||||
|
|
||||||
password = new BigInteger(512, new SecureRandom()).toString(16);
|
password = new BigInteger(512, new SecureRandom()).toString(16);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean enabled = true;
|
boolean enabled = true;
|
||||||
boolean accountNonExpired = true;
|
boolean accountNonExpired = true;
|
||||||
boolean credentialsNonExpired = true;
|
boolean credentialsNonExpired = true;
|
||||||
|
|
|
@ -60,7 +60,7 @@ public class ClientDetailsEntityJsonProcessor {
|
||||||
JsonElement jsonEl = parser.parse(jsonString);
|
JsonElement jsonEl = parser.parse(jsonString);
|
||||||
return parse(jsonEl);
|
return parse(jsonEl);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ClientDetailsEntity parse(JsonElement jsonEl) {
|
public static ClientDetailsEntity parse(JsonElement jsonEl) {
|
||||||
if (jsonEl.isJsonObject()) {
|
if (jsonEl.isJsonObject()) {
|
||||||
|
|
||||||
|
@ -155,7 +155,7 @@ public class ClientDetailsEntityJsonProcessor {
|
||||||
JsonElement jsonEl = parser.parse(jsonString);
|
JsonElement jsonEl = parser.parse(jsonString);
|
||||||
return parseRegistered(jsonEl);
|
return parseRegistered(jsonEl);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RegisteredClient parseRegistered(JsonElement jsonEl) {
|
public static RegisteredClient parseRegistered(JsonElement jsonEl) {
|
||||||
if (jsonEl.isJsonObject()) {
|
if (jsonEl.isJsonObject()) {
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ import org.springframework.web.servlet.i18n.AbstractLocaleContextResolver;
|
||||||
*/
|
*/
|
||||||
@Component("localeResolver")
|
@Component("localeResolver")
|
||||||
public class ConfigurationBeanLocaleResolver extends AbstractLocaleContextResolver {
|
public class ConfigurationBeanLocaleResolver extends AbstractLocaleContextResolver {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ConfigurationPropertiesBean config;
|
private ConfigurationPropertiesBean config;
|
||||||
|
|
||||||
|
|
|
@ -44,11 +44,11 @@ public class ConfigurationPropertiesBean {
|
||||||
private String topbarTitle;
|
private String topbarTitle;
|
||||||
|
|
||||||
private String logoImageUrl;
|
private String logoImageUrl;
|
||||||
|
|
||||||
private Long regTokenLifeTime;
|
private Long regTokenLifeTime;
|
||||||
|
|
||||||
private boolean forceHttps = false;
|
private boolean forceHttps = false;
|
||||||
|
|
||||||
private Locale locale = Locale.getDefault();
|
private Locale locale = Locale.getDefault();
|
||||||
|
|
||||||
public ConfigurationPropertiesBean() {
|
public ConfigurationPropertiesBean() {
|
||||||
|
@ -57,7 +57,7 @@ public class ConfigurationPropertiesBean {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Endpoints protected by TLS must have https scheme in the URI.
|
* Endpoints protected by TLS must have https scheme in the URI.
|
||||||
* @throws HttpsUrlRequiredException
|
* @throws HttpsUrlRequiredException
|
||||||
*/
|
*/
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void checkForHttps() {
|
public void checkForHttps() {
|
||||||
|
@ -127,7 +127,7 @@ public class ConfigurationPropertiesBean {
|
||||||
public void setRegTokenLifeTime(Long regTokenLifeTime) {
|
public void setRegTokenLifeTime(Long regTokenLifeTime) {
|
||||||
this.regTokenLifeTime = regTokenLifeTime;
|
this.regTokenLifeTime = regTokenLifeTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isForceHttps() {
|
public boolean isForceHttps() {
|
||||||
return forceHttps;
|
return forceHttps;
|
||||||
}
|
}
|
||||||
|
|
|
@ -205,23 +205,23 @@ public class ServerConfiguration {
|
||||||
private Boolean requireRequestUriRegistration;
|
private Boolean requireRequestUriRegistration;
|
||||||
private String opPolicyUri;
|
private String opPolicyUri;
|
||||||
private String opTosUri;
|
private String opTosUri;
|
||||||
|
|
||||||
//
|
//
|
||||||
// extensions to the discoverable methods
|
// extensions to the discoverable methods
|
||||||
//
|
//
|
||||||
|
|
||||||
// how do we send the access token to the userinfo endpoint?
|
// how do we send the access token to the userinfo endpoint?
|
||||||
private UserInfoTokenMethod userInfoTokenMethod;
|
private UserInfoTokenMethod userInfoTokenMethod;
|
||||||
|
|
||||||
public enum UserInfoTokenMethod {
|
public enum UserInfoTokenMethod {
|
||||||
HEADER,
|
HEADER,
|
||||||
FORM,
|
FORM,
|
||||||
QUERY;
|
QUERY;
|
||||||
}
|
}
|
||||||
|
|
||||||
// do we create and send a nonce value?
|
// do we create and send a nonce value?
|
||||||
private boolean nonceEnabled = true;
|
private boolean nonceEnabled = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the authorizationEndpointUri
|
* @return the authorizationEndpointUri
|
||||||
*/
|
*/
|
||||||
|
@ -666,7 +666,7 @@ public class ServerConfiguration {
|
||||||
public void setOpTosUri(String opTosUri) {
|
public void setOpTosUri(String opTosUri) {
|
||||||
this.opTosUri = opTosUri;
|
this.opTosUri = opTosUri;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getRevocationEndpointUri() {
|
public String getRevocationEndpointUri() {
|
||||||
return revocationEndpointUri;
|
return revocationEndpointUri;
|
||||||
}
|
}
|
||||||
|
@ -681,7 +681,7 @@ public class ServerConfiguration {
|
||||||
this.userInfoTokenMethod = userInfoTokenMethod;
|
this.userInfoTokenMethod = userInfoTokenMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the nonceEnabled
|
* @return the nonceEnabled
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -37,6 +37,10 @@ import com.google.gson.JsonObject;
|
||||||
})
|
})
|
||||||
public class DefaultUserInfo implements UserInfo {
|
public class DefaultUserInfo implements UserInfo {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = 6078310513185681918L;
|
||||||
private Long id;
|
private Long id;
|
||||||
private String sub;
|
private String sub;
|
||||||
private String preferredUsername;
|
private String preferredUsername;
|
||||||
|
|
|
@ -31,32 +31,32 @@ public interface MITREidDataService {
|
||||||
* Data member for 1.X configurations
|
* Data member for 1.X configurations
|
||||||
*/
|
*/
|
||||||
public static final String MITREID_CONNECT_1_0 = "mitreid-connect-1.0";
|
public static final String MITREID_CONNECT_1_0 = "mitreid-connect-1.0";
|
||||||
public static final String MITREID_CONNECT_1_1 = "mitreid-connect-1.1";
|
public static final String MITREID_CONNECT_1_1 = "mitreid-connect-1.1";
|
||||||
public static final String MITREID_CONNECT_1_2 = "mitreid-connect-1.2";
|
public static final String MITREID_CONNECT_1_2 = "mitreid-connect-1.2";
|
||||||
|
|
||||||
// member names
|
// member names
|
||||||
public static final String REFRESHTOKENS = "refreshTokens";
|
public static final String REFRESHTOKENS = "refreshTokens";
|
||||||
public static final String ACCESSTOKENS = "accessTokens";
|
public static final String ACCESSTOKENS = "accessTokens";
|
||||||
public static final String WHITELISTEDSITES = "whitelistedSites";
|
public static final String WHITELISTEDSITES = "whitelistedSites";
|
||||||
public static final String BLACKLISTEDSITES = "blacklistedSites";
|
public static final String BLACKLISTEDSITES = "blacklistedSites";
|
||||||
public static final String AUTHENTICATIONHOLDERS = "authenticationHolders";
|
public static final String AUTHENTICATIONHOLDERS = "authenticationHolders";
|
||||||
public static final String GRANTS = "grants";
|
public static final String GRANTS = "grants";
|
||||||
public static final String CLIENTS = "clients";
|
public static final String CLIENTS = "clients";
|
||||||
public static final String SYSTEMSCOPES = "systemScopes";
|
public static final String SYSTEMSCOPES = "systemScopes";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write out the current server state to the given JSON writer as a JSON object
|
* Write out the current server state to the given JSON writer as a JSON object
|
||||||
*
|
*
|
||||||
* @param writer
|
* @param writer
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
void exportData(JsonWriter writer) throws IOException;
|
void exportData(JsonWriter writer) throws IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read in the current server state from the given JSON reader as a JSON object
|
* Read in the current server state from the given JSON reader as a JSON object
|
||||||
*
|
*
|
||||||
* @param reader
|
* @param reader
|
||||||
*/
|
*/
|
||||||
void importData(JsonReader reader) throws IOException;
|
void importData(JsonReader reader) throws IOException;
|
||||||
|
|
||||||
}
|
}
|
|
@ -87,11 +87,11 @@ public class UserInfoInterceptor extends HandlerInterceptorAdapter {
|
||||||
modelAndView.addObject("userInfoJson", oidc.getUserInfo().toJson());
|
modelAndView.addObject("userInfoJson", oidc.getUserInfo().toJson());
|
||||||
} else {
|
} else {
|
||||||
modelAndView.addObject("userInfo", null);
|
modelAndView.addObject("userInfo", null);
|
||||||
modelAndView.addObject("userInfoJson", "null");
|
modelAndView.addObject("userInfoJson", "null");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// don't bother checking if we don't have a principal or a userInfoService to work with
|
// don't bother checking if we don't have a principal or a userInfoService to work with
|
||||||
if (p != null && p.getName() != null && userInfoService != null) {
|
if (p != null && p.getName() != null && userInfoService != null) {
|
||||||
|
|
||||||
// try to look up a user based on the principal's name
|
// try to look up a user based on the principal's name
|
||||||
UserInfo user = userInfoService.getByUsername(p.getName());
|
UserInfo user = userInfoService.getByUsername(p.getName());
|
||||||
|
|
|
@ -43,10 +43,10 @@ public class JOSEEmbedTest {
|
||||||
|
|
||||||
assertEquals(JWSAlgorithm.HS256, a.getAlgorithm());
|
assertEquals(JWSAlgorithm.HS256, a.getAlgorithm());
|
||||||
assertEquals("HS256", a.getAlgorithmName());
|
assertEquals("HS256", a.getAlgorithmName());
|
||||||
|
|
||||||
a.setAlgorithm(JWSAlgorithm.HS384);
|
a.setAlgorithm(JWSAlgorithm.HS384);
|
||||||
assertEquals(JWSAlgorithm.HS384, a.getAlgorithm());
|
assertEquals(JWSAlgorithm.HS384, a.getAlgorithm());
|
||||||
|
|
||||||
JWSAlgorithmEmbed null_a = new JWSAlgorithmEmbed(null);
|
JWSAlgorithmEmbed null_a = new JWSAlgorithmEmbed(null);
|
||||||
assertEquals(null, null_a.getAlgorithm());
|
assertEquals(null, null_a.getAlgorithm());
|
||||||
assertEquals(null, null_a.getAlgorithmName());
|
assertEquals(null, null_a.getAlgorithmName());
|
||||||
|
@ -58,8 +58,8 @@ public class JOSEEmbedTest {
|
||||||
|
|
||||||
assertEquals(JWSAlgorithm.RS256, a.getAlgorithm());
|
assertEquals(JWSAlgorithm.RS256, a.getAlgorithm());
|
||||||
assertEquals("RS256", a.getAlgorithmName());
|
assertEquals("RS256", a.getAlgorithmName());
|
||||||
|
|
||||||
JWSAlgorithmEmbed null_a = JWSAlgorithmEmbed.getForAlgorithmName("");
|
JWSAlgorithmEmbed null_a = JWSAlgorithmEmbed.getForAlgorithmName("");
|
||||||
assertEquals(null, null_a);
|
assertEquals(null, null_a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,10 +69,10 @@ public class JOSEEmbedTest {
|
||||||
|
|
||||||
assertEquals(JWEAlgorithm.A128KW, a.getAlgorithm());
|
assertEquals(JWEAlgorithm.A128KW, a.getAlgorithm());
|
||||||
assertEquals("A128KW", a.getAlgorithmName());
|
assertEquals("A128KW", a.getAlgorithmName());
|
||||||
|
|
||||||
a.setAlgorithm(JWEAlgorithm.A256KW);
|
a.setAlgorithm(JWEAlgorithm.A256KW);
|
||||||
assertEquals(JWEAlgorithm.A256KW, a.getAlgorithm());
|
assertEquals(JWEAlgorithm.A256KW, a.getAlgorithm());
|
||||||
|
|
||||||
JWEAlgorithmEmbed null_a = new JWEAlgorithmEmbed(null);
|
JWEAlgorithmEmbed null_a = new JWEAlgorithmEmbed(null);
|
||||||
assertEquals(null, null_a.getAlgorithm());
|
assertEquals(null, null_a.getAlgorithm());
|
||||||
assertEquals(null, null_a.getAlgorithmName());
|
assertEquals(null, null_a.getAlgorithmName());
|
||||||
|
@ -84,7 +84,7 @@ public class JOSEEmbedTest {
|
||||||
|
|
||||||
assertEquals(JWEAlgorithm.RSA1_5, a.getAlgorithm());
|
assertEquals(JWEAlgorithm.RSA1_5, a.getAlgorithm());
|
||||||
assertEquals("RSA1_5", a.getAlgorithmName());
|
assertEquals("RSA1_5", a.getAlgorithmName());
|
||||||
|
|
||||||
JWEAlgorithmEmbed null_a = JWEAlgorithmEmbed.getForAlgorithmName("");
|
JWEAlgorithmEmbed null_a = JWEAlgorithmEmbed.getForAlgorithmName("");
|
||||||
assertEquals(null, null_a);
|
assertEquals(null, null_a);
|
||||||
}
|
}
|
||||||
|
@ -95,10 +95,10 @@ public class JOSEEmbedTest {
|
||||||
|
|
||||||
assertEquals(EncryptionMethod.A128CBC_HS256, a.getAlgorithm());
|
assertEquals(EncryptionMethod.A128CBC_HS256, a.getAlgorithm());
|
||||||
assertEquals("A128CBC-HS256", a.getAlgorithmName());
|
assertEquals("A128CBC-HS256", a.getAlgorithmName());
|
||||||
|
|
||||||
a.setAlgorithm(EncryptionMethod.A256GCM);
|
a.setAlgorithm(EncryptionMethod.A256GCM);
|
||||||
assertEquals(EncryptionMethod.A256GCM, a.getAlgorithm());
|
assertEquals(EncryptionMethod.A256GCM, a.getAlgorithm());
|
||||||
|
|
||||||
JWEEncryptionMethodEmbed null_a = new JWEEncryptionMethodEmbed(null);
|
JWEEncryptionMethodEmbed null_a = new JWEEncryptionMethodEmbed(null);
|
||||||
assertEquals(null, null_a.getAlgorithm());
|
assertEquals(null, null_a.getAlgorithm());
|
||||||
assertEquals(null, null_a.getAlgorithmName());
|
assertEquals(null, null_a.getAlgorithmName());
|
||||||
|
@ -110,7 +110,7 @@ public class JOSEEmbedTest {
|
||||||
|
|
||||||
assertEquals(EncryptionMethod.A256GCM, a.getAlgorithm());
|
assertEquals(EncryptionMethod.A256GCM, a.getAlgorithm());
|
||||||
assertEquals("A256GCM", a.getAlgorithmName());
|
assertEquals("A256GCM", a.getAlgorithmName());
|
||||||
|
|
||||||
JWEEncryptionMethodEmbed null_a = JWEEncryptionMethodEmbed.getForAlgorithmName("");
|
JWEEncryptionMethodEmbed null_a = JWEEncryptionMethodEmbed.getForAlgorithmName("");
|
||||||
assertEquals(null, null_a);
|
assertEquals(null, null_a);
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,65 +45,65 @@ import com.nimbusds.jose.util.Base64URL;
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class TestJWKSetKeyStore {
|
public class TestJWKSetKeyStore {
|
||||||
|
|
||||||
private String RSAkid = "rsa_1";
|
private String RSAkid = "rsa_1";
|
||||||
private JWK RSAjwk = new RSAKey(
|
private JWK RSAjwk = new RSAKey(
|
||||||
new Base64URL("oahUIoWw0K0usKNuOR6H4wkf4oBUXHTxRvgb48E-BVvxkeDNjbC4he8rUW" +
|
new Base64URL("oahUIoWw0K0usKNuOR6H4wkf4oBUXHTxRvgb48E-BVvxkeDNjbC4he8rUW" +
|
||||||
"cJoZmds2h7M70imEVhRU5djINXtqllXI4DFqcI1DgjT9LewND8MW2Krf3S" +
|
"cJoZmds2h7M70imEVhRU5djINXtqllXI4DFqcI1DgjT9LewND8MW2Krf3S" +
|
||||||
"psk_ZkoFnilakGygTwpZ3uesH-PFABNIUYpOiN15dsQRkgr0vEhxN92i2a" +
|
"psk_ZkoFnilakGygTwpZ3uesH-PFABNIUYpOiN15dsQRkgr0vEhxN92i2a" +
|
||||||
"sbOenSZeyaxziK72UwxrrKoExv6kc5twXTq4h-QChLOln0_mtUZwfsRaMS" +
|
"sbOenSZeyaxziK72UwxrrKoExv6kc5twXTq4h-QChLOln0_mtUZwfsRaMS" +
|
||||||
"tPs6mS6XrgxnxbWhojf663tuEQueGC-FCMfra36C9knDFGzKsNa7LZK2dj" +
|
"tPs6mS6XrgxnxbWhojf663tuEQueGC-FCMfra36C9knDFGzKsNa7LZK2dj" +
|
||||||
"YgyD3JR_MB_4NUJW_TqOQtwHYbxevoJArm-L5StowjzGy-_bq6Gw"), // n
|
"YgyD3JR_MB_4NUJW_TqOQtwHYbxevoJArm-L5StowjzGy-_bq6Gw"), // n
|
||||||
new Base64URL("AQAB"), // e
|
new Base64URL("AQAB"), // e
|
||||||
new Base64URL("kLdtIj6GbDks_ApCSTYQtelcNttlKiOyPzMrXHeI-yk1F7-kpDxY4-WY5N" +
|
new Base64URL("kLdtIj6GbDks_ApCSTYQtelcNttlKiOyPzMrXHeI-yk1F7-kpDxY4-WY5N" +
|
||||||
"WV5KntaEeXS1j82E375xxhWMHXyvjYecPT9fpwR_M9gV8n9Hrh2anTpTD9" +
|
"WV5KntaEeXS1j82E375xxhWMHXyvjYecPT9fpwR_M9gV8n9Hrh2anTpTD9" +
|
||||||
"3Dt62ypW3yDsJzBnTnrYu1iwWRgBKrEYY46qAZIrA2xAwnm2X7uGR1hghk" +
|
"3Dt62ypW3yDsJzBnTnrYu1iwWRgBKrEYY46qAZIrA2xAwnm2X7uGR1hghk" +
|
||||||
"qDp0Vqj3kbSCz1XyfCs6_LehBwtxHIyh8Ripy40p24moOAbgxVw3rxT_vl" +
|
"qDp0Vqj3kbSCz1XyfCs6_LehBwtxHIyh8Ripy40p24moOAbgxVw3rxT_vl" +
|
||||||
"t3UVe4WO3JkJOzlpUf-KTVI2Ptgm-dARxTEtE-id-4OJr0h-K-VFs3VSnd" +
|
"t3UVe4WO3JkJOzlpUf-KTVI2Ptgm-dARxTEtE-id-4OJr0h-K-VFs3VSnd" +
|
||||||
"VTIznSxfyrj8ILL6MG_Uv8YAu7VILSB3lOW085-4qE3DzgrTjgyQ"), // d
|
"VTIznSxfyrj8ILL6MG_Uv8YAu7VILSB3lOW085-4qE3DzgrTjgyQ"), // d
|
||||||
KeyUse.ENCRYPTION, null, JWEAlgorithm.RSA_OAEP, RSAkid, null, null, null);
|
KeyUse.ENCRYPTION, null, JWEAlgorithm.RSA_OAEP, RSAkid, null, null, null);
|
||||||
|
|
||||||
private String RSAkid_rsa2 = "rsa_2";
|
private String RSAkid_rsa2 = "rsa_2";
|
||||||
private JWK RSAjwk_rsa2 = new RSAKey(
|
private JWK RSAjwk_rsa2 = new RSAKey(
|
||||||
new Base64URL("oahUIoWw0K0usKNuOR6H4wkf4oBUXHTxRvgb48E-BVvxkeDNjbC4he8rUW" +
|
new Base64URL("oahUIoWw0K0usKNuOR6H4wkf4oBUXHTxRvgb48E-BVvxkeDNjbC4he8rUW" +
|
||||||
"cJoZmds2h7M70imEVhRU5djINXtqllXI4DFqcI1DgjT9LewND8MW2Krf3S" +
|
"cJoZmds2h7M70imEVhRU5djINXtqllXI4DFqcI1DgjT9LewND8MW2Krf3S" +
|
||||||
"psk_ZkoFnilakGygTwpZ3uesH-PFABNIUYpOiN15dsQRkgr0vEhxN92i2a" +
|
"psk_ZkoFnilakGygTwpZ3uesH-PFABNIUYpOiN15dsQRkgr0vEhxN92i2a" +
|
||||||
"sbOenSZeyaxziK72UwxrrKoExv6kc5twXTq4h-QChLOln0_mtUZwfsRaMS" +
|
"sbOenSZeyaxziK72UwxrrKoExv6kc5twXTq4h-QChLOln0_mtUZwfsRaMS" +
|
||||||
"tPs6mS6XrgxnxbWhojf663tuEQueGC-FCMfra36C9knDFGzKsNa7LZK2dj" +
|
"tPs6mS6XrgxnxbWhojf663tuEQueGC-FCMfra36C9knDFGzKsNa7LZK2dj" +
|
||||||
"YgyD3JR_MB_4NUJW_TqOQtwHYbxevoJArm-L5StowjzGy-_bq6Gw"), // n
|
"YgyD3JR_MB_4NUJW_TqOQtwHYbxevoJArm-L5StowjzGy-_bq6Gw"), // n
|
||||||
new Base64URL("AQAB"), // e
|
new Base64URL("AQAB"), // e
|
||||||
new Base64URL("kLdtIj6GbDks_ApCSTYQtelcNttlKiOyPzMrXHeI-yk1F7-kpDxY4-WY5N" +
|
new Base64URL("kLdtIj6GbDks_ApCSTYQtelcNttlKiOyPzMrXHeI-yk1F7-kpDxY4-WY5N" +
|
||||||
"WV5KntaEeXS1j82E375xxhWMHXyvjYecPT9fpwR_M9gV8n9Hrh2anTpTD9" +
|
"WV5KntaEeXS1j82E375xxhWMHXyvjYecPT9fpwR_M9gV8n9Hrh2anTpTD9" +
|
||||||
"3Dt62ypW3yDsJzBnTnrYu1iwWRgBKrEYY46qAZIrA2xAwnm2X7uGR1hghk" +
|
"3Dt62ypW3yDsJzBnTnrYu1iwWRgBKrEYY46qAZIrA2xAwnm2X7uGR1hghk" +
|
||||||
"qDp0Vqj3kbSCz1XyfCs6_LehBwtxHIyh8Ripy40p24moOAbgxVw3rxT_vl" +
|
"qDp0Vqj3kbSCz1XyfCs6_LehBwtxHIyh8Ripy40p24moOAbgxVw3rxT_vl" +
|
||||||
"t3UVe4WO3JkJOzlpUf-KTVI2Ptgm-dARxTEtE-id-4OJr0h-K-VFs3VSnd" +
|
"t3UVe4WO3JkJOzlpUf-KTVI2Ptgm-dARxTEtE-id-4OJr0h-K-VFs3VSnd" +
|
||||||
"VTIznSxfyrj8ILL6MG_Uv8YAu7VILSB3lOW085-4qE3DzgrTjgyQ"), // d
|
"VTIznSxfyrj8ILL6MG_Uv8YAu7VILSB3lOW085-4qE3DzgrTjgyQ"), // d
|
||||||
KeyUse.ENCRYPTION, null, JWEAlgorithm.RSA1_5, RSAkid_rsa2, null, null, null);
|
KeyUse.ENCRYPTION, null, JWEAlgorithm.RSA1_5, RSAkid_rsa2, null, null, null);
|
||||||
|
|
||||||
|
|
||||||
|
List<JWK> keys_list = new LinkedList<JWK>();
|
||||||
|
private JWKSet jwkSet;
|
||||||
|
private String ks_file = "ks.txt";
|
||||||
|
private String ks_file_badJWK = "ks_badJWK.txt";
|
||||||
|
|
||||||
List<JWK> keys_list = new LinkedList<JWK>();
|
|
||||||
private JWKSet jwkSet;
|
|
||||||
private String ks_file = "ks.txt";
|
|
||||||
private String ks_file_badJWK = "ks_badJWK.txt";
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void prepare() throws IOException {
|
public void prepare() throws IOException {
|
||||||
|
|
||||||
keys_list.add(RSAjwk);
|
keys_list.add(RSAjwk);
|
||||||
keys_list.add(RSAjwk_rsa2);
|
keys_list.add(RSAjwk_rsa2);
|
||||||
jwkSet = new JWKSet(keys_list);
|
jwkSet = new JWKSet(keys_list);
|
||||||
jwkSet.getKeys();
|
jwkSet.getKeys();
|
||||||
|
|
||||||
byte jwtbyte[] = jwkSet.toString().getBytes();
|
byte jwtbyte[] = jwkSet.toString().getBytes();
|
||||||
FileOutputStream out = new FileOutputStream(ks_file);
|
FileOutputStream out = new FileOutputStream(ks_file);
|
||||||
out.write(jwtbyte);
|
out.write(jwtbyte);
|
||||||
out.close();
|
out.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
public void cleanup() throws IOException {
|
public void cleanup() throws IOException {
|
||||||
|
|
||||||
File f1 = new File(ks_file);
|
File f1 = new File(ks_file);
|
||||||
if (f1.exists()) {
|
if (f1.exists()) {
|
||||||
f1.delete();
|
f1.delete();
|
||||||
|
@ -112,21 +112,21 @@ public class TestJWKSetKeyStore {
|
||||||
if (f2.exists()) {
|
if (f2.exists()) {
|
||||||
f2.delete();
|
f2.delete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Constructors with no valid Resource setup */
|
/* Constructors with no valid Resource setup */
|
||||||
@Test
|
@Test
|
||||||
public void ksConstructorTest() {
|
public void ksConstructorTest() {
|
||||||
|
|
||||||
JWKSetKeyStore ks = new JWKSetKeyStore(jwkSet);
|
JWKSetKeyStore ks = new JWKSetKeyStore(jwkSet);
|
||||||
assertEquals(ks.getJwkSet(), jwkSet);
|
assertEquals(ks.getJwkSet(), jwkSet);
|
||||||
|
|
||||||
JWKSetKeyStore ks_empty= new JWKSetKeyStore();
|
JWKSetKeyStore ks_empty= new JWKSetKeyStore();
|
||||||
assertEquals(ks_empty.getJwkSet(), null);
|
assertEquals(ks_empty.getJwkSet(), null);
|
||||||
|
|
||||||
boolean thrown = false;
|
boolean thrown = false;
|
||||||
try {
|
try {
|
||||||
JWKSetKeyStore ks_null = new JWKSetKeyStore(null);
|
new JWKSetKeyStore(null);
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
thrown = true;
|
thrown = true;
|
||||||
}
|
}
|
||||||
|
@ -136,74 +136,74 @@ public class TestJWKSetKeyStore {
|
||||||
/* Misformatted JWK */
|
/* Misformatted JWK */
|
||||||
@Test(expected=IllegalArgumentException.class)
|
@Test(expected=IllegalArgumentException.class)
|
||||||
public void ksBadJWKinput() throws IOException {
|
public void ksBadJWKinput() throws IOException {
|
||||||
|
|
||||||
byte jwtbyte[] = RSAjwk.toString().getBytes();
|
byte jwtbyte[] = RSAjwk.toString().getBytes();
|
||||||
FileOutputStream out = new FileOutputStream(ks_file_badJWK);
|
FileOutputStream out = new FileOutputStream(ks_file_badJWK);
|
||||||
out.write(jwtbyte);
|
out.write(jwtbyte);
|
||||||
out.close();
|
out.close();
|
||||||
|
|
||||||
JWKSetKeyStore ks_badJWK = new JWKSetKeyStore();
|
JWKSetKeyStore ks_badJWK = new JWKSetKeyStore();
|
||||||
Resource loc = new FileSystemResource(ks_file_badJWK);
|
Resource loc = new FileSystemResource(ks_file_badJWK);
|
||||||
assertTrue(loc.exists());
|
assertTrue(loc.exists());
|
||||||
|
|
||||||
ks_badJWK.setLocation(loc);
|
ks_badJWK.setLocation(loc);
|
||||||
assertEquals(loc.getFilename(), ks_file_badJWK);
|
assertEquals(loc.getFilename(), ks_file_badJWK);
|
||||||
|
|
||||||
ks_badJWK = new JWKSetKeyStore(null);
|
ks_badJWK = new JWKSetKeyStore(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Empty constructor with valid Resource */
|
/* Empty constructor with valid Resource */
|
||||||
@Test
|
@Test
|
||||||
public void ksEmptyConstructorkLoc() {
|
public void ksEmptyConstructorkLoc() {
|
||||||
|
|
||||||
JWKSetKeyStore ks = new JWKSetKeyStore();
|
JWKSetKeyStore ks = new JWKSetKeyStore();
|
||||||
|
|
||||||
File file = new File(ks_file);
|
File file = new File(ks_file);
|
||||||
|
|
||||||
/* First, test with file without "read" permission */
|
/* First, test with file without "read" permission */
|
||||||
|
|
||||||
boolean set = false;
|
boolean set = false;
|
||||||
|
|
||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
set = file.setReadable(false);
|
set = file.setReadable(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// skip this part of the test on systems that don't allow the settable function, like Windows
|
|
||||||
if (set) {
|
|
||||||
|
|
||||||
Resource loc_noread = new FileSystemResource(file);
|
|
||||||
assertTrue(loc_noread.exists());
|
|
||||||
// assertTrue(!loc_noread.isReadable());
|
|
||||||
|
|
||||||
boolean thrown = false;
|
|
||||||
try {
|
|
||||||
ks.setLocation(loc_noread);
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
thrown = true;
|
|
||||||
}
|
|
||||||
assertTrue(thrown);
|
|
||||||
|
|
||||||
/* Now, make cache file readable */
|
|
||||||
|
|
||||||
if (file.exists()) {
|
|
||||||
file.setReadable(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
// skip this part of the test on systems that don't allow the settable function, like Windows
|
||||||
|
if (set) {
|
||||||
Resource loc = new FileSystemResource(file);
|
|
||||||
|
Resource loc_noread = new FileSystemResource(file);
|
||||||
|
assertTrue(loc_noread.exists());
|
||||||
|
// assertTrue(!loc_noread.isReadable());
|
||||||
|
|
||||||
|
boolean thrown = false;
|
||||||
|
try {
|
||||||
|
ks.setLocation(loc_noread);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
thrown = true;
|
||||||
|
}
|
||||||
|
assertTrue(thrown);
|
||||||
|
|
||||||
|
/* Now, make cache file readable */
|
||||||
|
|
||||||
|
if (file.exists()) {
|
||||||
|
file.setReadable(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Resource loc = new FileSystemResource(file);
|
||||||
assertTrue(loc.exists());
|
assertTrue(loc.exists());
|
||||||
assertTrue(loc.isReadable());
|
assertTrue(loc.isReadable());
|
||||||
|
|
||||||
ks.setLocation(loc);
|
ks.setLocation(loc);
|
||||||
|
|
||||||
assertEquals(loc.getFilename(),ks.getLocation().getFilename());
|
assertEquals(loc.getFilename(),ks.getLocation().getFilename());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void ksSetJwkSet() throws IllegalArgumentException {
|
public void ksSetJwkSet() throws IllegalArgumentException {
|
||||||
|
|
||||||
JWKSetKeyStore ks = new JWKSetKeyStore();
|
JWKSetKeyStore ks = new JWKSetKeyStore();
|
||||||
boolean thrown = false;
|
boolean thrown = false;
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -78,44 +78,45 @@ public class TestDefaultJwtEncryptionAndDecryptionService {
|
||||||
"XFBoMYUZodetZdvTiFvSkQ";
|
"XFBoMYUZodetZdvTiFvSkQ";
|
||||||
|
|
||||||
private String RSAkid = "rsa321";
|
private String RSAkid = "rsa321";
|
||||||
private JWK RSAjwk = new RSAKey(new Base64URL("oahUIoWw0K0usKNuOR6H4wkf4oBUXHTxRvgb48E-BVvxkeDNjbC4he8rUW" +
|
private JWK RSAjwk = new RSAKey(
|
||||||
"cJoZmds2h7M70imEVhRU5djINXtqllXI4DFqcI1DgjT9LewND8MW2Krf3S" +
|
new Base64URL("oahUIoWw0K0usKNuOR6H4wkf4oBUXHTxRvgb48E-BVvxkeDNjbC4he8rUW" +
|
||||||
"psk_ZkoFnilakGygTwpZ3uesH-PFABNIUYpOiN15dsQRkgr0vEhxN92i2a" +
|
"cJoZmds2h7M70imEVhRU5djINXtqllXI4DFqcI1DgjT9LewND8MW2Krf3S" +
|
||||||
"sbOenSZeyaxziK72UwxrrKoExv6kc5twXTq4h-QChLOln0_mtUZwfsRaMS" +
|
"psk_ZkoFnilakGygTwpZ3uesH-PFABNIUYpOiN15dsQRkgr0vEhxN92i2a" +
|
||||||
"tPs6mS6XrgxnxbWhojf663tuEQueGC-FCMfra36C9knDFGzKsNa7LZK2dj" +
|
"sbOenSZeyaxziK72UwxrrKoExv6kc5twXTq4h-QChLOln0_mtUZwfsRaMS" +
|
||||||
"YgyD3JR_MB_4NUJW_TqOQtwHYbxevoJArm-L5StowjzGy-_bq6Gw"), // n
|
"tPs6mS6XrgxnxbWhojf663tuEQueGC-FCMfra36C9knDFGzKsNa7LZK2dj" +
|
||||||
|
"YgyD3JR_MB_4NUJW_TqOQtwHYbxevoJArm-L5StowjzGy-_bq6Gw"), // n
|
||||||
new Base64URL("AQAB"), // e
|
new Base64URL("AQAB"), // e
|
||||||
new Base64URL("kLdtIj6GbDks_ApCSTYQtelcNttlKiOyPzMrXHeI-yk1F7-kpDxY4-WY5N" +
|
new Base64URL("kLdtIj6GbDks_ApCSTYQtelcNttlKiOyPzMrXHeI-yk1F7-kpDxY4-WY5N" +
|
||||||
"WV5KntaEeXS1j82E375xxhWMHXyvjYecPT9fpwR_M9gV8n9Hrh2anTpTD9" +
|
"WV5KntaEeXS1j82E375xxhWMHXyvjYecPT9fpwR_M9gV8n9Hrh2anTpTD9" +
|
||||||
"3Dt62ypW3yDsJzBnTnrYu1iwWRgBKrEYY46qAZIrA2xAwnm2X7uGR1hghk" +
|
"3Dt62ypW3yDsJzBnTnrYu1iwWRgBKrEYY46qAZIrA2xAwnm2X7uGR1hghk" +
|
||||||
"qDp0Vqj3kbSCz1XyfCs6_LehBwtxHIyh8Ripy40p24moOAbgxVw3rxT_vl" +
|
"qDp0Vqj3kbSCz1XyfCs6_LehBwtxHIyh8Ripy40p24moOAbgxVw3rxT_vl" +
|
||||||
"t3UVe4WO3JkJOzlpUf-KTVI2Ptgm-dARxTEtE-id-4OJr0h-K-VFs3VSnd" +
|
"t3UVe4WO3JkJOzlpUf-KTVI2Ptgm-dARxTEtE-id-4OJr0h-K-VFs3VSnd" +
|
||||||
"VTIznSxfyrj8ILL6MG_Uv8YAu7VILSB3lOW085-4qE3DzgrTjgyQ"), // d
|
"VTIznSxfyrj8ILL6MG_Uv8YAu7VILSB3lOW085-4qE3DzgrTjgyQ"), // d
|
||||||
KeyUse.ENCRYPTION, null, JWEAlgorithm.RSA_OAEP, RSAkid, null, null, null);
|
KeyUse.ENCRYPTION, null, JWEAlgorithm.RSA_OAEP, RSAkid, null, null, null);
|
||||||
|
|
||||||
private String RSAkid_2 = "rsa3210";
|
private String RSAkid_2 = "rsa3210";
|
||||||
private JWK RSAjwk_2 = new RSAKey(
|
private JWK RSAjwk_2 = new RSAKey(
|
||||||
new Base64URL("oahUIoWw0K0usKNuOR6H4wkf4oBUXHTxRvgb48E-BVvxkeDNjbC4he8rUW" +
|
new Base64URL("oahUIoWw0K0usKNuOR6H4wkf4oBUXHTxRvgb48E-BVvxkeDNjbC4he8rUW" +
|
||||||
"cJoZmds2h7M70imEVhRU5djINXtqllXI4DFqcI1DgjT9LewND8MW2Krf3S" +
|
"cJoZmds2h7M70imEVhRU5djINXtqllXI4DFqcI1DgjT9LewND8MW2Krf3S" +
|
||||||
"psk_ZkoFnilakGygTwpZ3uesH-PFABNIUYpOiN15dsQRkgr0vEhxN92i2a" +
|
"psk_ZkoFnilakGygTwpZ3uesH-PFABNIUYpOiN15dsQRkgr0vEhxN92i2a" +
|
||||||
"sbOenSZeyaxziK72UwxrrKoExv6kc5twXTq4h-QChLOln0_mtUZwfsRaMS" +
|
"sbOenSZeyaxziK72UwxrrKoExv6kc5twXTq4h-QChLOln0_mtUZwfsRaMS" +
|
||||||
"tPs6mS6XrgxnxbWhojf663tuEQueGC-FCMfra36C9knDFGzKsNa7LZK2dj" +
|
"tPs6mS6XrgxnxbWhojf663tuEQueGC-FCMfra36C9knDFGzKsNa7LZK2dj" +
|
||||||
"YgyD3JR_MB_4NUJW_TqOQtwHYbxevoJArm-L5StowjzGy-_bq6Gw"), // n
|
"YgyD3JR_MB_4NUJW_TqOQtwHYbxevoJArm-L5StowjzGy-_bq6Gw"), // n
|
||||||
new Base64URL("AQAB"), // e
|
new Base64URL("AQAB"), // e
|
||||||
new Base64URL("kLdtIj6GbDks_ApCSTYQtelcNttlKiOyPzMrXHeI-yk1F7-kpDxY4-WY5N" +
|
new Base64URL("kLdtIj6GbDks_ApCSTYQtelcNttlKiOyPzMrXHeI-yk1F7-kpDxY4-WY5N" +
|
||||||
"WV5KntaEeXS1j82E375xxhWMHXyvjYecPT9fpwR_M9gV8n9Hrh2anTpTD9" +
|
"WV5KntaEeXS1j82E375xxhWMHXyvjYecPT9fpwR_M9gV8n9Hrh2anTpTD9" +
|
||||||
"3Dt62ypW3yDsJzBnTnrYu1iwWRgBKrEYY46qAZIrA2xAwnm2X7uGR1hghk" +
|
"3Dt62ypW3yDsJzBnTnrYu1iwWRgBKrEYY46qAZIrA2xAwnm2X7uGR1hghk" +
|
||||||
"qDp0Vqj3kbSCz1XyfCs6_LehBwtxHIyh8Ripy40p24moOAbgxVw3rxT_vl" +
|
"qDp0Vqj3kbSCz1XyfCs6_LehBwtxHIyh8Ripy40p24moOAbgxVw3rxT_vl" +
|
||||||
"t3UVe4WO3JkJOzlpUf-KTVI2Ptgm-dARxTEtE-id-4OJr0h-K-VFs3VSnd" +
|
"t3UVe4WO3JkJOzlpUf-KTVI2Ptgm-dARxTEtE-id-4OJr0h-K-VFs3VSnd" +
|
||||||
"VTIznSxfyrj8ILL6MG_Uv8YAu7VILSB3lOW085-4qE3DzgrTjgyQ"), // d
|
"VTIznSxfyrj8ILL6MG_Uv8YAu7VILSB3lOW085-4qE3DzgrTjgyQ"), // d
|
||||||
KeyUse.ENCRYPTION, null, JWEAlgorithm.RSA1_5, RSAkid_2, null, null, null);
|
KeyUse.ENCRYPTION, null, JWEAlgorithm.RSA1_5, RSAkid_2, null, null, null);
|
||||||
|
|
||||||
private String AESkid = "aes123";
|
private String AESkid = "aes123";
|
||||||
private JWK AESjwk = new OctetSequenceKey( new Base64URL("GawgguFyGrWKav7AX4VKUg"),
|
private JWK AESjwk = new OctetSequenceKey( new Base64URL("GawgguFyGrWKav7AX4VKUg"),
|
||||||
KeyUse.ENCRYPTION, null, JWEAlgorithm.A128KW,
|
KeyUse.ENCRYPTION, null, JWEAlgorithm.A128KW,
|
||||||
AESkid, null, null, null);
|
AESkid, null, null, null);
|
||||||
|
|
||||||
|
|
||||||
private Map<String, JWK> keys = new ImmutableMap.Builder<String, JWK>()
|
private Map<String, JWK> keys = new ImmutableMap.Builder<String, JWK>()
|
||||||
.put(RSAkid, RSAjwk)
|
.put(RSAkid, RSAjwk)
|
||||||
.build();
|
.build();
|
||||||
|
@ -131,7 +132,7 @@ public class TestDefaultJwtEncryptionAndDecryptionService {
|
||||||
.put(RSAkid_2, RSAjwk_2)
|
.put(RSAkid_2, RSAjwk_2)
|
||||||
.put(AESkid, AESjwk)
|
.put(AESkid, AESjwk)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
|
||||||
private List<JWK> keys_list = new LinkedList<JWK>();
|
private List<JWK> keys_list = new LinkedList<JWK>();
|
||||||
|
|
||||||
|
@ -139,8 +140,8 @@ public class TestDefaultJwtEncryptionAndDecryptionService {
|
||||||
private DefaultJwtEncryptionAndDecryptionService service_2;
|
private DefaultJwtEncryptionAndDecryptionService service_2;
|
||||||
private DefaultJwtEncryptionAndDecryptionService service_3;
|
private DefaultJwtEncryptionAndDecryptionService service_3;
|
||||||
private DefaultJwtEncryptionAndDecryptionService service_4;
|
private DefaultJwtEncryptionAndDecryptionService service_4;
|
||||||
private DefaultJwtEncryptionAndDecryptionService service_ks;
|
private DefaultJwtEncryptionAndDecryptionService service_ks;
|
||||||
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void prepare() throws NoSuchAlgorithmException, InvalidKeySpecException, JOSEException {
|
public void prepare() throws NoSuchAlgorithmException, InvalidKeySpecException, JOSEException {
|
||||||
|
@ -152,21 +153,21 @@ public class TestDefaultJwtEncryptionAndDecryptionService {
|
||||||
|
|
||||||
claimsSet.setIssuer(issuer);
|
claimsSet.setIssuer(issuer);
|
||||||
claimsSet.setSubject(subject);
|
claimsSet.setSubject(subject);
|
||||||
|
|
||||||
// Key Store
|
// Key Store
|
||||||
|
|
||||||
keys_list.add(RSAjwk);
|
keys_list.add(RSAjwk);
|
||||||
keys_list.add(AESjwk);
|
keys_list.add(AESjwk);
|
||||||
JWKSet jwkSet = new JWKSet(keys_list);
|
JWKSet jwkSet = new JWKSet(keys_list);
|
||||||
JWKSetKeyStore keyStore = new JWKSetKeyStore(jwkSet);
|
JWKSetKeyStore keyStore = new JWKSetKeyStore(jwkSet);
|
||||||
|
|
||||||
service_ks = new DefaultJwtEncryptionAndDecryptionService(keyStore);
|
service_ks = new DefaultJwtEncryptionAndDecryptionService(keyStore);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void decrypt_RSA() throws ParseException {
|
public void decrypt_RSA() throws ParseException {
|
||||||
|
|
||||||
service.setDefaultDecryptionKeyId(RSAkid);
|
service.setDefaultDecryptionKeyId(RSAkid);
|
||||||
service.setDefaultEncryptionKeyId(RSAkid);
|
service.setDefaultEncryptionKeyId(RSAkid);
|
||||||
|
|
||||||
|
@ -210,7 +211,7 @@ public class TestDefaultJwtEncryptionAndDecryptionService {
|
||||||
|
|
||||||
// The same as encryptThenDecrypt_RSA() but relies on the key from the map
|
// The same as encryptThenDecrypt_RSA() but relies on the key from the map
|
||||||
@Test
|
@Test
|
||||||
public void encryptThenDecrypt_nullID() throws ParseException {
|
public void encryptThenDecrypt_nullID() throws ParseException {
|
||||||
|
|
||||||
service.setDefaultDecryptionKeyId(null);
|
service.setDefaultDecryptionKeyId(null);
|
||||||
service.setDefaultEncryptionKeyId(null);
|
service.setDefaultEncryptionKeyId(null);
|
||||||
|
@ -250,7 +251,7 @@ public class TestDefaultJwtEncryptionAndDecryptionService {
|
||||||
assertEquals(null, service_2.getDefaultEncryptionKeyId());
|
assertEquals(null, service_2.getDefaultEncryptionKeyId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test(expected=IllegalStateException.class)
|
@Test(expected=IllegalStateException.class)
|
||||||
public void decrypt_nullID() throws ParseException {
|
public void decrypt_nullID() throws ParseException {
|
||||||
|
|
||||||
|
@ -286,25 +287,25 @@ public class TestDefaultJwtEncryptionAndDecryptionService {
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getAllPubKeys() throws ParseException {
|
public void getAllPubKeys() throws ParseException {
|
||||||
|
|
||||||
Map<String,JWK> keys2check = service_2.getAllPublicKeys();
|
Map<String,JWK> keys2check = service_2.getAllPublicKeys();
|
||||||
assertEquals(
|
assertEquals(
|
||||||
JSONObjectUtils.getString(RSAjwk.toPublicJWK().toJSONObject(), "e"),
|
JSONObjectUtils.getString(RSAjwk.toPublicJWK().toJSONObject(), "e"),
|
||||||
JSONObjectUtils.getString(keys2check.get(RSAkid).toJSONObject(), "e")
|
JSONObjectUtils.getString(keys2check.get(RSAkid).toJSONObject(), "e")
|
||||||
);
|
);
|
||||||
assertEquals(
|
assertEquals(
|
||||||
JSONObjectUtils.getString(RSAjwk_2.toPublicJWK().toJSONObject(), "e"),
|
JSONObjectUtils.getString(RSAjwk_2.toPublicJWK().toJSONObject(), "e"),
|
||||||
JSONObjectUtils.getString(keys2check.get(RSAkid_2).toJSONObject(), "e")
|
JSONObjectUtils.getString(keys2check.get(RSAkid_2).toJSONObject(), "e")
|
||||||
);
|
);
|
||||||
|
|
||||||
assertTrue(service_3.getAllPublicKeys().isEmpty());
|
assertTrue(service_3.getAllPublicKeys().isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getAllCryptoAlgsSupported() throws ParseException {
|
public void getAllCryptoAlgsSupported() throws ParseException {
|
||||||
|
|
||||||
assertTrue(service_4.getAllEncryptionAlgsSupported().contains(JWEAlgorithm.RSA_OAEP));
|
assertTrue(service_4.getAllEncryptionAlgsSupported().contains(JWEAlgorithm.RSA_OAEP));
|
||||||
assertTrue(service_4.getAllEncryptionAlgsSupported().contains(JWEAlgorithm.RSA1_5));
|
assertTrue(service_4.getAllEncryptionAlgsSupported().contains(JWEAlgorithm.RSA1_5));
|
||||||
assertTrue(service_4.getAllEncryptionAlgsSupported().contains(JWEAlgorithm.DIR));
|
assertTrue(service_4.getAllEncryptionAlgsSupported().contains(JWEAlgorithm.DIR));
|
||||||
|
@ -323,24 +324,24 @@ public class TestDefaultJwtEncryptionAndDecryptionService {
|
||||||
assertTrue(service_ks.getAllEncryptionEncsSupported().contains(EncryptionMethod.A192CBC_HS384));
|
assertTrue(service_ks.getAllEncryptionEncsSupported().contains(EncryptionMethod.A192CBC_HS384));
|
||||||
assertTrue(service_ks.getAllEncryptionEncsSupported().contains(EncryptionMethod.A192GCM));
|
assertTrue(service_ks.getAllEncryptionEncsSupported().contains(EncryptionMethod.A192GCM));
|
||||||
assertTrue(service_ks.getAllEncryptionEncsSupported().contains(EncryptionMethod.A256GCM));
|
assertTrue(service_ks.getAllEncryptionEncsSupported().contains(EncryptionMethod.A256GCM));
|
||||||
assertTrue(service_ks.getAllEncryptionEncsSupported().contains(EncryptionMethod.A256CBC_HS512));
|
assertTrue(service_ks.getAllEncryptionEncsSupported().contains(EncryptionMethod.A256CBC_HS512));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getDefaultCryptoKeyId() throws ParseException {
|
public void getDefaultCryptoKeyId() throws ParseException {
|
||||||
|
|
||||||
// Test set/getDefaultEn/DecryptionKeyId
|
// Test set/getDefaultEn/DecryptionKeyId
|
||||||
|
|
||||||
assertEquals(null, service_4.getDefaultEncryptionKeyId());
|
assertEquals(null, service_4.getDefaultEncryptionKeyId());
|
||||||
assertEquals(null, service_4.getDefaultDecryptionKeyId());
|
assertEquals(null, service_4.getDefaultDecryptionKeyId());
|
||||||
service_4.setDefaultEncryptionKeyId(RSAkid);
|
service_4.setDefaultEncryptionKeyId(RSAkid);
|
||||||
service_4.setDefaultDecryptionKeyId(AESkid);
|
service_4.setDefaultDecryptionKeyId(AESkid);
|
||||||
assertEquals(RSAkid, service_4.getDefaultEncryptionKeyId());
|
assertEquals(RSAkid, service_4.getDefaultEncryptionKeyId());
|
||||||
assertEquals(AESkid, service_4.getDefaultDecryptionKeyId());
|
assertEquals(AESkid, service_4.getDefaultDecryptionKeyId());
|
||||||
|
|
||||||
assertEquals(null, service_ks.getDefaultEncryptionKeyId());
|
assertEquals(null, service_ks.getDefaultEncryptionKeyId());
|
||||||
assertEquals(null, service_ks.getDefaultDecryptionKeyId());
|
assertEquals(null, service_ks.getDefaultDecryptionKeyId());
|
||||||
service_ks.setDefaultEncryptionKeyId(RSAkid);
|
service_ks.setDefaultEncryptionKeyId(RSAkid);
|
||||||
service_ks.setDefaultDecryptionKeyId(AESkid);
|
service_ks.setDefaultDecryptionKeyId(AESkid);
|
||||||
assertEquals( RSAkid, service_ks.getDefaultEncryptionKeyId()) ;
|
assertEquals( RSAkid, service_ks.getDefaultEncryptionKeyId()) ;
|
||||||
|
|
|
@ -30,7 +30,7 @@ import org.springframework.beans.factory.BeanCreationException;
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class ConfigurationPropertiesBeanTest {
|
public class ConfigurationPropertiesBeanTest {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test getters and setters for configuration object.
|
* Test getters and setters for configuration object.
|
||||||
*/
|
*/
|
||||||
|
@ -58,12 +58,12 @@ public class ConfigurationPropertiesBeanTest {
|
||||||
@Test
|
@Test
|
||||||
public void testCheckForHttpsIssuerHttpDefaultFlag() {
|
public void testCheckForHttpsIssuerHttpDefaultFlag() {
|
||||||
ConfigurationPropertiesBean bean = new ConfigurationPropertiesBean();
|
ConfigurationPropertiesBean bean = new ConfigurationPropertiesBean();
|
||||||
|
|
||||||
// issuer is http
|
// issuer is http
|
||||||
// leave as default, which is unset/false
|
// leave as default, which is unset/false
|
||||||
try {
|
try {
|
||||||
bean.setIssuer("http://localhost:8080/openid-connect-server/");
|
bean.setIssuer("http://localhost:8080/openid-connect-server/");
|
||||||
bean.checkForHttps();
|
bean.checkForHttps();
|
||||||
} catch (BeanCreationException e) {
|
} catch (BeanCreationException e) {
|
||||||
fail("Unexpected BeanCreationException for http issuer with default forceHttps, message:" + e.getMessage());
|
fail("Unexpected BeanCreationException for http issuer with default forceHttps, message:" + e.getMessage());
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,7 @@ public class ConfigurationPropertiesBeanTest {
|
||||||
@Test(expected = BeanCreationException.class)
|
@Test(expected = BeanCreationException.class)
|
||||||
public void testCheckForHttpsIssuerHttpTrueFlag() {
|
public void testCheckForHttpsIssuerHttpTrueFlag() {
|
||||||
ConfigurationPropertiesBean bean = new ConfigurationPropertiesBean();
|
ConfigurationPropertiesBean bean = new ConfigurationPropertiesBean();
|
||||||
// issuer is http
|
// issuer is http
|
||||||
// set to true
|
// set to true
|
||||||
bean.setIssuer("http://localhost:8080/openid-connect-server/");
|
bean.setIssuer("http://localhost:8080/openid-connect-server/");
|
||||||
bean.setForceHttps(true);
|
bean.setForceHttps(true);
|
||||||
|
@ -100,12 +100,12 @@ public class ConfigurationPropertiesBeanTest {
|
||||||
// leave as default, which is unset/false
|
// leave as default, which is unset/false
|
||||||
try {
|
try {
|
||||||
bean.setIssuer("https://localhost:8080/openid-connect-server/");
|
bean.setIssuer("https://localhost:8080/openid-connect-server/");
|
||||||
bean.checkForHttps();
|
bean.checkForHttps();
|
||||||
} catch (BeanCreationException e) {
|
} catch (BeanCreationException e) {
|
||||||
fail("Unexpected BeanCreationException for https issuer with default forceHttps, message:" + e.getMessage());
|
fail("Unexpected BeanCreationException for https issuer with default forceHttps, message:" + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCheckForHttpsIssuerHttpsFalseFlag() {
|
public void testCheckForHttpsIssuerHttpsFalseFlag() {
|
||||||
ConfigurationPropertiesBean bean = new ConfigurationPropertiesBean();
|
ConfigurationPropertiesBean bean = new ConfigurationPropertiesBean();
|
||||||
|
@ -119,11 +119,11 @@ public class ConfigurationPropertiesBeanTest {
|
||||||
fail("Unexpected BeanCreationException for https issuer with forceHttps=false, message:" + e.getMessage());
|
fail("Unexpected BeanCreationException for https issuer with forceHttps=false, message:" + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCheckForHttpsIssuerHttpsTrueFlag() {
|
public void testCheckForHttpsIssuerHttpsTrueFlag() {
|
||||||
ConfigurationPropertiesBean bean = new ConfigurationPropertiesBean();
|
ConfigurationPropertiesBean bean = new ConfigurationPropertiesBean();
|
||||||
// issuer is https
|
// issuer is https
|
||||||
// set to true
|
// set to true
|
||||||
try {
|
try {
|
||||||
bean.setIssuer("https://localhost:8080/openid-connect-server/");
|
bean.setIssuer("https://localhost:8080/openid-connect-server/");
|
||||||
|
@ -132,7 +132,7 @@ public class ConfigurationPropertiesBeanTest {
|
||||||
} catch (BeanCreationException e) {
|
} catch (BeanCreationException e) {
|
||||||
fail("Unexpected BeanCreationException for https issuer with forceHttps=true, message:" + e.getMessage());
|
fail("Unexpected BeanCreationException for https issuer with forceHttps=true, message:" + e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -263,7 +263,7 @@ public class DiscoveryEndpoint {
|
||||||
Collection<JWSAlgorithm> serverSigningAlgs = signService.getAllSigningAlgsSupported();
|
Collection<JWSAlgorithm> serverSigningAlgs = signService.getAllSigningAlgsSupported();
|
||||||
Collection<JWSAlgorithm> clientSymmetricSigningAlgs = Lists.newArrayList(JWSAlgorithm.HS256, JWSAlgorithm.HS384, JWSAlgorithm.HS512);
|
Collection<JWSAlgorithm> clientSymmetricSigningAlgs = Lists.newArrayList(JWSAlgorithm.HS256, JWSAlgorithm.HS384, JWSAlgorithm.HS512);
|
||||||
Collection<JWSAlgorithm> clientSymmetricAndAsymmetricSigningAlgs = Lists.newArrayList(JWSAlgorithm.HS256, JWSAlgorithm.HS384, JWSAlgorithm.HS512, JWSAlgorithm.RS256, JWSAlgorithm.RS384, JWSAlgorithm.RS512);
|
Collection<JWSAlgorithm> clientSymmetricAndAsymmetricSigningAlgs = Lists.newArrayList(JWSAlgorithm.HS256, JWSAlgorithm.HS384, JWSAlgorithm.HS512, JWSAlgorithm.RS256, JWSAlgorithm.RS384, JWSAlgorithm.RS512);
|
||||||
Collection<Algorithm> clientSymmetricAndAsymmetricSigningAlgsWithNone = Lists.newArrayList(JWSAlgorithm.HS256, JWSAlgorithm.HS384, JWSAlgorithm.HS512, JWSAlgorithm.RS256, JWSAlgorithm.RS384, JWSAlgorithm.RS512, JWSAlgorithm.NONE);
|
Collection<Algorithm> clientSymmetricAndAsymmetricSigningAlgsWithNone = Lists.newArrayList(JWSAlgorithm.HS256, JWSAlgorithm.HS384, JWSAlgorithm.HS512, JWSAlgorithm.RS256, JWSAlgorithm.RS384, JWSAlgorithm.RS512, Algorithm.NONE);
|
||||||
|
|
||||||
Map<String, Object> m = new HashMap<String, Object>();
|
Map<String, Object> m = new HashMap<String, Object>();
|
||||||
m.put("issuer", config.getIssuer());
|
m.put("issuer", config.getIssuer());
|
||||||
|
|
|
@ -37,13 +37,13 @@ public class JpaAuthenticationHolderRepository implements AuthenticationHolderRe
|
||||||
|
|
||||||
@PersistenceContext
|
@PersistenceContext
|
||||||
private EntityManager manager;
|
private EntityManager manager;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<AuthenticationHolderEntity> getAll() {
|
public List<AuthenticationHolderEntity> getAll() {
|
||||||
TypedQuery<AuthenticationHolderEntity> query = manager.createNamedQuery("AuthenticationHolderEntity.getAll", AuthenticationHolderEntity.class);
|
TypedQuery<AuthenticationHolderEntity> query = manager.createNamedQuery("AuthenticationHolderEntity.getAll", AuthenticationHolderEntity.class);
|
||||||
return query.getResultList();
|
return query.getResultList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AuthenticationHolderEntity getById(Long id) {
|
public AuthenticationHolderEntity getById(Long id) {
|
||||||
return manager.find(AuthenticationHolderEntity.class, id);
|
return manager.find(AuthenticationHolderEntity.class, id);
|
||||||
|
|
|
@ -36,7 +36,7 @@ public class BlacklistAwareRedirectResolver extends DefaultRedirectResolver {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private BlacklistedSiteService blacklistService;
|
private BlacklistedSiteService blacklistService;
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.springframework.security.oauth2.provider.endpoint.RedirectResolver#resolveRedirect(java.lang.String, org.springframework.security.oauth2.provider.ClientDetails)
|
* @see org.springframework.security.oauth2.provider.endpoint.RedirectResolver#resolveRedirect(java.lang.String, org.springframework.security.oauth2.provider.ClientDetails)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -42,77 +42,77 @@ import com.google.common.base.Joiner;
|
||||||
public class DefaultIntrospectionResultAssembler implements IntrospectionResultAssembler {
|
public class DefaultIntrospectionResultAssembler implements IntrospectionResultAssembler {
|
||||||
|
|
||||||
private static Logger log = LoggerFactory.getLogger(DefaultIntrospectionResultAssembler.class);
|
private static Logger log = LoggerFactory.getLogger(DefaultIntrospectionResultAssembler.class);
|
||||||
|
|
||||||
private static DateFormatter dateFormat = new DateFormatter(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"));
|
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();
|
@Override
|
||||||
OAuth2Authentication authentication = accessToken.getAuthenticationHolder().getAuthentication();
|
public Map<String, Object> assembleFrom(OAuth2AccessTokenEntity accessToken, UserInfo userInfo) {
|
||||||
|
|
||||||
result.put("active", true);
|
Map<String, Object> result = newLinkedHashMap();
|
||||||
|
OAuth2Authentication authentication = accessToken.getAuthenticationHolder().getAuthentication();
|
||||||
|
|
||||||
result.put("scope", Joiner.on(" ").join(accessToken.getScope()));
|
result.put("active", true);
|
||||||
|
|
||||||
if (accessToken.getExpiration() != null) {
|
result.put("scope", Joiner.on(" ").join(accessToken.getScope()));
|
||||||
try {
|
|
||||||
|
if (accessToken.getExpiration() != null) {
|
||||||
|
try {
|
||||||
result.put("expires_at", dateFormat.valueToString(accessToken.getExpiration()));
|
result.put("expires_at", dateFormat.valueToString(accessToken.getExpiration()));
|
||||||
result.put("exp", accessToken.getExpiration().getTime() / 1000L);
|
result.put("exp", accessToken.getExpiration().getTime() / 1000L);
|
||||||
} catch (ParseException e) {
|
} catch (ParseException e) {
|
||||||
log.error("Parse exception in token introspection", e);
|
log.error("Parse exception in token introspection", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (userInfo != null) {
|
if (userInfo != null) {
|
||||||
// if we have a UserInfo, use that for the subject
|
// if we have a UserInfo, use that for the subject
|
||||||
result.put("sub", userInfo.getSub());
|
result.put("sub", userInfo.getSub());
|
||||||
} else {
|
} else {
|
||||||
// otherwise, use the authentication's username
|
// 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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Object> assembleFrom(OAuth2RefreshTokenEntity refreshToken, UserInfo userInfo) {
|
public Map<String, Object> assembleFrom(OAuth2RefreshTokenEntity refreshToken, UserInfo userInfo) {
|
||||||
|
|
||||||
Map<String, Object> result = newLinkedHashMap();
|
Map<String, Object> result = newLinkedHashMap();
|
||||||
OAuth2Authentication authentication = refreshToken.getAuthenticationHolder().getAuthentication();
|
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(" ").join(authentication.getOAuth2Request().getScope()));
|
||||||
|
|
||||||
if (refreshToken.getExpiration() != null) {
|
if (refreshToken.getExpiration() != null) {
|
||||||
try {
|
try {
|
||||||
result.put("expires_at", dateFormat.valueToString(refreshToken.getExpiration()));
|
result.put("expires_at", dateFormat.valueToString(refreshToken.getExpiration()));
|
||||||
result.put("exp", refreshToken.getExpiration().getTime() / 1000L);
|
result.put("exp", refreshToken.getExpiration().getTime() / 1000L);
|
||||||
} catch (ParseException e) {
|
} catch (ParseException e) {
|
||||||
log.error("Parse exception in token introspection", e);
|
log.error("Parse exception in token introspection", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (userInfo != null) {
|
if (userInfo != null) {
|
||||||
// if we have a UserInfo, use that for the subject
|
// if we have a UserInfo, use that for the subject
|
||||||
result.put("sub", userInfo.getSub());
|
result.put("sub", userInfo.getSub());
|
||||||
} else {
|
} else {
|
||||||
// otherwise, use the authentication's username
|
// 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;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,6 @@ import com.google.common.base.Strings;
|
||||||
import com.google.common.cache.CacheBuilder;
|
import com.google.common.cache.CacheBuilder;
|
||||||
import com.google.common.cache.CacheLoader;
|
import com.google.common.cache.CacheLoader;
|
||||||
import com.google.common.cache.LoadingCache;
|
import com.google.common.cache.LoadingCache;
|
||||||
import com.google.common.util.concurrent.UncheckedExecutionException;
|
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonParser;
|
import com.google.gson.JsonParser;
|
||||||
|
|
||||||
|
@ -149,7 +148,7 @@ public class DefaultOAuth2ClientDetailsEntityService implements ClientDetailsEnt
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ensureRefreshTokenConsistency(ClientDetailsEntity client) {
|
private void ensureRefreshTokenConsistency(ClientDetailsEntity client) {
|
||||||
if (client.getAuthorizedGrantTypes().contains("refresh_token")
|
if (client.getAuthorizedGrantTypes().contains("refresh_token")
|
||||||
|| client.getScope().contains(SystemScopeService.OFFLINE_ACCESS)) {
|
|| client.getScope().contains(SystemScopeService.OFFLINE_ACCESS)) {
|
||||||
client.getScope().add(SystemScopeService.OFFLINE_ACCESS);
|
client.getScope().add(SystemScopeService.OFFLINE_ACCESS);
|
||||||
client.getAuthorizedGrantTypes().add("refresh_token");
|
client.getAuthorizedGrantTypes().add("refresh_token");
|
||||||
|
@ -239,7 +238,7 @@ public class DefaultOAuth2ClientDetailsEntityService implements ClientDetailsEnt
|
||||||
|
|
||||||
// if the client is flagged to allow for refresh tokens, make sure it's got the right scope
|
// if the client is flagged to allow for refresh tokens, make sure it's got the right scope
|
||||||
ensureRefreshTokenConsistency(newClient);
|
ensureRefreshTokenConsistency(newClient);
|
||||||
|
|
||||||
// check the sector URI
|
// check the sector URI
|
||||||
checkSectorIdentifierUri(newClient);
|
checkSectorIdentifierUri(newClient);
|
||||||
|
|
||||||
|
|
|
@ -194,7 +194,7 @@ public class DefaultOAuth2ProviderTokenService implements OAuth2TokenEntityServi
|
||||||
|
|
||||||
token.setRefreshToken(savedRefreshToken);
|
token.setRefreshToken(savedRefreshToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
OAuth2AccessTokenEntity enhancedToken = (OAuth2AccessTokenEntity) tokenEnhancer.enhance(token, authentication);
|
OAuth2AccessTokenEntity enhancedToken = (OAuth2AccessTokenEntity) tokenEnhancer.enhance(token, authentication);
|
||||||
|
|
||||||
OAuth2AccessTokenEntity savedToken = tokenRepository.saveAccessToken(enhancedToken);
|
OAuth2AccessTokenEntity savedToken = tokenRepository.saveAccessToken(enhancedToken);
|
||||||
|
@ -235,14 +235,14 @@ public class DefaultOAuth2ProviderTokenService implements OAuth2TokenEntityServi
|
||||||
ClientDetailsEntity client = refreshToken.getClient();
|
ClientDetailsEntity client = refreshToken.getClient();
|
||||||
|
|
||||||
AuthenticationHolderEntity authHolder = refreshToken.getAuthenticationHolder();
|
AuthenticationHolderEntity authHolder = refreshToken.getAuthenticationHolder();
|
||||||
|
|
||||||
// make sure that the client requesting the token is the one who owns the refresh token
|
// make sure that the client requesting the token is the one who owns the refresh token
|
||||||
ClientDetailsEntity requestingClient = clientDetailsService.loadClientByClientId(authRequest.getClientId());
|
ClientDetailsEntity requestingClient = clientDetailsService.loadClientByClientId(authRequest.getClientId());
|
||||||
if (!client.getClientId().equals(requestingClient.getClientId())) {
|
if (!client.getClientId().equals(requestingClient.getClientId())) {
|
||||||
tokenRepository.removeRefreshToken(refreshToken);
|
tokenRepository.removeRefreshToken(refreshToken);
|
||||||
throw new InvalidClientException("Client does not own the presented refresh token");
|
throw new InvalidClientException("Client does not own the presented refresh token");
|
||||||
}
|
}
|
||||||
|
|
||||||
//Make sure this client allows access token refreshing
|
//Make sure this client allows access token refreshing
|
||||||
if (!client.isAllowRefresh()) {
|
if (!client.isAllowRefresh()) {
|
||||||
throw new InvalidClientException("Client does not allow refreshing access token!");
|
throw new InvalidClientException("Client does not allow refreshing access token!");
|
||||||
|
@ -483,18 +483,18 @@ public class DefaultOAuth2ProviderTokenService implements OAuth2TokenEntityServi
|
||||||
@Override
|
@Override
|
||||||
public OAuth2AccessTokenEntity getRegistrationAccessTokenForClient(ClientDetailsEntity client) {
|
public OAuth2AccessTokenEntity getRegistrationAccessTokenForClient(ClientDetailsEntity client) {
|
||||||
List<OAuth2AccessTokenEntity> allTokens = getAccessTokensForClient(client);
|
List<OAuth2AccessTokenEntity> allTokens = getAccessTokensForClient(client);
|
||||||
|
|
||||||
for (OAuth2AccessTokenEntity token : allTokens) {
|
for (OAuth2AccessTokenEntity token : allTokens) {
|
||||||
if ((token.getScope().contains(SystemScopeService.REGISTRATION_TOKEN_SCOPE) || token.getScope().contains(SystemScopeService.RESOURCE_TOKEN_SCOPE))
|
if ((token.getScope().contains(SystemScopeService.REGISTRATION_TOKEN_SCOPE) || token.getScope().contains(SystemScopeService.RESOURCE_TOKEN_SCOPE))
|
||||||
&& token.getScope().size() == 1) {
|
&& token.getScope().size() == 1) {
|
||||||
// if it only has the registration scope, then it's a registration token
|
// if it only has the registration scope, then it's a registration token
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,8 +16,10 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.mitre.oauth2.web;
|
package org.mitre.oauth2.web;
|
||||||
|
|
||||||
import com.google.common.base.Strings;
|
import java.security.Principal;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.mitre.oauth2.model.ClientDetailsEntity;
|
import org.mitre.oauth2.model.ClientDetailsEntity;
|
||||||
import org.mitre.oauth2.model.OAuth2AccessTokenEntity;
|
import org.mitre.oauth2.model.OAuth2AccessTokenEntity;
|
||||||
import org.mitre.oauth2.model.OAuth2RefreshTokenEntity;
|
import org.mitre.oauth2.model.OAuth2RefreshTokenEntity;
|
||||||
|
@ -40,9 +42,8 @@ import org.springframework.ui.Model;
|
||||||
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 java.security.Principal;
|
import com.google.common.base.Strings;
|
||||||
import java.util.Map;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
public class IntrospectionEndpoint {
|
public class IntrospectionEndpoint {
|
||||||
|
@ -56,8 +57,8 @@ public class IntrospectionEndpoint {
|
||||||
@Autowired
|
@Autowired
|
||||||
private IntrospectionAuthorizer introspectionAuthorizer;
|
private IntrospectionAuthorizer introspectionAuthorizer;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private IntrospectionResultAssembler introspectionResultAssembler;
|
private IntrospectionResultAssembler introspectionResultAssembler;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private UserInfoService userInfoService;
|
private UserInfoService userInfoService;
|
||||||
|
@ -86,8 +87,8 @@ public class IntrospectionEndpoint {
|
||||||
return JsonEntityView.VIEWNAME;
|
return JsonEntityView.VIEWNAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
OAuth2AccessTokenEntity accessToken = null;
|
OAuth2AccessTokenEntity accessToken = null;
|
||||||
OAuth2RefreshTokenEntity refreshToken = null;
|
OAuth2RefreshTokenEntity refreshToken = null;
|
||||||
ClientDetailsEntity tokenClient;
|
ClientDetailsEntity tokenClient;
|
||||||
Set<String> scopes;
|
Set<String> scopes;
|
||||||
UserInfo user;
|
UserInfo user;
|
||||||
|
@ -100,7 +101,7 @@ public class IntrospectionEndpoint {
|
||||||
tokenClient = accessToken.getClient();
|
tokenClient = accessToken.getClient();
|
||||||
scopes = accessToken.getScope();
|
scopes = accessToken.getScope();
|
||||||
|
|
||||||
user = userInfoService.getByUsernameAndClientId(accessToken.getAuthenticationHolder().getAuthentication().getName(), tokenClient.getClientId());
|
user = userInfoService.getByUsernameAndClientId(accessToken.getAuthenticationHolder().getAuthentication().getName(), tokenClient.getClientId());
|
||||||
|
|
||||||
} catch (InvalidTokenException e) {
|
} catch (InvalidTokenException e) {
|
||||||
logger.info("Verify failed; Invalid access token. Checking refresh token.");
|
logger.info("Verify failed; Invalid access token. Checking refresh token.");
|
||||||
|
@ -122,28 +123,28 @@ public class IntrospectionEndpoint {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// clientID is the principal name in the authentication
|
// clientID is the principal name in the authentication
|
||||||
String clientId = p.getName();
|
String clientId = p.getName();
|
||||||
ClientDetailsEntity authClient = clientService.loadClientByClientId(clientId);
|
ClientDetailsEntity authClient = clientService.loadClientByClientId(clientId);
|
||||||
|
|
||||||
if (authClient.isAllowIntrospection()) {
|
if (authClient.isAllowIntrospection()) {
|
||||||
if (introspectionAuthorizer.isIntrospectionPermitted(authClient, tokenClient, scopes)) {
|
if (introspectionAuthorizer.isIntrospectionPermitted(authClient, tokenClient, scopes)) {
|
||||||
// if it's a valid token, we'll print out information on it
|
// if it's a valid token, we'll print out information on it
|
||||||
Map<String, Object> entity = accessToken != null
|
Map<String, Object> entity = accessToken != null
|
||||||
? introspectionResultAssembler.assembleFrom(accessToken, user)
|
? introspectionResultAssembler.assembleFrom(accessToken, user)
|
||||||
: introspectionResultAssembler.assembleFrom(refreshToken, user);
|
: introspectionResultAssembler.assembleFrom(refreshToken, user);
|
||||||
model.addAttribute("entity", entity);
|
model.addAttribute("entity", entity);
|
||||||
return JsonEntityView.VIEWNAME;
|
return JsonEntityView.VIEWNAME;
|
||||||
} else {
|
} else {
|
||||||
logger.error("Verify failed; client configuration or scope don't permit token introspection");
|
logger.error("Verify failed; client configuration or scope don't permit token introspection");
|
||||||
model.addAttribute("code", HttpStatus.FORBIDDEN);
|
model.addAttribute("code", HttpStatus.FORBIDDEN);
|
||||||
return HttpCodeView.VIEWNAME;
|
return HttpCodeView.VIEWNAME;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
logger.error("Verify failed; client " + clientId + " is not allowed to call introspection endpoint");
|
logger.error("Verify failed; client " + clientId + " is not allowed to call introspection endpoint");
|
||||||
model.addAttribute("code", HttpStatus.FORBIDDEN);
|
model.addAttribute("code", HttpStatus.FORBIDDEN);
|
||||||
return HttpCodeView.VIEWNAME;
|
return HttpCodeView.VIEWNAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -102,7 +102,7 @@ public class OAuthConfirmationController {
|
||||||
model.put("code", HttpStatus.FORBIDDEN);
|
model.put("code", HttpStatus.FORBIDDEN);
|
||||||
return HttpCodeView.VIEWNAME;
|
return HttpCodeView.VIEWNAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prompts.contains("consent")) {
|
if (prompts.contains("consent")) {
|
||||||
model.put("consent", true);
|
model.put("consent", true);
|
||||||
}
|
}
|
||||||
|
@ -160,10 +160,10 @@ public class OAuthConfirmationController {
|
||||||
Map<String, Map<String, String>> claimsForScopes = new HashMap<String, Map<String, String>>();
|
Map<String, Map<String, String>> claimsForScopes = new HashMap<String, Map<String, String>>();
|
||||||
if (user != null) {
|
if (user != null) {
|
||||||
JsonObject userJson = user.toJson();
|
JsonObject userJson = user.toJson();
|
||||||
|
|
||||||
for (SystemScope systemScope : sortedScopes) {
|
for (SystemScope systemScope : sortedScopes) {
|
||||||
Map<String, String> claimValues = new HashMap<String, String>();
|
Map<String, String> claimValues = new HashMap<String, String>();
|
||||||
|
|
||||||
Set<String> claims = scopeClaimTranslationService.getClaimsForScope(systemScope.getValue());
|
Set<String> claims = scopeClaimTranslationService.getClaimsForScope(systemScope.getValue());
|
||||||
for (String claim : claims) {
|
for (String claim : claims) {
|
||||||
if (userJson.has(claim) && userJson.get(claim).isJsonPrimitive()) {
|
if (userJson.has(claim) && userJson.get(claim).isJsonPrimitive()) {
|
||||||
|
@ -171,7 +171,7 @@ public class OAuthConfirmationController {
|
||||||
claimValues.put(claim, userJson.get(claim).getAsString());
|
claimValues.put(claim, userJson.get(claim).getAsString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
claimsForScopes.put(systemScope.getValue(), claimValues);
|
claimsForScopes.put(systemScope.getValue(), claimValues);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,10 +52,10 @@ public class TokenAPI {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private OAuth2TokenEntityService tokenService;
|
private OAuth2TokenEntityService tokenService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ClientDetailsEntityService clientService;
|
private ClientDetailsEntityService clientService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private OIDCTokenService oidcTokenService;
|
private OIDCTokenService oidcTokenService;
|
||||||
|
|
||||||
|
@ -115,9 +115,9 @@ public class TokenAPI {
|
||||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||||
@RequestMapping(value = "/client/{clientId}", method = RequestMethod.GET, produces = "application/json")
|
@RequestMapping(value = "/client/{clientId}", method = RequestMethod.GET, produces = "application/json")
|
||||||
public String getAccessTokensByClientId(@PathVariable("clientId") String clientId, ModelMap m, Principal p) {
|
public String getAccessTokensByClientId(@PathVariable("clientId") String clientId, ModelMap m, Principal p) {
|
||||||
|
|
||||||
ClientDetailsEntity client = clientService.loadClientByClientId(clientId);
|
ClientDetailsEntity client = clientService.loadClientByClientId(clientId);
|
||||||
|
|
||||||
if (client != null) {
|
if (client != null) {
|
||||||
List<OAuth2AccessTokenEntity> tokens = tokenService.getAccessTokensForClient(client);
|
List<OAuth2AccessTokenEntity> tokens = tokenService.getAccessTokensForClient(client);
|
||||||
m.put("entity", tokens);
|
m.put("entity", tokens);
|
||||||
|
@ -128,15 +128,15 @@ public class TokenAPI {
|
||||||
m.put("errorMessage", "The requested client with id " + clientId + " could not be found.");
|
m.put("errorMessage", "The requested client with id " + clientId + " could not be found.");
|
||||||
return JsonErrorView.VIEWNAME;
|
return JsonErrorView.VIEWNAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||||
@RequestMapping(value = "/registration/{clientId}", method = RequestMethod.GET, produces = "application/json")
|
@RequestMapping(value = "/registration/{clientId}", method = RequestMethod.GET, produces = "application/json")
|
||||||
public String getRegistrationTokenByClientId(@PathVariable("clientId") String clientId, ModelMap m, Principal p) {
|
public String getRegistrationTokenByClientId(@PathVariable("clientId") String clientId, ModelMap m, Principal p) {
|
||||||
|
|
||||||
ClientDetailsEntity client = clientService.loadClientByClientId(clientId);
|
ClientDetailsEntity client = clientService.loadClientByClientId(clientId);
|
||||||
|
|
||||||
if (client != null) {
|
if (client != null) {
|
||||||
OAuth2AccessTokenEntity token = tokenService.getRegistrationAccessTokenForClient(client);
|
OAuth2AccessTokenEntity token = tokenService.getRegistrationAccessTokenForClient(client);
|
||||||
if (token != null) {
|
if (token != null) {
|
||||||
|
@ -153,18 +153,18 @@ public class TokenAPI {
|
||||||
m.put("errorMessage", "The requested client with id " + clientId + " could not be found.");
|
m.put("errorMessage", "The requested client with id " + clientId + " could not be found.");
|
||||||
return JsonErrorView.VIEWNAME;
|
return JsonErrorView.VIEWNAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||||
@RequestMapping(value = "/registration/{clientId}", method = RequestMethod.PUT, produces = "application/json")
|
@RequestMapping(value = "/registration/{clientId}", method = RequestMethod.PUT, produces = "application/json")
|
||||||
public String rotateRegistrationTokenByClientId(@PathVariable("clientId") String clientId, ModelMap m, Principal p) {
|
public String rotateRegistrationTokenByClientId(@PathVariable("clientId") String clientId, ModelMap m, Principal p) {
|
||||||
ClientDetailsEntity client = clientService.loadClientByClientId(clientId);
|
ClientDetailsEntity client = clientService.loadClientByClientId(clientId);
|
||||||
|
|
||||||
if (client != null) {
|
if (client != null) {
|
||||||
OAuth2AccessTokenEntity token = oidcTokenService.rotateRegistrationAccessTokenForClient(client);
|
OAuth2AccessTokenEntity token = oidcTokenService.rotateRegistrationAccessTokenForClient(client);
|
||||||
token = tokenService.saveAccessToken(token);
|
token = tokenService.saveAccessToken(token);
|
||||||
|
|
||||||
if (token != null) {
|
if (token != null) {
|
||||||
m.put("entity", token);
|
m.put("entity", token);
|
||||||
return TokenApiView.VIEWNAME;
|
return TokenApiView.VIEWNAME;
|
||||||
|
@ -179,9 +179,9 @@ public class TokenAPI {
|
||||||
m.put("errorMessage", "The requested client with id " + clientId + " could not be found.");
|
m.put("errorMessage", "The requested client with id " + clientId + " could not be found.");
|
||||||
return JsonErrorView.VIEWNAME;
|
return JsonErrorView.VIEWNAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(value = "/refresh", method = RequestMethod.GET, produces = "application/json")
|
@RequestMapping(value = "/refresh", method = RequestMethod.GET, produces = "application/json")
|
||||||
public String getAllRefreshTokens(ModelMap m, Principal p) {
|
public String getAllRefreshTokens(ModelMap m, Principal p) {
|
||||||
|
|
||||||
|
|
|
@ -120,12 +120,12 @@ public class ConnectOAuth2RequestFactory extends DefaultOAuth2RequestFactory {
|
||||||
if (inputParams.containsKey("login_hint")) {
|
if (inputParams.containsKey("login_hint")) {
|
||||||
request.getExtensions().put("login_hint", inputParams.get("login_hint"));
|
request.getExtensions().put("login_hint", inputParams.get("login_hint"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inputParams.containsKey("request")) {
|
if (inputParams.containsKey("request")) {
|
||||||
request.getExtensions().put("request", inputParams.get("request"));
|
request.getExtensions().put("request", inputParams.get("request"));
|
||||||
processRequestObject(inputParams.get("request"), request);
|
processRequestObject(inputParams.get("request"), request);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (request.getClientId() != null) {
|
if (request.getClientId() != null) {
|
||||||
try {
|
try {
|
||||||
ClientDetailsEntity client = clientDetailsService.loadClientByClientId(request.getClientId());
|
ClientDetailsEntity client = clientDetailsService.loadClientByClientId(request.getClientId());
|
||||||
|
@ -352,7 +352,7 @@ public class ConnectOAuth2RequestFactory extends DefaultOAuth2RequestFactory {
|
||||||
// we save the string because the object might not be a Java Serializable, and we can parse it easily enough anyway
|
// 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 != null) {
|
||||||
if (!loginHint.equals(request.getExtensions().get("login_hint"))) {
|
if (!loginHint.equals(request.getExtensions().get("login_hint"))) {
|
||||||
|
|
|
@ -57,7 +57,7 @@ public class JwtBearerAuthenticationProvider implements AuthenticationProvider {
|
||||||
private static final Logger logger = LoggerFactory.getLogger(JwtBearerAuthenticationProvider.class);
|
private static final Logger logger = LoggerFactory.getLogger(JwtBearerAuthenticationProvider.class);
|
||||||
|
|
||||||
private static final GrantedAuthority ROLE_CLIENT = new SimpleGrantedAuthority("ROLE_CLIENT");
|
private static final GrantedAuthority ROLE_CLIENT = new SimpleGrantedAuthority("ROLE_CLIENT");
|
||||||
|
|
||||||
// map of verifiers, load keys for clients
|
// map of verifiers, load keys for clients
|
||||||
@Autowired
|
@Autowired
|
||||||
private JWKSetCacheService validators;
|
private JWKSetCacheService validators;
|
||||||
|
@ -107,10 +107,10 @@ public class JwtBearerAuthenticationProvider implements AuthenticationProvider {
|
||||||
client.getTokenEndpointAuthMethod().equals(AuthMethod.NONE) ||
|
client.getTokenEndpointAuthMethod().equals(AuthMethod.NONE) ||
|
||||||
client.getTokenEndpointAuthMethod().equals(AuthMethod.SECRET_BASIC) ||
|
client.getTokenEndpointAuthMethod().equals(AuthMethod.SECRET_BASIC) ||
|
||||||
client.getTokenEndpointAuthMethod().equals(AuthMethod.SECRET_POST)) {
|
client.getTokenEndpointAuthMethod().equals(AuthMethod.SECRET_POST)) {
|
||||||
|
|
||||||
// this client doesn't support this type of authentication
|
// this client doesn't support this type of authentication
|
||||||
throw new AuthenticationServiceException("Client does not support this authentication method.");
|
throw new AuthenticationServiceException("Client does not support this authentication method.");
|
||||||
|
|
||||||
} else if (client.getTokenEndpointAuthMethod().equals(AuthMethod.PRIVATE_KEY) &&
|
} else if (client.getTokenEndpointAuthMethod().equals(AuthMethod.PRIVATE_KEY) &&
|
||||||
(alg.equals(JWSAlgorithm.RS256)
|
(alg.equals(JWSAlgorithm.RS256)
|
||||||
|| alg.equals(JWSAlgorithm.RS384)
|
|| alg.equals(JWSAlgorithm.RS384)
|
||||||
|
@ -188,11 +188,11 @@ public class JwtBearerAuthenticationProvider implements AuthenticationProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
// IFF we managed to get all the way down here, the token is valid
|
// IFF we managed to get all the way down here, the token is valid
|
||||||
|
|
||||||
// add in the ROLE_CLIENT authority
|
// add in the ROLE_CLIENT authority
|
||||||
Set<GrantedAuthority> authorities = new HashSet<>(client.getAuthorities());
|
Set<GrantedAuthority> authorities = new HashSet<>(client.getAuthorities());
|
||||||
authorities.add(ROLE_CLIENT);
|
authorities.add(ROLE_CLIENT);
|
||||||
|
|
||||||
return new JwtBearerAssertionAuthenticationToken(client.getClientId(), jwt, authorities);
|
return new JwtBearerAssertionAuthenticationToken(client.getClientId(), jwt, authorities);
|
||||||
|
|
||||||
} catch (InvalidClientException e) {
|
} catch (InvalidClientException e) {
|
||||||
|
|
|
@ -54,7 +54,7 @@ public class ValidationException extends Exception {
|
||||||
public void setStatus(HttpStatus status) {
|
public void setStatus(HttpStatus status) {
|
||||||
this.status = status;
|
this.status = status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "ValidationException [error=" + error + ", errorDescription="
|
return "ValidationException [error=" + error + ", errorDescription="
|
||||||
|
|
|
@ -97,15 +97,15 @@ public class AuthorizationRequestFilter extends GenericFilterBean {
|
||||||
// no need to worry about this here, it would be caught elsewhere
|
// no need to worry about this here, it would be caught elsewhere
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// save the login hint to the session
|
// save the login hint to the session
|
||||||
if (authRequest.getExtensions().get("login_hint") != null) {
|
if (authRequest.getExtensions().get("login_hint") != null) {
|
||||||
session.setAttribute("login_hint", authRequest.getExtensions().get("login_hint"));
|
session.setAttribute("login_hint", authRequest.getExtensions().get("login_hint"));
|
||||||
} else {
|
} 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
|
// we have a "prompt" parameter
|
||||||
String prompt = (String)authRequest.getExtensions().get("prompt");
|
String prompt = (String)authRequest.getExtensions().get("prompt");
|
||||||
|
|
|
@ -19,8 +19,6 @@ package org.mitre.openid.connect.repository.impl;
|
||||||
import static org.mitre.util.jpa.JpaUtil.getSingleResult;
|
import static org.mitre.util.jpa.JpaUtil.getSingleResult;
|
||||||
import static org.mitre.util.jpa.JpaUtil.saveOrUpdate;
|
import static org.mitre.util.jpa.JpaUtil.saveOrUpdate;
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
import javax.persistence.EntityManager;
|
import javax.persistence.EntityManager;
|
||||||
import javax.persistence.PersistenceContext;
|
import javax.persistence.PersistenceContext;
|
||||||
import javax.persistence.TypedQuery;
|
import javax.persistence.TypedQuery;
|
||||||
|
|
|
@ -84,7 +84,7 @@ public class DefaultOIDCTokenService implements OIDCTokenService {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private SymmetricCacheService symmetricCacheService;
|
private SymmetricCacheService symmetricCacheService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private OAuth2TokenEntityService tokenService;
|
private OAuth2TokenEntityService tokenService;
|
||||||
|
|
||||||
|
@ -156,17 +156,17 @@ public class DefaultOIDCTokenService implements OIDCTokenService {
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
JWT idToken;
|
JWT idToken;
|
||||||
|
|
||||||
if (signingAlg.equals(JWSAlgorithm.NONE)) {
|
if (signingAlg.equals(Algorithm.NONE)) {
|
||||||
// unsigned ID token
|
// unsigned ID token
|
||||||
idToken = new PlainJWT(idClaims);
|
idToken = new PlainJWT(idClaims);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// signed ID token
|
// signed ID token
|
||||||
|
|
||||||
if (signingAlg.equals(JWSAlgorithm.HS256)
|
if (signingAlg.equals(JWSAlgorithm.HS256)
|
||||||
|| signingAlg.equals(JWSAlgorithm.HS384)
|
|| signingAlg.equals(JWSAlgorithm.HS384)
|
||||||
|| signingAlg.equals(JWSAlgorithm.HS512)) {
|
|| signingAlg.equals(JWSAlgorithm.HS512)) {
|
||||||
|
@ -174,19 +174,19 @@ public class DefaultOIDCTokenService implements OIDCTokenService {
|
||||||
idToken = new SignedJWT(new JWSHeader(signingAlg), idClaims);
|
idToken = new SignedJWT(new JWSHeader(signingAlg), idClaims);
|
||||||
|
|
||||||
JwtSigningAndValidationService signer = symmetricCacheService.getSymmetricValidtor(client);
|
JwtSigningAndValidationService signer = symmetricCacheService.getSymmetricValidtor(client);
|
||||||
|
|
||||||
// sign it with the client's secret
|
// sign it with the client's secret
|
||||||
signer.signJwt((SignedJWT) idToken);
|
signer.signJwt((SignedJWT) idToken);
|
||||||
} else {
|
} else {
|
||||||
idClaims.setCustomClaim("kid", jwtService.getDefaultSignerKeyId());
|
idClaims.setCustomClaim("kid", jwtService.getDefaultSignerKeyId());
|
||||||
|
|
||||||
idToken = new SignedJWT(new JWSHeader(signingAlg), idClaims);
|
idToken = new SignedJWT(new JWSHeader(signingAlg), idClaims);
|
||||||
|
|
||||||
// sign it with the server's key
|
// sign it with the server's key
|
||||||
jwtService.signJwt((SignedJWT) idToken);
|
jwtService.signJwt((SignedJWT) idToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
idTokenEntity.setJwt(idToken);
|
idTokenEntity.setJwt(idToken);
|
||||||
}
|
}
|
||||||
|
@ -212,9 +212,9 @@ public class DefaultOIDCTokenService implements OIDCTokenService {
|
||||||
public OAuth2AccessTokenEntity createRegistrationAccessToken(ClientDetailsEntity client) {
|
public OAuth2AccessTokenEntity createRegistrationAccessToken(ClientDetailsEntity client) {
|
||||||
|
|
||||||
return createAssociatedToken(client, Sets.newHashSet(SystemScopeService.REGISTRATION_TOKEN_SCOPE));
|
return createAssociatedToken(client, Sets.newHashSet(SystemScopeService.REGISTRATION_TOKEN_SCOPE));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param client
|
* @param client
|
||||||
* @return
|
* @return
|
||||||
|
@ -223,7 +223,7 @@ public class DefaultOIDCTokenService implements OIDCTokenService {
|
||||||
public OAuth2AccessTokenEntity createResourceAccessToken(ClientDetailsEntity client) {
|
public OAuth2AccessTokenEntity createResourceAccessToken(ClientDetailsEntity client) {
|
||||||
|
|
||||||
return createAssociatedToken(client, Sets.newHashSet(SystemScopeService.RESOURCE_TOKEN_SCOPE));
|
return createAssociatedToken(client, Sets.newHashSet(SystemScopeService.RESOURCE_TOKEN_SCOPE));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -237,19 +237,19 @@ public class DefaultOIDCTokenService implements OIDCTokenService {
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private OAuth2AccessTokenEntity createAssociatedToken(ClientDetailsEntity client, Set<String> scope) {
|
private OAuth2AccessTokenEntity createAssociatedToken(ClientDetailsEntity client, Set<String> scope) {
|
||||||
|
|
||||||
// revoke any previous tokens that might exist, just to be sure
|
// revoke any previous tokens that might exist, just to be sure
|
||||||
OAuth2AccessTokenEntity oldToken = tokenService.getRegistrationAccessTokenForClient(client);
|
OAuth2AccessTokenEntity oldToken = tokenService.getRegistrationAccessTokenForClient(client);
|
||||||
if (oldToken != null) {
|
if (oldToken != null) {
|
||||||
tokenService.revokeAccessToken(oldToken);
|
tokenService.revokeAccessToken(oldToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a new token
|
// create a new token
|
||||||
|
|
||||||
Map<String, String> authorizationParameters = Maps.newHashMap();
|
Map<String, String> authorizationParameters = Maps.newHashMap();
|
||||||
OAuth2Request clientAuth = new OAuth2Request(authorizationParameters, client.getClientId(),
|
OAuth2Request clientAuth = new OAuth2Request(authorizationParameters, client.getClientId(),
|
||||||
Sets.newHashSet(new SimpleGrantedAuthority("ROLE_CLIENT")), true,
|
Sets.newHashSet(new SimpleGrantedAuthority("ROLE_CLIENT")), true,
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -16,9 +16,6 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.mitre.openid.connect.service.impl;
|
package org.mitre.openid.connect.service.impl;
|
||||||
|
|
||||||
import com.google.common.io.BaseEncoding;
|
|
||||||
import com.google.gson.stream.JsonReader;
|
|
||||||
import com.google.gson.stream.JsonWriter;
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -29,109 +26,114 @@ import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.mitre.openid.connect.service.MITREidDataService;
|
import org.mitre.openid.connect.service.MITREidDataService;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import com.google.common.io.BaseEncoding;
|
||||||
|
import com.google.gson.stream.JsonReader;
|
||||||
|
import com.google.gson.stream.JsonWriter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author arielak
|
* @author arielak
|
||||||
*/
|
*/
|
||||||
public abstract class MITREidDataService_1_X implements MITREidDataService {
|
public abstract class MITREidDataService_1_X implements MITREidDataService {
|
||||||
private static Logger logger = LoggerFactory.getLogger(MITREidDataService_1_X.class);
|
private static Logger logger = LoggerFactory.getLogger(MITREidDataService_1_X.class);
|
||||||
|
|
||||||
protected static <T> T base64UrlDecodeObject(String encoded, Class<T> type) {
|
protected static <T> T base64UrlDecodeObject(String encoded, Class<T> type) {
|
||||||
if (encoded == null) {
|
if (encoded == null) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
T deserialized = null;
|
T deserialized = null;
|
||||||
try {
|
try {
|
||||||
byte[] decoded = BaseEncoding.base64Url().decode(encoded);
|
byte[] decoded = BaseEncoding.base64Url().decode(encoded);
|
||||||
ByteArrayInputStream bais = new ByteArrayInputStream(decoded);
|
ByteArrayInputStream bais = new ByteArrayInputStream(decoded);
|
||||||
ObjectInputStream ois = new ObjectInputStream(bais);
|
ObjectInputStream ois = new ObjectInputStream(bais);
|
||||||
deserialized = type.cast(ois.readObject());
|
deserialized = type.cast(ois.readObject());
|
||||||
ois.close();
|
ois.close();
|
||||||
bais.close();
|
bais.close();
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
logger.error("Unable to decode object", ex);
|
logger.error("Unable to decode object", ex);
|
||||||
}
|
}
|
||||||
return deserialized;
|
return deserialized;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static String base64UrlEncodeObject(Serializable obj) {
|
protected static String base64UrlEncodeObject(Serializable obj) {
|
||||||
if (obj == null) {
|
if (obj == null) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
String encoded = null;
|
String encoded = null;
|
||||||
try {
|
try {
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
ObjectOutputStream oos = new ObjectOutputStream(baos);
|
ObjectOutputStream oos = new ObjectOutputStream(baos);
|
||||||
oos.writeObject(obj);
|
oos.writeObject(obj);
|
||||||
encoded = BaseEncoding.base64Url().encode(baos.toByteArray());
|
encoded = BaseEncoding.base64Url().encode(baos.toByteArray());
|
||||||
oos.close();
|
oos.close();
|
||||||
baos.close();
|
baos.close();
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
logger.error("Unable to encode object", ex);
|
logger.error("Unable to encode object", ex);
|
||||||
}
|
}
|
||||||
return encoded;
|
return encoded;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
protected static Set readSet(JsonReader reader) throws IOException {
|
protected static Set readSet(JsonReader reader) throws IOException {
|
||||||
Set arraySet = null;
|
Set arraySet = null;
|
||||||
reader.beginArray();
|
reader.beginArray();
|
||||||
switch (reader.peek()) {
|
switch (reader.peek()) {
|
||||||
case STRING:
|
case STRING:
|
||||||
arraySet = new HashSet<String>();
|
arraySet = new HashSet<String>();
|
||||||
while (reader.hasNext()) {
|
while (reader.hasNext()) {
|
||||||
arraySet.add(reader.nextString());
|
arraySet.add(reader.nextString());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NUMBER:
|
case NUMBER:
|
||||||
arraySet = new HashSet<Long>();
|
arraySet = new HashSet<Long>();
|
||||||
while (reader.hasNext()) {
|
while (reader.hasNext()) {
|
||||||
arraySet.add(reader.nextLong());
|
arraySet.add(reader.nextLong());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
arraySet = new HashSet();
|
arraySet = new HashSet();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
reader.endArray();
|
reader.endArray();
|
||||||
return arraySet;
|
return arraySet;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static Map readMap(JsonReader reader) throws IOException {
|
protected static Map readMap(JsonReader reader) throws IOException {
|
||||||
Map map = new HashMap<String, Object>();
|
Map map = new HashMap<String, Object>();
|
||||||
reader.beginObject();
|
reader.beginObject();
|
||||||
while(reader.hasNext()) {
|
while(reader.hasNext()) {
|
||||||
String name = reader.nextName();
|
String name = reader.nextName();
|
||||||
Object value = null;
|
Object value = null;
|
||||||
switch(reader.peek()) {
|
switch(reader.peek()) {
|
||||||
case STRING:
|
case STRING:
|
||||||
value = reader.nextString();
|
value = reader.nextString();
|
||||||
break;
|
break;
|
||||||
case BOOLEAN:
|
case BOOLEAN:
|
||||||
value = reader.nextBoolean();
|
value = reader.nextBoolean();
|
||||||
break;
|
break;
|
||||||
case NUMBER:
|
case NUMBER:
|
||||||
value = reader.nextLong();
|
value = reader.nextLong();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
map.put(name, value);
|
map.put(name, value);
|
||||||
}
|
}
|
||||||
reader.endObject();
|
reader.endObject();
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void writeNullSafeArray(JsonWriter writer, Set<String> items)
|
protected void writeNullSafeArray(JsonWriter writer, Set<String> items)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
if (items != null) {
|
if (items != null) {
|
||||||
writer.beginArray();
|
writer.beginArray();
|
||||||
for (String s : items) {
|
for (String s : items) {
|
||||||
writer.value(s);
|
writer.value(s);
|
||||||
}
|
}
|
||||||
writer.endArray();
|
writer.endArray();
|
||||||
} else {
|
} else {
|
||||||
writer.nullValue();
|
writer.nullValue();
|
||||||
}
|
}
|
||||||
|
|
|
@ -277,7 +277,7 @@ public class TofuUserApprovalHandler implements UserApprovalHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Object> getUserApprovalRequest(AuthorizationRequest authorizationRequest,
|
public Map<String, Object> getUserApprovalRequest(AuthorizationRequest authorizationRequest,
|
||||||
Authentication userAuthentication) {
|
Authentication userAuthentication) {
|
||||||
|
|
|
@ -20,6 +20,7 @@ import java.text.ParseException;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -28,29 +29,29 @@ import org.slf4j.LoggerFactory;
|
||||||
* @author arielak
|
* @author arielak
|
||||||
*/
|
*/
|
||||||
public class DateUtil {
|
public class DateUtil {
|
||||||
private static final Logger log = LoggerFactory.getLogger(DateUtil.class);
|
private static final Logger log = LoggerFactory.getLogger(DateUtil.class);
|
||||||
private static final String ISO_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";
|
private static final String ISO_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";
|
||||||
private static final SimpleDateFormat sdf = new SimpleDateFormat(ISO_FORMAT);
|
private static final SimpleDateFormat sdf = new SimpleDateFormat(ISO_FORMAT);
|
||||||
private static final TimeZone utc = TimeZone.getTimeZone("UTC");
|
private static final TimeZone utc = TimeZone.getTimeZone("UTC");
|
||||||
|
|
||||||
public static String toUTCString(Date date) {
|
|
||||||
if (date == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
sdf.setTimeZone(utc);
|
|
||||||
return sdf.format(date);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Date utcToDate(String s) {
|
public static String toUTCString(Date date) {
|
||||||
if (s == null) {
|
if (date == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Date d = null;
|
sdf.setTimeZone(utc);
|
||||||
try {
|
return sdf.format(date);
|
||||||
d = sdf.parse(s);
|
}
|
||||||
} catch(ParseException ex) {
|
|
||||||
log.error("Unable to parse date string {}", s, ex);
|
public static Date utcToDate(String s) {
|
||||||
}
|
if (s == null) {
|
||||||
return d;
|
return null;
|
||||||
}
|
}
|
||||||
|
Date d = null;
|
||||||
|
try {
|
||||||
|
d = sdf.parse(s);
|
||||||
|
} catch(ParseException ex) {
|
||||||
|
log.error("Unable to parse date string {}", s, ex);
|
||||||
|
}
|
||||||
|
return d;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ public class ClientEntityViewForUsers extends AbstractClientEntityView {
|
||||||
private Set<String> whitelistedFields = ImmutableSet.of("clientName", "clientId", "id", "clientDescription", "scope", "logoUri");
|
private Set<String> whitelistedFields = ImmutableSet.of("clientName", "clientId", "id", "clientDescription", "scope", "logoUri");
|
||||||
|
|
||||||
public static final String VIEWNAME = "clientEntityViewUsers";
|
public static final String VIEWNAME = "clientEntityViewUsers";
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.mitre.openid.connect.view.AbstractClientEntityView#getExclusionStrategy()
|
* @see org.mitre.openid.connect.view.AbstractClientEntityView#getExclusionStrategy()
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -52,7 +52,7 @@ public class ClientInformationResponseView extends AbstractView {
|
||||||
private static Logger logger = LoggerFactory.getLogger(ClientInformationResponseView.class);
|
private static Logger logger = LoggerFactory.getLogger(ClientInformationResponseView.class);
|
||||||
|
|
||||||
public static final String VIEWNAME = "clientInformationResponseView";
|
public static final String VIEWNAME = "clientInformationResponseView";
|
||||||
|
|
||||||
// note that this won't serialize nulls by default
|
// note that this won't serialize nulls by default
|
||||||
private Gson gson = new Gson();
|
private Gson gson = new Gson();
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ import org.springframework.web.servlet.view.AbstractView;
|
||||||
public class HttpCodeView extends AbstractView {
|
public class HttpCodeView extends AbstractView {
|
||||||
|
|
||||||
public static final String VIEWNAME = "httpCodeView";
|
public static final String VIEWNAME = "httpCodeView";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) {
|
protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) {
|
||||||
HttpStatus code = (HttpStatus) model.get("code");
|
HttpStatus code = (HttpStatus) model.get("code");
|
||||||
|
|
|
@ -55,7 +55,7 @@ public class JsonApprovedSiteView extends AbstractView {
|
||||||
private static Logger logger = LoggerFactory.getLogger(JsonApprovedSiteView.class);
|
private static Logger logger = LoggerFactory.getLogger(JsonApprovedSiteView.class);
|
||||||
|
|
||||||
public static final String VIEWNAME = "jsonApprovedSiteView";
|
public static final String VIEWNAME = "jsonApprovedSiteView";
|
||||||
|
|
||||||
private Gson gson = new GsonBuilder()
|
private Gson gson = new GsonBuilder()
|
||||||
.setExclusionStrategies(new ExclusionStrategy() {
|
.setExclusionStrategies(new ExclusionStrategy() {
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ public class JsonEntityView extends AbstractView {
|
||||||
private static Logger logger = LoggerFactory.getLogger(JsonEntityView.class);
|
private static Logger logger = LoggerFactory.getLogger(JsonEntityView.class);
|
||||||
|
|
||||||
public static final String VIEWNAME = "jsonEntityView";
|
public static final String VIEWNAME = "jsonEntityView";
|
||||||
|
|
||||||
private Gson gson = new GsonBuilder()
|
private Gson gson = new GsonBuilder()
|
||||||
.setExclusionStrategies(new ExclusionStrategy() {
|
.setExclusionStrategies(new ExclusionStrategy() {
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ public class JsonErrorView extends AbstractView {
|
||||||
private static Logger logger = LoggerFactory.getLogger(JsonEntityView.class);
|
private static Logger logger = LoggerFactory.getLogger(JsonEntityView.class);
|
||||||
|
|
||||||
public static final String VIEWNAME = "jsonErrorView";
|
public static final String VIEWNAME = "jsonErrorView";
|
||||||
|
|
||||||
private Gson gson = new GsonBuilder()
|
private Gson gson = new GsonBuilder()
|
||||||
.setExclusionStrategies(new ExclusionStrategy() {
|
.setExclusionStrategies(new ExclusionStrategy() {
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,7 @@ public class UserInfoJwtView extends UserInfoView {
|
||||||
private static Logger logger = LoggerFactory.getLogger(UserInfoJwtView.class);
|
private static Logger logger = LoggerFactory.getLogger(UserInfoJwtView.class);
|
||||||
|
|
||||||
public static final String VIEWNAME = "userInfoJwtView";
|
public static final String VIEWNAME = "userInfoJwtView";
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private JwtSigningAndValidationService jwtService;
|
private JwtSigningAndValidationService jwtService;
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ public class UserInfoJwtView extends UserInfoView {
|
||||||
gson.toJson(json, writer);
|
gson.toJson(json, writer);
|
||||||
|
|
||||||
response.setContentType("application/jwt");
|
response.setContentType("application/jwt");
|
||||||
|
|
||||||
JWTClaimsSet claims = JWTClaimsSet.parse(writer.toString());
|
JWTClaimsSet claims = JWTClaimsSet.parse(writer.toString());
|
||||||
|
|
||||||
claims.setAudience(Lists.newArrayList(client.getClientId()));
|
claims.setAudience(Lists.newArrayList(client.getClientId()));
|
||||||
|
|
|
@ -49,7 +49,7 @@ public class UserInfoView extends AbstractView {
|
||||||
private static JsonParser jsonParser = new JsonParser();
|
private static JsonParser jsonParser = new JsonParser();
|
||||||
|
|
||||||
public static final String VIEWNAME = "userInfoView";
|
public static final String VIEWNAME = "userInfoView";
|
||||||
|
|
||||||
private static Logger logger = LoggerFactory.getLogger(UserInfoView.class);
|
private static Logger logger = LoggerFactory.getLogger(UserInfoView.class);
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|
|
@ -161,20 +161,20 @@ public class ClientAPI {
|
||||||
// if they leave the client identifier empty, force it to be generated
|
// if they leave the client identifier empty, force it to be generated
|
||||||
if (Strings.isNullOrEmpty(client.getClientId())) {
|
if (Strings.isNullOrEmpty(client.getClientId())) {
|
||||||
client = clientService.generateClientId(client);
|
client = clientService.generateClientId(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (client.getTokenEndpointAuthMethod() == null ||
|
if (client.getTokenEndpointAuthMethod() == null ||
|
||||||
client.getTokenEndpointAuthMethod().equals(AuthMethod.NONE)) {
|
client.getTokenEndpointAuthMethod().equals(AuthMethod.NONE)) {
|
||||||
// we shouldn't have a secret for this client
|
// we shouldn't have a secret for this client
|
||||||
|
|
||||||
client.setClientSecret(null);
|
client.setClientSecret(null);
|
||||||
|
|
||||||
} else if (client.getTokenEndpointAuthMethod().equals(AuthMethod.SECRET_BASIC)
|
} else if (client.getTokenEndpointAuthMethod().equals(AuthMethod.SECRET_BASIC)
|
||||||
|| client.getTokenEndpointAuthMethod().equals(AuthMethod.SECRET_POST)
|
|| client.getTokenEndpointAuthMethod().equals(AuthMethod.SECRET_POST)
|
||||||
|| client.getTokenEndpointAuthMethod().equals(AuthMethod.SECRET_JWT)) {
|
|| client.getTokenEndpointAuthMethod().equals(AuthMethod.SECRET_JWT)) {
|
||||||
|
|
||||||
// if they've asked for us to generate a client secret (or they left it blank but require one), do so here
|
// if they've asked for us to generate a client secret (or they left it blank but require one), do so here
|
||||||
if (json.has("generateClientSecret") && json.get("generateClientSecret").getAsBoolean()
|
if (json.has("generateClientSecret") && json.get("generateClientSecret").getAsBoolean()
|
||||||
|| Strings.isNullOrEmpty(client.getClientSecret())) {
|
|| Strings.isNullOrEmpty(client.getClientSecret())) {
|
||||||
client = clientService.generateClientSecret(client);
|
client = clientService.generateClientSecret(client);
|
||||||
}
|
}
|
||||||
|
@ -187,18 +187,18 @@ public class ClientAPI {
|
||||||
m.addAttribute("errorMessage", "Can not create a client with private key authentication without registering a key via the JWS Set URI.");
|
m.addAttribute("errorMessage", "Can not create a client with private key authentication without registering a key via the JWS Set URI.");
|
||||||
return JsonErrorView.VIEWNAME;
|
return JsonErrorView.VIEWNAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
// otherwise we shouldn't have a secret for this client
|
// otherwise we shouldn't have a secret for this client
|
||||||
client.setClientSecret(null);
|
client.setClientSecret(null);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
logger.error("unknown auth method");
|
logger.error("unknown auth method");
|
||||||
m.addAttribute("code", HttpStatus.BAD_REQUEST);
|
m.addAttribute("code", HttpStatus.BAD_REQUEST);
|
||||||
m.addAttribute("errorMessage", "Unknown auth method requested");
|
m.addAttribute("errorMessage", "Unknown auth method requested");
|
||||||
return JsonErrorView.VIEWNAME;
|
return JsonErrorView.VIEWNAME;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
client.setDynamicallyRegistered(false);
|
client.setDynamicallyRegistered(false);
|
||||||
|
@ -262,15 +262,15 @@ public class ClientAPI {
|
||||||
if (client.getTokenEndpointAuthMethod() == null ||
|
if (client.getTokenEndpointAuthMethod() == null ||
|
||||||
client.getTokenEndpointAuthMethod().equals(AuthMethod.NONE)) {
|
client.getTokenEndpointAuthMethod().equals(AuthMethod.NONE)) {
|
||||||
// we shouldn't have a secret for this client
|
// we shouldn't have a secret for this client
|
||||||
|
|
||||||
client.setClientSecret(null);
|
client.setClientSecret(null);
|
||||||
|
|
||||||
} else if (client.getTokenEndpointAuthMethod().equals(AuthMethod.SECRET_BASIC)
|
} else if (client.getTokenEndpointAuthMethod().equals(AuthMethod.SECRET_BASIC)
|
||||||
|| client.getTokenEndpointAuthMethod().equals(AuthMethod.SECRET_POST)
|
|| client.getTokenEndpointAuthMethod().equals(AuthMethod.SECRET_POST)
|
||||||
|| client.getTokenEndpointAuthMethod().equals(AuthMethod.SECRET_JWT)) {
|
|| client.getTokenEndpointAuthMethod().equals(AuthMethod.SECRET_JWT)) {
|
||||||
|
|
||||||
// if they've asked for us to generate a client secret (or they left it blank but require one), do so here
|
// if they've asked for us to generate a client secret (or they left it blank but require one), do so here
|
||||||
if (json.has("generateClientSecret") && json.get("generateClientSecret").getAsBoolean()
|
if (json.has("generateClientSecret") && json.get("generateClientSecret").getAsBoolean()
|
||||||
|| Strings.isNullOrEmpty(client.getClientSecret())) {
|
|| Strings.isNullOrEmpty(client.getClientSecret())) {
|
||||||
client = clientService.generateClientSecret(client);
|
client = clientService.generateClientSecret(client);
|
||||||
}
|
}
|
||||||
|
@ -283,18 +283,18 @@ public class ClientAPI {
|
||||||
m.addAttribute("errorMessage", "Can not create a client with private key authentication without registering a key via the JWS Set URI.");
|
m.addAttribute("errorMessage", "Can not create a client with private key authentication without registering a key via the JWS Set URI.");
|
||||||
return JsonErrorView.VIEWNAME;
|
return JsonErrorView.VIEWNAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
// otherwise we shouldn't have a secret for this client
|
// otherwise we shouldn't have a secret for this client
|
||||||
client.setClientSecret(null);
|
client.setClientSecret(null);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
logger.error("unknown auth method");
|
logger.error("unknown auth method");
|
||||||
m.addAttribute("code", HttpStatus.BAD_REQUEST);
|
m.addAttribute("code", HttpStatus.BAD_REQUEST);
|
||||||
m.addAttribute("errorMessage", "Unknown auth method requested");
|
m.addAttribute("errorMessage", "Unknown auth method requested");
|
||||||
return JsonErrorView.VIEWNAME;
|
return JsonErrorView.VIEWNAME;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientDetailsEntity newClient = clientService.updateClient(oldClient, client);
|
ClientDetailsEntity newClient = clientService.updateClient(oldClient, client);
|
||||||
|
|
|
@ -133,7 +133,7 @@ public class ClientDynamicRegistrationEndpoint {
|
||||||
m.addAttribute("code", ve.getStatus());
|
m.addAttribute("code", ve.getStatus());
|
||||||
return JsonErrorView.VIEWNAME;
|
return JsonErrorView.VIEWNAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newClient.getTokenEndpointAuthMethod() == null) {
|
if (newClient.getTokenEndpointAuthMethod() == null) {
|
||||||
newClient.setTokenEndpointAuthMethod(AuthMethod.SECRET_BASIC);
|
newClient.setTokenEndpointAuthMethod(AuthMethod.SECRET_BASIC);
|
||||||
}
|
}
|
||||||
|
@ -178,11 +178,11 @@ public class ClientDynamicRegistrationEndpoint {
|
||||||
return HttpCodeView.VIEWNAME;
|
return HttpCodeView.VIEWNAME;
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
logger.error("Couldn't save client", e);
|
logger.error("Couldn't save client", e);
|
||||||
|
|
||||||
m.addAttribute("error", "invalid_client_metadata");
|
m.addAttribute("error", "invalid_client_metadata");
|
||||||
m.addAttribute("errorMessage", "Unable to save client due to invalid or inconsistent metadata.");
|
m.addAttribute("errorMessage", "Unable to save client due to invalid or inconsistent metadata.");
|
||||||
m.addAttribute("code", HttpStatus.BAD_REQUEST); // http 400
|
m.addAttribute("code", HttpStatus.BAD_REQUEST); // http 400
|
||||||
|
|
||||||
return JsonErrorView.VIEWNAME;
|
return JsonErrorView.VIEWNAME;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -224,7 +224,7 @@ public class ClientDynamicRegistrationEndpoint {
|
||||||
m.addAttribute("code", HttpStatus.INTERNAL_SERVER_ERROR);
|
m.addAttribute("code", HttpStatus.INTERNAL_SERVER_ERROR);
|
||||||
return HttpCodeView.VIEWNAME;
|
return HttpCodeView.VIEWNAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// client mismatch
|
// client mismatch
|
||||||
logger.error("readClientConfiguration failed, client ID mismatch: "
|
logger.error("readClientConfiguration failed, client ID mismatch: "
|
||||||
|
@ -293,7 +293,7 @@ public class ClientDynamicRegistrationEndpoint {
|
||||||
m.addAttribute("code", ve.getStatus());
|
m.addAttribute("code", ve.getStatus());
|
||||||
return JsonErrorView.VIEWNAME;
|
return JsonErrorView.VIEWNAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// save the client
|
// save the client
|
||||||
ClientDetailsEntity savedClient = clientService.updateClient(oldClient, newClient);
|
ClientDetailsEntity savedClient = clientService.updateClient(oldClient, newClient);
|
||||||
|
@ -313,11 +313,11 @@ public class ClientDynamicRegistrationEndpoint {
|
||||||
return HttpCodeView.VIEWNAME;
|
return HttpCodeView.VIEWNAME;
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
logger.error("Couldn't save client", e);
|
logger.error("Couldn't save client", e);
|
||||||
|
|
||||||
m.addAttribute("error", "invalid_client_metadata");
|
m.addAttribute("error", "invalid_client_metadata");
|
||||||
m.addAttribute("errorMessage", "Unable to save client due to invalid or inconsistent metadata.");
|
m.addAttribute("errorMessage", "Unable to save client due to invalid or inconsistent metadata.");
|
||||||
m.addAttribute("code", HttpStatus.BAD_REQUEST); // http 400
|
m.addAttribute("code", HttpStatus.BAD_REQUEST); // http 400
|
||||||
|
|
||||||
return JsonErrorView.VIEWNAME;
|
return JsonErrorView.VIEWNAME;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -376,17 +376,17 @@ public class ClientDynamicRegistrationEndpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
newClient.setScope(scopeService.toStrings(allowedScopes));
|
newClient.setScope(scopeService.toStrings(allowedScopes));
|
||||||
|
|
||||||
return newClient;
|
return newClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ClientDetailsEntity validateResponseTypes(ClientDetailsEntity newClient) throws ValidationException {
|
private ClientDetailsEntity validateResponseTypes(ClientDetailsEntity newClient) throws ValidationException {
|
||||||
if (newClient.getResponseTypes() == null) {
|
if (newClient.getResponseTypes() == null) {
|
||||||
newClient.setResponseTypes(new HashSet<String>());
|
newClient.setResponseTypes(new HashSet<String>());
|
||||||
}
|
}
|
||||||
return newClient;
|
return newClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ClientDetailsEntity validateGrantTypes(ClientDetailsEntity newClient) throws ValidationException {
|
private ClientDetailsEntity validateGrantTypes(ClientDetailsEntity newClient) throws ValidationException {
|
||||||
// set default grant types if needed
|
// set default grant types if needed
|
||||||
if (newClient.getGrantTypes() == null || newClient.getGrantTypes().isEmpty()) {
|
if (newClient.getGrantTypes() == null || newClient.getGrantTypes().isEmpty()) {
|
||||||
|
@ -396,15 +396,15 @@ public class ClientDynamicRegistrationEndpoint {
|
||||||
newClient.setGrantTypes(Sets.newHashSet("authorization_code")); // allow authorization code grant type by default
|
newClient.setGrantTypes(Sets.newHashSet("authorization_code")); // allow authorization code grant type by default
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// filter out unknown grant types
|
// filter out unknown grant types
|
||||||
// TODO: make this a pluggable service
|
// TODO: make this a pluggable service
|
||||||
Set<String> requestedGrantTypes = new HashSet<String>(newClient.getGrantTypes());
|
Set<String> requestedGrantTypes = new HashSet<String>(newClient.getGrantTypes());
|
||||||
requestedGrantTypes.retainAll(
|
requestedGrantTypes.retainAll(
|
||||||
ImmutableSet.of("authorization_code", "implicit",
|
ImmutableSet.of("authorization_code", "implicit",
|
||||||
"password", "client_credentials", "refresh_token",
|
"password", "client_credentials", "refresh_token",
|
||||||
"urn:ietf:params:oauth:grant_type:redelegate"));
|
"urn:ietf:params:oauth:grant_type:redelegate"));
|
||||||
|
|
||||||
// don't allow "password" grant type for dynamic registration
|
// don't allow "password" grant type for dynamic registration
|
||||||
if (newClient.getGrantTypes().contains("password")) {
|
if (newClient.getGrantTypes().contains("password")) {
|
||||||
// return an error, you can't dynamically register for the password grant
|
// return an error, you can't dynamically register for the password grant
|
||||||
|
@ -425,12 +425,12 @@ public class ClientDynamicRegistrationEndpoint {
|
||||||
// return an error, you can't have this grant type and response type together
|
// return an error, you can't have this grant type and response type together
|
||||||
throw new ValidationException("invalid_client_metadata", "Incompatible response types requested: " + newClient.getGrantTypes() + " / " + newClient.getResponseTypes(), HttpStatus.BAD_REQUEST);
|
throw new ValidationException("invalid_client_metadata", "Incompatible response types requested: " + newClient.getGrantTypes() + " / " + newClient.getResponseTypes(), HttpStatus.BAD_REQUEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
newClient.getResponseTypes().add("code");
|
newClient.getResponseTypes().add("code");
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newClient.getGrantTypes().contains("implicit")) {
|
if (newClient.getGrantTypes().contains("implicit")) {
|
||||||
|
|
||||||
// check for incompatible grants
|
// check for incompatible grants
|
||||||
|
@ -439,19 +439,19 @@ public class ClientDynamicRegistrationEndpoint {
|
||||||
// return an error, you can't have these grant types together
|
// return an error, you can't have these grant types together
|
||||||
throw new ValidationException("invalid_client_metadata", "Incompatible grant types requested: " + newClient.getGrantTypes(), HttpStatus.BAD_REQUEST);
|
throw new ValidationException("invalid_client_metadata", "Incompatible grant types requested: " + newClient.getGrantTypes(), HttpStatus.BAD_REQUEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newClient.getResponseTypes().contains("code")) {
|
if (newClient.getResponseTypes().contains("code")) {
|
||||||
// return an error, you can't have this grant type and response type together
|
// return an error, you can't have this grant type and response type together
|
||||||
throw new ValidationException("invalid_client_metadata", "Incompatible response types requested: " + newClient.getGrantTypes() + " / " + newClient.getResponseTypes(), HttpStatus.BAD_REQUEST);
|
throw new ValidationException("invalid_client_metadata", "Incompatible response types requested: " + newClient.getGrantTypes() + " / " + newClient.getResponseTypes(), HttpStatus.BAD_REQUEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
newClient.getResponseTypes().add("token");
|
newClient.getResponseTypes().add("token");
|
||||||
|
|
||||||
// don't allow refresh tokens in implicit clients
|
// don't allow refresh tokens in implicit clients
|
||||||
newClient.getGrantTypes().remove("refresh_token");
|
newClient.getGrantTypes().remove("refresh_token");
|
||||||
newClient.getScope().remove("offline_access");
|
newClient.getScope().remove("offline_access");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newClient.getGrantTypes().contains("client_credentials")) {
|
if (newClient.getGrantTypes().contains("client_credentials")) {
|
||||||
|
|
||||||
// check for incompatible grants
|
// check for incompatible grants
|
||||||
|
@ -460,25 +460,25 @@ public class ClientDynamicRegistrationEndpoint {
|
||||||
// return an error, you can't have these grant types together
|
// return an error, you can't have these grant types together
|
||||||
throw new ValidationException("invalid_client_metadata", "Incompatible grant types requested: " + newClient.getGrantTypes(), HttpStatus.BAD_REQUEST);
|
throw new ValidationException("invalid_client_metadata", "Incompatible grant types requested: " + newClient.getGrantTypes(), HttpStatus.BAD_REQUEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!newClient.getResponseTypes().isEmpty()) {
|
if (!newClient.getResponseTypes().isEmpty()) {
|
||||||
// return an error, you can't have this grant type and response type together
|
// return an error, you can't have this grant type and response type together
|
||||||
throw new ValidationException("invalid_client_metadata", "Incompatible response types requested: " + newClient.getGrantTypes() + " / " + newClient.getResponseTypes(), HttpStatus.BAD_REQUEST);
|
throw new ValidationException("invalid_client_metadata", "Incompatible response types requested: " + newClient.getGrantTypes() + " / " + newClient.getResponseTypes(), HttpStatus.BAD_REQUEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
// don't allow refresh tokens or id tokens in client_credentials clients
|
// don't allow refresh tokens or id tokens in client_credentials clients
|
||||||
newClient.getGrantTypes().remove("refresh_token");
|
newClient.getGrantTypes().remove("refresh_token");
|
||||||
newClient.getScope().remove("offline_access");
|
newClient.getScope().remove("offline_access");
|
||||||
newClient.getScope().remove("openid");
|
newClient.getScope().remove("openid");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newClient.getGrantTypes().isEmpty()) {
|
if (newClient.getGrantTypes().isEmpty()) {
|
||||||
// return an error, you need at least one grant type selected
|
// return an error, you need at least one grant type selected
|
||||||
throw new ValidationException("invalid_client_metadata", "Clients must register at least one grant type.", HttpStatus.BAD_REQUEST);
|
throw new ValidationException("invalid_client_metadata", "Clients must register at least one grant type.", HttpStatus.BAD_REQUEST);
|
||||||
}
|
}
|
||||||
return newClient;
|
return newClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ClientDetailsEntity validateRedirectUris(ClientDetailsEntity newClient) throws ValidationException {
|
private ClientDetailsEntity validateRedirectUris(ClientDetailsEntity newClient) throws ValidationException {
|
||||||
// check to make sure this client registered a redirect URI if using a redirect flow
|
// check to make sure this client registered a redirect URI if using a redirect flow
|
||||||
if (newClient.getGrantTypes().contains("authorization_code") || newClient.getGrantTypes().contains("implicit")) {
|
if (newClient.getGrantTypes().contains("authorization_code") || newClient.getGrantTypes().contains("implicit")) {
|
||||||
|
@ -492,17 +492,17 @@ public class ClientDynamicRegistrationEndpoint {
|
||||||
// return an error
|
// return an error
|
||||||
throw new ValidationException("invalid_redirect_uri", "Redirect URI is not allowed: " + uri, HttpStatus.BAD_REQUEST);
|
throw new ValidationException("invalid_redirect_uri", "Redirect URI is not allowed: " + uri, HttpStatus.BAD_REQUEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uri.contains("#")) {
|
if (uri.contains("#")) {
|
||||||
// if it contains the hash symbol then it has a fragment, which isn't allowed
|
// if it contains the hash symbol then it has a fragment, which isn't allowed
|
||||||
throw new ValidationException("invalid_redirect_uri", "Redirect URI can not have a fragment", HttpStatus.BAD_REQUEST);
|
throw new ValidationException("invalid_redirect_uri", "Redirect URI can not have a fragment", HttpStatus.BAD_REQUEST);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return newClient;
|
return newClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ClientDetailsEntity validateAuth(ClientDetailsEntity newClient) throws ValidationException {
|
private ClientDetailsEntity validateAuth(ClientDetailsEntity newClient) throws ValidationException {
|
||||||
if (newClient.getTokenEndpointAuthMethod() == null) {
|
if (newClient.getTokenEndpointAuthMethod() == null) {
|
||||||
newClient.setTokenEndpointAuthMethod(AuthMethod.SECRET_BASIC);
|
newClient.setTokenEndpointAuthMethod(AuthMethod.SECRET_BASIC);
|
||||||
|
@ -520,7 +520,7 @@ public class ClientDynamicRegistrationEndpoint {
|
||||||
if (Strings.isNullOrEmpty(newClient.getJwksUri())) {
|
if (Strings.isNullOrEmpty(newClient.getJwksUri())) {
|
||||||
throw new ValidationException("invalid_client_metadata", "JWK Set URI required when using private key authentication", HttpStatus.BAD_REQUEST);
|
throw new ValidationException("invalid_client_metadata", "JWK Set URI required when using private key authentication", HttpStatus.BAD_REQUEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
newClient.setClientSecret(null);
|
newClient.setClientSecret(null);
|
||||||
} else if (newClient.getTokenEndpointAuthMethod() == AuthMethod.NONE) {
|
} else if (newClient.getTokenEndpointAuthMethod() == AuthMethod.NONE) {
|
||||||
newClient.setClientSecret(null);
|
newClient.setClientSecret(null);
|
||||||
|
@ -529,14 +529,14 @@ public class ClientDynamicRegistrationEndpoint {
|
||||||
}
|
}
|
||||||
return newClient;
|
return newClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
private OAuth2AccessTokenEntity fetchValidRegistrationToken(OAuth2Authentication auth, ClientDetailsEntity client) {
|
private OAuth2AccessTokenEntity fetchValidRegistrationToken(OAuth2Authentication auth, ClientDetailsEntity client) {
|
||||||
|
|
||||||
OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails) auth.getDetails();
|
OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails) auth.getDetails();
|
||||||
OAuth2AccessTokenEntity token = tokenService.readAccessToken(details.getTokenValue());
|
OAuth2AccessTokenEntity token = tokenService.readAccessToken(details.getTokenValue());
|
||||||
|
|
||||||
if (config.getRegTokenLifeTime() != null) {
|
if (config.getRegTokenLifeTime() != null) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Re-issue the token if it has been issued before [currentTime - validity]
|
// Re-issue the token if it has been issued before [currentTime - validity]
|
||||||
Date validToDate = new Date(System.currentTimeMillis() - config.getRegTokenLifeTime() * 1000);
|
Date validToDate = new Date(System.currentTimeMillis() - config.getRegTokenLifeTime() * 1000);
|
||||||
|
|
|
@ -60,13 +60,13 @@ public class DataAPI {
|
||||||
@Autowired
|
@Autowired
|
||||||
private ConfigurationPropertiesBean config;
|
private ConfigurationPropertiesBean config;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private MITREidDataService_1_0 dataService_1_0;
|
private MITREidDataService_1_0 dataService_1_0;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private MITREidDataService_1_1 dataService_1_1;
|
private MITREidDataService_1_1 dataService_1_1;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private MITREidDataService_1_1 dataService_1_2;
|
private MITREidDataService_1_1 dataService_1_2;
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.POST, consumes = "application/json")
|
@RequestMapping(method = RequestMethod.POST, consumes = "application/json")
|
||||||
|
@ -79,29 +79,29 @@ public class DataAPI {
|
||||||
while (reader.hasNext()) {
|
while (reader.hasNext()) {
|
||||||
JsonToken tok = reader.peek();
|
JsonToken tok = reader.peek();
|
||||||
switch (tok) {
|
switch (tok) {
|
||||||
case NAME:
|
case NAME:
|
||||||
String name = reader.nextName();
|
String name = reader.nextName();
|
||||||
if (name.equals(MITREidDataService.MITREID_CONNECT_1_0)) {
|
if (name.equals(MITREidDataService.MITREID_CONNECT_1_0)) {
|
||||||
dataService_1_0.importData(reader);
|
dataService_1_0.importData(reader);
|
||||||
} else if (name.equals(MITREidDataService.MITREID_CONNECT_1_1)) {
|
} else if (name.equals(MITREidDataService.MITREID_CONNECT_1_1)) {
|
||||||
dataService_1_1.importData(reader);
|
dataService_1_1.importData(reader);
|
||||||
} else if (name.equals(MITREidDataService.MITREID_CONNECT_1_2)) {
|
} else if (name.equals(MITREidDataService.MITREID_CONNECT_1_2)) {
|
||||||
dataService_1_2.importData(reader);
|
dataService_1_2.importData(reader);
|
||||||
} else {
|
} else {
|
||||||
// consume the next bit silently for now
|
// consume the next bit silently for now
|
||||||
logger.debug("Skipping value for " + name); // TODO: write these out?
|
logger.debug("Skipping value for " + name); // TODO: write these out?
|
||||||
reader.skipValue();
|
reader.skipValue();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case END_OBJECT:
|
case END_OBJECT:
|
||||||
reader.endObject();
|
reader.endObject();
|
||||||
break;
|
break;
|
||||||
case END_DOCUMENT:
|
case END_DOCUMENT:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return "httpCodeView";
|
return "httpCodeView";
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.GET, produces = "application/json")
|
@RequestMapping(method = RequestMethod.GET, produces = "application/json")
|
||||||
|
@ -115,7 +115,7 @@ public class DataAPI {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
writer.beginObject();
|
writer.beginObject();
|
||||||
|
|
||||||
writer.name("exported-at");
|
writer.name("exported-at");
|
||||||
writer.value(dateFormat.format(new Date()));
|
writer.value(dateFormat.format(new Date()));
|
||||||
|
|
|
@ -55,7 +55,6 @@ import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
import org.springframework.web.util.UriUtils;
|
import org.springframework.web.util.UriUtils;
|
||||||
|
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
import com.google.common.collect.Sets;
|
|
||||||
import com.google.gson.JsonSyntaxException;
|
import com.google.gson.JsonSyntaxException;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
|
@ -184,11 +183,11 @@ public class ProtectedResourceRegistrationEndpoint {
|
||||||
return HttpCodeView.VIEWNAME;
|
return HttpCodeView.VIEWNAME;
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
logger.error("Couldn't save client", e);
|
logger.error("Couldn't save client", e);
|
||||||
|
|
||||||
m.addAttribute("error", "invalid_client_metadata");
|
m.addAttribute("error", "invalid_client_metadata");
|
||||||
m.addAttribute("errorMessage", "Unable to save client due to invalid or inconsistent metadata.");
|
m.addAttribute("errorMessage", "Unable to save client due to invalid or inconsistent metadata.");
|
||||||
m.addAttribute("code", HttpStatus.BAD_REQUEST); // http 400
|
m.addAttribute("code", HttpStatus.BAD_REQUEST); // http 400
|
||||||
|
|
||||||
return JsonErrorView.VIEWNAME;
|
return JsonErrorView.VIEWNAME;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -204,7 +203,7 @@ public class ProtectedResourceRegistrationEndpoint {
|
||||||
private ClientDetailsEntity validateScopes(ClientDetailsEntity newClient) throws ValidationException {
|
private ClientDetailsEntity validateScopes(ClientDetailsEntity newClient) throws ValidationException {
|
||||||
|
|
||||||
// note that protected resources can register for any scopes, even ones not used by the sysadmin
|
// note that protected resources can register for any scopes, even ones not used by the sysadmin
|
||||||
|
|
||||||
// scopes that the client is asking for
|
// scopes that the client is asking for
|
||||||
Set<SystemScope> requestedScopes = scopeService.fromStrings(newClient.getScope());
|
Set<SystemScope> requestedScopes = scopeService.fromStrings(newClient.getScope());
|
||||||
|
|
||||||
|
@ -214,7 +213,7 @@ public class ProtectedResourceRegistrationEndpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
newClient.setScope(scopeService.toStrings(requestedScopes));
|
newClient.setScope(scopeService.toStrings(requestedScopes));
|
||||||
|
|
||||||
return newClient;
|
return newClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -363,11 +362,11 @@ public class ProtectedResourceRegistrationEndpoint {
|
||||||
return HttpCodeView.VIEWNAME;
|
return HttpCodeView.VIEWNAME;
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
logger.error("Couldn't save client", e);
|
logger.error("Couldn't save client", e);
|
||||||
|
|
||||||
m.addAttribute("error", "invalid_client_metadata");
|
m.addAttribute("error", "invalid_client_metadata");
|
||||||
m.addAttribute("errorMessage", "Unable to save client due to invalid or inconsistent metadata.");
|
m.addAttribute("errorMessage", "Unable to save client due to invalid or inconsistent metadata.");
|
||||||
m.addAttribute("code", HttpStatus.BAD_REQUEST); // http 400
|
m.addAttribute("code", HttpStatus.BAD_REQUEST); // http 400
|
||||||
|
|
||||||
return JsonErrorView.VIEWNAME;
|
return JsonErrorView.VIEWNAME;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -428,7 +427,7 @@ public class ProtectedResourceRegistrationEndpoint {
|
||||||
if (Strings.isNullOrEmpty(newClient.getJwksUri())) {
|
if (Strings.isNullOrEmpty(newClient.getJwksUri())) {
|
||||||
throw new ValidationException("invalid_client_metadata", "JWK Set URI required when using private key authentication", HttpStatus.BAD_REQUEST);
|
throw new ValidationException("invalid_client_metadata", "JWK Set URI required when using private key authentication", HttpStatus.BAD_REQUEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
newClient.setClientSecret(null);
|
newClient.setClientSecret(null);
|
||||||
} else if (newClient.getTokenEndpointAuthMethod() == AuthMethod.NONE) {
|
} else if (newClient.getTokenEndpointAuthMethod() == AuthMethod.NONE) {
|
||||||
newClient.setClientSecret(null);
|
newClient.setClientSecret(null);
|
||||||
|
@ -437,14 +436,14 @@ public class ProtectedResourceRegistrationEndpoint {
|
||||||
}
|
}
|
||||||
return newClient;
|
return newClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
private OAuth2AccessTokenEntity fetchValidRegistrationToken(OAuth2Authentication auth, ClientDetailsEntity client) {
|
private OAuth2AccessTokenEntity fetchValidRegistrationToken(OAuth2Authentication auth, ClientDetailsEntity client) {
|
||||||
|
|
||||||
OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails) auth.getDetails();
|
OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails) auth.getDetails();
|
||||||
OAuth2AccessTokenEntity token = tokenService.readAccessToken(details.getTokenValue());
|
OAuth2AccessTokenEntity token = tokenService.readAccessToken(details.getTokenValue());
|
||||||
|
|
||||||
if (config.getRegTokenLifeTime() != null) {
|
if (config.getRegTokenLifeTime() != null) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Re-issue the token if it has been issued before [currentTime - validity]
|
// Re-issue the token if it has been issued before [currentTime - validity]
|
||||||
Date validToDate = new Date(System.currentTimeMillis() - config.getRegTokenLifeTime() * 1000);
|
Date validToDate = new Date(System.currentTimeMillis() - config.getRegTokenLifeTime() * 1000);
|
||||||
|
|
|
@ -99,11 +99,11 @@ public class UserInfoEndpoint {
|
||||||
// start off by seeing if the client has registered for a signed/encrypted JWT from here
|
// start off by seeing if the client has registered for a signed/encrypted JWT from here
|
||||||
ClientDetailsEntity client = clientService.loadClientByClientId(auth.getOAuth2Request().getClientId());
|
ClientDetailsEntity client = clientService.loadClientByClientId(auth.getOAuth2Request().getClientId());
|
||||||
model.addAttribute("client", client);
|
model.addAttribute("client", client);
|
||||||
|
|
||||||
List<MediaType> mediaTypes = MediaType.parseMediaTypes(acceptHeader);
|
List<MediaType> mediaTypes = MediaType.parseMediaTypes(acceptHeader);
|
||||||
MediaType.sortBySpecificityAndQuality(mediaTypes);
|
MediaType.sortBySpecificityAndQuality(mediaTypes);
|
||||||
|
|
||||||
if (client.getUserInfoSignedResponseAlg() != null
|
if (client.getUserInfoSignedResponseAlg() != null
|
||||||
|| client.getUserInfoEncryptedResponseAlg() != null
|
|| client.getUserInfoEncryptedResponseAlg() != null
|
||||||
|| client.getUserInfoEncryptedResponseEnc() != null) {
|
|| client.getUserInfoEncryptedResponseEnc() != null) {
|
||||||
// client has a preference, see if they ask for plain JSON specifically on this request
|
// client has a preference, see if they ask for plain JSON specifically on this request
|
||||||
|
@ -114,7 +114,7 @@ public class UserInfoEndpoint {
|
||||||
return UserInfoView.VIEWNAME;
|
return UserInfoView.VIEWNAME;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// otherwise return JWT
|
// otherwise return JWT
|
||||||
return UserInfoJwtView.VIEWNAME;
|
return UserInfoJwtView.VIEWNAME;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -83,8 +83,7 @@ public class TestDefaultIntrospectionAuthorizer {
|
||||||
String tokenClient = "token";
|
String tokenClient = "token";
|
||||||
Set<String> authScope = scope("scope1", "scope2");
|
Set<String> authScope = scope("scope1", "scope2");
|
||||||
Set<String> tokenScope = scope("scope1", "scope2", "scope3");
|
Set<String> tokenScope = scope("scope1", "scope2", "scope3");
|
||||||
given(scopeService.scopesMatch(authScope, tokenScope))
|
given(scopeService.scopesMatch(authScope, tokenScope)).willReturn(false);
|
||||||
.willReturn(false);
|
|
||||||
|
|
||||||
// when
|
// when
|
||||||
boolean permitted = introspectionPermitter.isIntrospectionPermitted(
|
boolean permitted = introspectionPermitter.isIntrospectionPermitted(
|
||||||
|
@ -101,8 +100,7 @@ public class TestDefaultIntrospectionAuthorizer {
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ClientDetails clientWithIdAndScope(String clientId,
|
private ClientDetails clientWithIdAndScope(String clientId, Set<String> scope) {
|
||||||
Set<String> scope) {
|
|
||||||
ClientDetails client = clientWithId(clientId);
|
ClientDetails client = clientWithId(clientId);
|
||||||
given(client.getScope()).willReturn(scope);
|
given(client.getScope()).willReturn(scope);
|
||||||
return client;
|
return client;
|
||||||
|
|
|
@ -16,13 +16,13 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.mitre.oauth2.service.impl;
|
package org.mitre.oauth2.service.impl;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import static com.google.common.collect.Sets.newHashSet;
|
||||||
import org.junit.Test;
|
import static org.hamcrest.CoreMatchers.equalTo;
|
||||||
import org.mitre.oauth2.model.OAuth2AccessTokenEntity;
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
import org.mitre.oauth2.model.OAuth2RefreshTokenEntity;
|
import static org.junit.Assert.assertThat;
|
||||||
import org.mitre.openid.connect.model.UserInfo;
|
import static org.mockito.BDDMockito.given;
|
||||||
import org.springframework.security.oauth2.provider.OAuth2Authentication;
|
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
|
||||||
import org.springframework.security.oauth2.provider.OAuth2Request;
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
|
@ -32,209 +32,210 @@ import java.util.Set;
|
||||||
|
|
||||||
import javax.swing.text.DateFormatter;
|
import javax.swing.text.DateFormatter;
|
||||||
|
|
||||||
import static com.google.common.collect.Sets.newHashSet;
|
import org.junit.Test;
|
||||||
import static org.hamcrest.CoreMatchers.equalTo;
|
import org.mitre.oauth2.model.OAuth2AccessTokenEntity;
|
||||||
import static org.hamcrest.CoreMatchers.is;
|
import org.mitre.oauth2.model.OAuth2RefreshTokenEntity;
|
||||||
import static org.junit.Assert.assertThat;
|
import org.mitre.openid.connect.model.UserInfo;
|
||||||
import static org.mockito.BDDMockito.given;
|
import org.springframework.security.oauth2.provider.OAuth2Authentication;
|
||||||
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
|
import org.springframework.security.oauth2.provider.OAuth2Request;
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
|
||||||
public class TestDefaultIntrospectionResultAssembler {
|
public class TestDefaultIntrospectionResultAssembler {
|
||||||
|
|
||||||
private DefaultIntrospectionResultAssembler assembler = new DefaultIntrospectionResultAssembler();
|
private DefaultIntrospectionResultAssembler assembler = new DefaultIntrospectionResultAssembler();
|
||||||
|
|
||||||
private static DateFormatter dateFormat = new DateFormatter(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"));
|
private static DateFormatter dateFormat = new DateFormatter(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"));
|
||||||
|
|
||||||
@Test
|
|
||||||
public void shouldAssembleExpectedResultForAccessToken() throws ParseException {
|
|
||||||
|
|
||||||
// given
|
@Test
|
||||||
OAuth2AccessTokenEntity accessToken = accessToken(new Date(123 * 1000L), scopes("foo", "bar"), "Bearer",
|
public void shouldAssembleExpectedResultForAccessToken() throws ParseException {
|
||||||
authentication("name", request("clientId")));
|
|
||||||
|
|
||||||
UserInfo userInfo = userInfo("sub");
|
// given
|
||||||
|
OAuth2AccessTokenEntity accessToken = accessToken(new Date(123 * 1000L), scopes("foo", "bar"), "Bearer",
|
||||||
|
authentication("name", request("clientId")));
|
||||||
|
|
||||||
// when
|
UserInfo userInfo = userInfo("sub");
|
||||||
Map<String, Object> result = assembler.assembleFrom(accessToken, userInfo);
|
|
||||||
|
// when
|
||||||
|
Map<String, Object> result = assembler.assembleFrom(accessToken, userInfo);
|
||||||
|
|
||||||
|
|
||||||
// then
|
// then
|
||||||
Map<String, Object> expected = new ImmutableMap.Builder<String, Object>()
|
Map<String, Object> expected = new ImmutableMap.Builder<String, Object>()
|
||||||
.put("sub", "sub")
|
.put("sub", "sub")
|
||||||
.put("exp", 123L)
|
.put("exp", 123L)
|
||||||
.put("expires_at", dateFormat.valueToString(new Date(123 * 1000L)))
|
.put("expires_at", dateFormat.valueToString(new Date(123 * 1000L)))
|
||||||
.put("scope", "bar foo")
|
.put("scope", "bar foo")
|
||||||
.put("active", Boolean.TRUE)
|
.put("active", Boolean.TRUE)
|
||||||
.put("user_id", "name")
|
.put("user_id", "name")
|
||||||
.put("client_id", "clientId")
|
.put("client_id", "clientId")
|
||||||
.put("token_type", "Bearer")
|
.put("token_type", "Bearer")
|
||||||
.build();
|
.build();
|
||||||
assertThat(result, is(equalTo(expected)));
|
assertThat(result, is(equalTo(expected)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldAssembleExpectedResultForAccessTokenWithoutUserInfo() throws ParseException {
|
public void shouldAssembleExpectedResultForAccessTokenWithoutUserInfo() throws ParseException {
|
||||||
|
|
||||||
// given
|
// given
|
||||||
OAuth2AccessTokenEntity accessToken = accessToken(new Date(123 * 1000L), scopes("foo", "bar"), "Bearer",
|
OAuth2AccessTokenEntity accessToken = accessToken(new Date(123 * 1000L), scopes("foo", "bar"), "Bearer",
|
||||||
authentication("name", request("clientId")));
|
authentication("name", request("clientId")));
|
||||||
|
|
||||||
// when
|
// when
|
||||||
Map<String, Object> result = assembler.assembleFrom(accessToken, null);
|
Map<String, Object> result = assembler.assembleFrom(accessToken, null);
|
||||||
|
|
||||||
|
|
||||||
// then
|
// then
|
||||||
Map<String, Object> expected = new ImmutableMap.Builder<String, Object>()
|
Map<String, Object> expected = new ImmutableMap.Builder<String, Object>()
|
||||||
.put("sub", "name")
|
.put("sub", "name")
|
||||||
.put("exp", 123L)
|
.put("exp", 123L)
|
||||||
.put("expires_at", dateFormat.valueToString(new Date(123 * 1000L)))
|
.put("expires_at", dateFormat.valueToString(new Date(123 * 1000L)))
|
||||||
.put("scope", "bar foo")
|
.put("scope", "bar foo")
|
||||||
.put("active", Boolean.TRUE)
|
.put("active", Boolean.TRUE)
|
||||||
.put("user_id", "name")
|
.put("user_id", "name")
|
||||||
.put("client_id", "clientId")
|
.put("client_id", "clientId")
|
||||||
.put("token_type", "Bearer")
|
.put("token_type", "Bearer")
|
||||||
.build();
|
.build();
|
||||||
assertThat(result, is(equalTo(expected)));
|
assertThat(result, is(equalTo(expected)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldAssembleExpectedResultForAccessTokenWithoutExpiry() {
|
public void shouldAssembleExpectedResultForAccessTokenWithoutExpiry() {
|
||||||
|
|
||||||
// given
|
// given
|
||||||
OAuth2AccessTokenEntity accessToken = accessToken(null, scopes("foo", "bar"), "Bearer",
|
OAuth2AccessTokenEntity accessToken = accessToken(null, scopes("foo", "bar"), "Bearer",
|
||||||
authentication("name", request("clientId")));
|
authentication("name", request("clientId")));
|
||||||
|
|
||||||
UserInfo userInfo = userInfo("sub");
|
UserInfo userInfo = userInfo("sub");
|
||||||
|
|
||||||
// when
|
// when
|
||||||
Map<String, Object> result = assembler.assembleFrom(accessToken, userInfo);
|
Map<String, Object> result = assembler.assembleFrom(accessToken, userInfo);
|
||||||
|
|
||||||
|
|
||||||
// then
|
// then
|
||||||
Map<String, Object> expected = new ImmutableMap.Builder<String, Object>()
|
Map<String, Object> expected = new ImmutableMap.Builder<String, Object>()
|
||||||
.put("sub", "sub")
|
.put("sub", "sub")
|
||||||
.put("scope", "bar foo")
|
.put("scope", "bar foo")
|
||||||
.put("active", Boolean.TRUE)
|
.put("active", Boolean.TRUE)
|
||||||
.put("user_id", "name")
|
.put("user_id", "name")
|
||||||
.put("client_id", "clientId")
|
.put("client_id", "clientId")
|
||||||
.put("token_type", "Bearer")
|
.put("token_type", "Bearer")
|
||||||
.build();
|
.build();
|
||||||
assertThat(result, is(equalTo(expected)));
|
assertThat(result, is(equalTo(expected)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldAssembleExpectedResultForRefreshToken() throws ParseException {
|
public void shouldAssembleExpectedResultForRefreshToken() throws ParseException {
|
||||||
|
|
||||||
// given
|
// given
|
||||||
OAuth2RefreshTokenEntity refreshToken = refreshToken(new Date(123 * 1000L),
|
OAuth2RefreshTokenEntity refreshToken = refreshToken(new Date(123 * 1000L),
|
||||||
authentication("name", request("clientId", scopes("foo", "bar"))));
|
authentication("name", request("clientId", scopes("foo", "bar"))));
|
||||||
|
|
||||||
UserInfo userInfo = userInfo("sub");
|
UserInfo userInfo = userInfo("sub");
|
||||||
|
|
||||||
// when
|
// when
|
||||||
Map<String, Object> result = assembler.assembleFrom(refreshToken, userInfo);
|
Map<String, Object> result = assembler.assembleFrom(refreshToken, userInfo);
|
||||||
|
|
||||||
|
|
||||||
// then
|
// then
|
||||||
Map<String, Object> expected = new ImmutableMap.Builder<String, Object>()
|
Map<String, Object> expected = new ImmutableMap.Builder<String, Object>()
|
||||||
.put("sub", "sub")
|
.put("sub", "sub")
|
||||||
.put("exp", 123L)
|
.put("exp", 123L)
|
||||||
.put("expires_at", dateFormat.valueToString(new Date(123 * 1000L)))
|
.put("expires_at", dateFormat.valueToString(new Date(123 * 1000L)))
|
||||||
.put("scope", "bar foo")
|
.put("scope", "bar foo")
|
||||||
.put("active", Boolean.TRUE)
|
.put("active", Boolean.TRUE)
|
||||||
.put("user_id", "name")
|
.put("user_id", "name")
|
||||||
.put("client_id", "clientId")
|
.put("client_id", "clientId")
|
||||||
.build();
|
.build();
|
||||||
assertThat(result, is(equalTo(expected)));
|
assertThat(result, is(equalTo(expected)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldAssembleExpectedResultForRefreshTokenWithoutUserInfo() throws ParseException {
|
public void shouldAssembleExpectedResultForRefreshTokenWithoutUserInfo() throws ParseException {
|
||||||
|
|
||||||
// given
|
// given
|
||||||
OAuth2RefreshTokenEntity refreshToken = refreshToken(new Date(123 * 1000L),
|
OAuth2RefreshTokenEntity refreshToken = refreshToken(new Date(123 * 1000L),
|
||||||
authentication("name", request("clientId", scopes("foo", "bar"))));
|
authentication("name", request("clientId", scopes("foo", "bar"))));
|
||||||
|
|
||||||
// when
|
// when
|
||||||
Map<String, Object> result = assembler.assembleFrom(refreshToken, null);
|
Map<String, Object> result = assembler.assembleFrom(refreshToken, null);
|
||||||
|
|
||||||
|
|
||||||
// then
|
// then
|
||||||
Map<String, Object> expected = new ImmutableMap.Builder<String, Object>()
|
Map<String, Object> expected = new ImmutableMap.Builder<String, Object>()
|
||||||
.put("sub", "name")
|
.put("sub", "name")
|
||||||
.put("exp", 123L)
|
.put("exp", 123L)
|
||||||
.put("expires_at", dateFormat.valueToString(new Date(123 * 1000L)))
|
.put("expires_at", dateFormat.valueToString(new Date(123 * 1000L)))
|
||||||
.put("scope", "bar foo")
|
.put("scope", "bar foo")
|
||||||
.put("active", Boolean.TRUE)
|
.put("active", Boolean.TRUE)
|
||||||
.put("user_id", "name")
|
.put("user_id", "name")
|
||||||
.put("client_id", "clientId")
|
.put("client_id", "clientId")
|
||||||
.build();
|
.build();
|
||||||
assertThat(result, is(equalTo(expected)));
|
assertThat(result, is(equalTo(expected)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldAssembleExpectedResultForRefreshTokenWithoutExpiry() {
|
public void shouldAssembleExpectedResultForRefreshTokenWithoutExpiry() {
|
||||||
|
|
||||||
// given
|
// given
|
||||||
OAuth2RefreshTokenEntity refreshToken = refreshToken(null,
|
OAuth2RefreshTokenEntity refreshToken = refreshToken(null,
|
||||||
authentication("name", request("clientId", scopes("foo", "bar"))));
|
authentication("name", request("clientId", scopes("foo", "bar"))));
|
||||||
|
|
||||||
UserInfo userInfo = userInfo("sub");
|
UserInfo userInfo = userInfo("sub");
|
||||||
|
|
||||||
// when
|
// when
|
||||||
Map<String, Object> result = assembler.assembleFrom(refreshToken, userInfo);
|
Map<String, Object> result = assembler.assembleFrom(refreshToken, userInfo);
|
||||||
|
|
||||||
|
|
||||||
// then
|
// then
|
||||||
Map<String, Object> expected = new ImmutableMap.Builder<String, Object>()
|
Map<String, Object> expected = new ImmutableMap.Builder<String, Object>()
|
||||||
.put("sub", "sub")
|
.put("sub", "sub")
|
||||||
.put("scope", "bar foo")
|
.put("scope", "bar foo")
|
||||||
.put("active", Boolean.TRUE)
|
.put("active", Boolean.TRUE)
|
||||||
.put("user_id", "name")
|
.put("user_id", "name")
|
||||||
.put("client_id", "clientId")
|
.put("client_id", "clientId")
|
||||||
.build();
|
.build();
|
||||||
assertThat(result, is(equalTo(expected)));
|
assertThat(result, is(equalTo(expected)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private UserInfo userInfo(String sub) {
|
private UserInfo userInfo(String sub) {
|
||||||
UserInfo userInfo = mock(UserInfo.class);
|
UserInfo userInfo = mock(UserInfo.class);
|
||||||
given(userInfo.getSub()).willReturn(sub);
|
given(userInfo.getSub()).willReturn(sub);
|
||||||
return userInfo;
|
return userInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
private OAuth2AccessTokenEntity accessToken(Date exp, Set<String> scopes, String tokenType, OAuth2Authentication authentication) {
|
private OAuth2AccessTokenEntity accessToken(Date exp, Set<String> scopes, String tokenType, OAuth2Authentication authentication) {
|
||||||
OAuth2AccessTokenEntity accessToken = mock(OAuth2AccessTokenEntity.class, RETURNS_DEEP_STUBS);
|
OAuth2AccessTokenEntity accessToken = mock(OAuth2AccessTokenEntity.class, RETURNS_DEEP_STUBS);
|
||||||
given(accessToken.getExpiration()).willReturn(exp);
|
given(accessToken.getExpiration()).willReturn(exp);
|
||||||
given(accessToken.getScope()).willReturn(scopes);
|
given(accessToken.getScope()).willReturn(scopes);
|
||||||
given(accessToken.getTokenType()).willReturn(tokenType);
|
given(accessToken.getTokenType()).willReturn(tokenType);
|
||||||
given(accessToken.getAuthenticationHolder().getAuthentication()).willReturn(authentication);
|
given(accessToken.getAuthenticationHolder().getAuthentication()).willReturn(authentication);
|
||||||
return accessToken;
|
return accessToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
private OAuth2RefreshTokenEntity refreshToken(Date exp, OAuth2Authentication authentication) {
|
private OAuth2RefreshTokenEntity refreshToken(Date exp, OAuth2Authentication authentication) {
|
||||||
OAuth2RefreshTokenEntity refreshToken = mock(OAuth2RefreshTokenEntity.class, RETURNS_DEEP_STUBS);
|
OAuth2RefreshTokenEntity refreshToken = mock(OAuth2RefreshTokenEntity.class, RETURNS_DEEP_STUBS);
|
||||||
given(refreshToken.getExpiration()).willReturn(exp);
|
given(refreshToken.getExpiration()).willReturn(exp);
|
||||||
given(refreshToken.getAuthenticationHolder().getAuthentication()).willReturn(authentication);
|
given(refreshToken.getAuthenticationHolder().getAuthentication()).willReturn(authentication);
|
||||||
return refreshToken;
|
return refreshToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
private OAuth2Authentication authentication(String name, OAuth2Request request) {
|
|
||||||
OAuth2Authentication authentication = mock(OAuth2Authentication.class);
|
|
||||||
given(authentication.getName()).willReturn(name);
|
|
||||||
given(authentication.getOAuth2Request()).willReturn(request);
|
|
||||||
return authentication;
|
|
||||||
}
|
|
||||||
|
|
||||||
private OAuth2Request request(String clientId) {
|
private OAuth2Authentication authentication(String name, OAuth2Request request) {
|
||||||
return request(clientId, null);
|
OAuth2Authentication authentication = mock(OAuth2Authentication.class);
|
||||||
}
|
given(authentication.getName()).willReturn(name);
|
||||||
|
given(authentication.getOAuth2Request()).willReturn(request);
|
||||||
|
return authentication;
|
||||||
|
}
|
||||||
|
|
||||||
private OAuth2Request request(String clientId, Set<String> scopes) {
|
private OAuth2Request request(String clientId) {
|
||||||
return new OAuth2Request(null, clientId, null, true, scopes, null, null, null, null);
|
return request(clientId, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Set<String> scopes(String... scopes) {
|
private OAuth2Request request(String clientId, Set<String> scopes) {
|
||||||
return newHashSet(scopes);
|
return new OAuth2Request(null, clientId, null, true, scopes, null, null, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Set<String> scopes(String... scopes) {
|
||||||
|
return newHashSet(scopes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,31 +82,31 @@ public class TestDefaultOAuth2ClientDetailsEntityService {
|
||||||
@Before
|
@Before
|
||||||
public void prepare() {
|
public void prepare() {
|
||||||
Mockito.reset(clientRepository, tokenRepository, approvedSiteService, whitelistedSiteService, blacklistedSiteService, scopeService, statsService);
|
Mockito.reset(clientRepository, tokenRepository, approvedSiteService, whitelistedSiteService, blacklistedSiteService, scopeService, statsService);
|
||||||
|
|
||||||
Mockito.when(clientRepository.saveClient(Mockito.any(ClientDetailsEntity.class))).thenAnswer(new Answer<ClientDetailsEntity>() {
|
Mockito.when(clientRepository.saveClient(Matchers.any(ClientDetailsEntity.class))).thenAnswer(new Answer<ClientDetailsEntity>() {
|
||||||
@Override
|
@Override
|
||||||
public ClientDetailsEntity answer(InvocationOnMock invocation) throws Throwable {
|
public ClientDetailsEntity answer(InvocationOnMock invocation) throws Throwable {
|
||||||
Object[] args = invocation.getArguments();
|
Object[] args = invocation.getArguments();
|
||||||
return (ClientDetailsEntity) args[0];
|
return (ClientDetailsEntity) args[0];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Mockito.when(clientRepository.updateClient(Mockito.anyLong(), Mockito.any(ClientDetailsEntity.class))).thenAnswer(new Answer<ClientDetailsEntity>() {
|
Mockito.when(clientRepository.updateClient(Matchers.anyLong(), Matchers.any(ClientDetailsEntity.class))).thenAnswer(new Answer<ClientDetailsEntity>() {
|
||||||
@Override
|
@Override
|
||||||
public ClientDetailsEntity answer(InvocationOnMock invocation) throws Throwable {
|
public ClientDetailsEntity answer(InvocationOnMock invocation) throws Throwable {
|
||||||
Object[] args = invocation.getArguments();
|
Object[] args = invocation.getArguments();
|
||||||
return (ClientDetailsEntity) args[1];
|
return (ClientDetailsEntity) args[1];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Mockito.when(scopeService.removeRestrictedScopes(Mockito.anySet())).thenAnswer(new Answer<Set<String>>() {
|
Mockito.when(scopeService.removeRestrictedScopes(Matchers.anySet())).thenAnswer(new Answer<Set<String>>() {
|
||||||
@Override
|
@Override
|
||||||
public Set<String> answer(InvocationOnMock invocation) throws Throwable {
|
public Set<String> answer(InvocationOnMock invocation) throws Throwable {
|
||||||
Object[] args = invocation.getArguments();
|
Object[] args = invocation.getArguments();
|
||||||
return (Set<String>) args[0];
|
return (Set<String>) args[0];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -158,7 +158,7 @@ public class TestDefaultOAuth2ClientDetailsEntityService {
|
||||||
public void saveNewClient_yesOfflineAccess() {
|
public void saveNewClient_yesOfflineAccess() {
|
||||||
|
|
||||||
ClientDetailsEntity client = new ClientDetailsEntity();
|
ClientDetailsEntity client = new ClientDetailsEntity();
|
||||||
|
|
||||||
Set<String> grantTypes = new HashSet<String>();
|
Set<String> grantTypes = new HashSet<String>();
|
||||||
grantTypes.add("refresh_token");
|
grantTypes.add("refresh_token");
|
||||||
client.setGrantTypes(grantTypes);
|
client.setGrantTypes(grantTypes);
|
||||||
|
@ -175,7 +175,7 @@ public class TestDefaultOAuth2ClientDetailsEntityService {
|
||||||
public void saveNewClient_noOfflineAccess() {
|
public void saveNewClient_noOfflineAccess() {
|
||||||
|
|
||||||
ClientDetailsEntity client = new ClientDetailsEntity();
|
ClientDetailsEntity client = new ClientDetailsEntity();
|
||||||
|
|
||||||
client = service.saveNewClient(client);
|
client = service.saveNewClient(client);
|
||||||
|
|
||||||
assertThat(client.getScope().contains(SystemScopeService.OFFLINE_ACCESS), is(equalTo(false)));
|
assertThat(client.getScope().contains(SystemScopeService.OFFLINE_ACCESS), is(equalTo(false)));
|
||||||
|
@ -293,7 +293,7 @@ public class TestDefaultOAuth2ClientDetailsEntityService {
|
||||||
|
|
||||||
ClientDetailsEntity oldClient = new ClientDetailsEntity();
|
ClientDetailsEntity oldClient = new ClientDetailsEntity();
|
||||||
ClientDetailsEntity client = new ClientDetailsEntity();
|
ClientDetailsEntity client = new ClientDetailsEntity();
|
||||||
|
|
||||||
Set<String> grantTypes = new HashSet<String>();
|
Set<String> grantTypes = new HashSet<String>();
|
||||||
grantTypes.add("refresh_token");
|
grantTypes.add("refresh_token");
|
||||||
client.setGrantTypes(grantTypes);
|
client.setGrantTypes(grantTypes);
|
||||||
|
@ -307,11 +307,11 @@ public class TestDefaultOAuth2ClientDetailsEntityService {
|
||||||
public void updateClient_noOfflineAccess() {
|
public void updateClient_noOfflineAccess() {
|
||||||
|
|
||||||
ClientDetailsEntity oldClient = new ClientDetailsEntity();
|
ClientDetailsEntity oldClient = new ClientDetailsEntity();
|
||||||
|
|
||||||
oldClient.getScope().add(SystemScopeService.OFFLINE_ACCESS);
|
oldClient.getScope().add(SystemScopeService.OFFLINE_ACCESS);
|
||||||
|
|
||||||
ClientDetailsEntity client = new ClientDetailsEntity();
|
ClientDetailsEntity client = new ClientDetailsEntity();
|
||||||
|
|
||||||
client = service.updateClient(oldClient, client);
|
client = service.updateClient(oldClient, client);
|
||||||
|
|
||||||
assertThat(client.getScope().contains(SystemScopeService.OFFLINE_ACCESS), is(equalTo(false)));
|
assertThat(client.getScope().contains(SystemScopeService.OFFLINE_ACCESS), is(equalTo(false)));
|
||||||
|
|
|
@ -121,10 +121,10 @@ public class TestDefaultOAuth2ProviderTokenService {
|
||||||
|
|
||||||
// by default in tests, allow refresh tokens
|
// by default in tests, allow refresh tokens
|
||||||
Mockito.when(client.isAllowRefresh()).thenReturn(true);
|
Mockito.when(client.isAllowRefresh()).thenReturn(true);
|
||||||
|
|
||||||
badClient = Mockito.mock(ClientDetailsEntity.class);
|
badClient = Mockito.mock(ClientDetailsEntity.class);
|
||||||
Mockito.when(badClient.getClientId()).thenReturn(badClientId);
|
Mockito.when(badClient.getClientId()).thenReturn(badClientId);
|
||||||
Mockito.when(clientDetailsService.loadClientByClientId(badClientId)).thenReturn(badClient);
|
Mockito.when(clientDetailsService.loadClientByClientId(badClientId)).thenReturn(badClient);
|
||||||
|
|
||||||
refreshToken = Mockito.mock(OAuth2RefreshTokenEntity.class);
|
refreshToken = Mockito.mock(OAuth2RefreshTokenEntity.class);
|
||||||
Mockito.when(tokenRepository.getRefreshTokenByValue(refreshTokenValue)).thenReturn(refreshToken);
|
Mockito.when(tokenRepository.getRefreshTokenByValue(refreshTokenValue)).thenReturn(refreshToken);
|
||||||
|
@ -147,8 +147,8 @@ public class TestDefaultOAuth2ProviderTokenService {
|
||||||
Mockito.when(scopeService.removeRestrictedScopes(Matchers.anySet())).then(AdditionalAnswers.returnsFirstArg());
|
Mockito.when(scopeService.removeRestrictedScopes(Matchers.anySet())).then(AdditionalAnswers.returnsFirstArg());
|
||||||
|
|
||||||
Mockito.when(tokenEnhancer.enhance(Matchers.any(OAuth2AccessTokenEntity.class), Matchers.any(OAuth2Authentication.class)))
|
Mockito.when(tokenEnhancer.enhance(Matchers.any(OAuth2AccessTokenEntity.class), Matchers.any(OAuth2Authentication.class)))
|
||||||
.thenAnswer(new Answer<OAuth2AccessTokenEntity>(){
|
.thenAnswer(new Answer<OAuth2AccessTokenEntity>(){
|
||||||
@Override
|
@Override
|
||||||
public OAuth2AccessTokenEntity answer(InvocationOnMock invocation) throws Throwable {
|
public OAuth2AccessTokenEntity answer(InvocationOnMock invocation) throws Throwable {
|
||||||
Object[] args = invocation.getArguments();
|
Object[] args = invocation.getArguments();
|
||||||
return (OAuth2AccessTokenEntity) args[0];
|
return (OAuth2AccessTokenEntity) args[0];
|
||||||
|
@ -156,24 +156,24 @@ public class TestDefaultOAuth2ProviderTokenService {
|
||||||
});
|
});
|
||||||
|
|
||||||
Mockito.when(tokenRepository.saveAccessToken(Matchers.any(OAuth2AccessTokenEntity.class)))
|
Mockito.when(tokenRepository.saveAccessToken(Matchers.any(OAuth2AccessTokenEntity.class)))
|
||||||
.thenAnswer(new Answer<OAuth2AccessTokenEntity>() {
|
.thenAnswer(new Answer<OAuth2AccessTokenEntity>() {
|
||||||
@Override
|
@Override
|
||||||
public OAuth2AccessTokenEntity answer(InvocationOnMock invocation) throws Throwable {
|
public OAuth2AccessTokenEntity answer(InvocationOnMock invocation) throws Throwable {
|
||||||
Object[] args = invocation.getArguments();
|
Object[] args = invocation.getArguments();
|
||||||
return (OAuth2AccessTokenEntity) args[0];
|
return (OAuth2AccessTokenEntity) args[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Mockito.when(tokenRepository.saveRefreshToken(Matchers.any(OAuth2RefreshTokenEntity.class)))
|
Mockito.when(tokenRepository.saveRefreshToken(Matchers.any(OAuth2RefreshTokenEntity.class)))
|
||||||
.thenAnswer(new Answer<OAuth2RefreshTokenEntity>() {
|
.thenAnswer(new Answer<OAuth2RefreshTokenEntity>() {
|
||||||
@Override
|
@Override
|
||||||
public OAuth2RefreshTokenEntity answer(InvocationOnMock invocation) throws Throwable {
|
public OAuth2RefreshTokenEntity answer(InvocationOnMock invocation) throws Throwable {
|
||||||
Object[] args = invocation.getArguments();
|
Object[] args = invocation.getArguments();
|
||||||
return (OAuth2RefreshTokenEntity) args[0];
|
return (OAuth2RefreshTokenEntity) args[0];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -222,7 +222,7 @@ public class TestDefaultOAuth2ProviderTokenService {
|
||||||
|
|
||||||
Mockito.verify(clientDetailsService).loadClientByClientId(Matchers.anyString());
|
Mockito.verify(clientDetailsService).loadClientByClientId(Matchers.anyString());
|
||||||
Mockito.verify(authenticationHolderRepository).save(Matchers.any(AuthenticationHolderEntity.class));
|
Mockito.verify(authenticationHolderRepository).save(Matchers.any(AuthenticationHolderEntity.class));
|
||||||
Mockito.verify(tokenEnhancer).enhance(Matchers.any(OAuth2AccessTokenEntity.class), Mockito.eq(authentication));
|
Mockito.verify(tokenEnhancer).enhance(Matchers.any(OAuth2AccessTokenEntity.class), Matchers.eq(authentication));
|
||||||
Mockito.verify(tokenRepository).saveAccessToken(Matchers.any(OAuth2AccessTokenEntity.class));
|
Mockito.verify(tokenRepository).saveAccessToken(Matchers.any(OAuth2AccessTokenEntity.class));
|
||||||
|
|
||||||
Mockito.verify(tokenRepository, Mockito.never()).saveRefreshToken(Matchers.any(OAuth2RefreshTokenEntity.class));
|
Mockito.verify(tokenRepository, Mockito.never()).saveRefreshToken(Matchers.any(OAuth2RefreshTokenEntity.class));
|
||||||
|
@ -326,7 +326,7 @@ public class TestDefaultOAuth2ProviderTokenService {
|
||||||
|
|
||||||
service.refreshAccessToken(refreshTokenValue, tokenRequest);
|
service.refreshAccessToken(refreshTokenValue, tokenRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = InvalidTokenException.class)
|
@Test(expected = InvalidTokenException.class)
|
||||||
public void refreshAccessToken_expired() {
|
public void refreshAccessToken_expired() {
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -52,13 +52,13 @@ public class TestIdTokenHashUtils {
|
||||||
public void prepare() throws ParseException {
|
public void prepare() throws ParseException {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Claims for first token:
|
Claims for first token:
|
||||||
|
|
||||||
claims.setType("JWT");
|
claims.setType("JWT");
|
||||||
claims.setIssuer("www.example.com");
|
claims.setIssuer("www.example.com");
|
||||||
claims.setSubject("example_user");
|
claims.setSubject("example_user");
|
||||||
claims.setClaim("alg", "HS256");
|
claims.setClaim("alg", "HS256");
|
||||||
*/
|
*/
|
||||||
Mockito.when(mockToken256.getJwt()).thenReturn(JWTParser.parse("eyJhbGciOiJub25lIn0.eyJhbGciOiJIUzI1NiIsInN1YiI6ImV4YW1wbGVfdXNlciIsImlzcyI6Ind3dy5leGFtcGxlLmNvbSIsInR5cCI6IkpXVCJ9."));
|
Mockito.when(mockToken256.getJwt()).thenReturn(JWTParser.parse("eyJhbGciOiJub25lIn0.eyJhbGciOiJIUzI1NiIsInN1YiI6ImV4YW1wbGVfdXNlciIsImlzcyI6Ind3dy5leGFtcGxlLmNvbSIsInR5cCI6IkpXVCJ9."));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -85,12 +85,7 @@ public class TestIdTokenHashUtils {
|
||||||
@Test
|
@Test
|
||||||
public void getAccessTokenHash256() {
|
public void getAccessTokenHash256() {
|
||||||
|
|
||||||
/*
|
mockToken256.getJwt().serialize();
|
||||||
* independently generate hash
|
|
||||||
ascii of token = eyJhbGciOiJub25lIn0.eyJhbGciOiJIUzI1NiIsInN1YiI6ImV4YW1wbGVfdXNlciIsImlzcyI6Ind3dy5leGFtcGxlLmNvbSIsInR5cCI6IkpXVCJ9.
|
|
||||||
base64url of hash = EP1gXNeESRH-n57baopfTQ
|
|
||||||
*/
|
|
||||||
String token = mockToken256.getJwt().serialize();
|
|
||||||
Base64URL expectedHash = new Base64URL("EP1gXNeESRH-n57baopfTQ");
|
Base64URL expectedHash = new Base64URL("EP1gXNeESRH-n57baopfTQ");
|
||||||
|
|
||||||
Base64URL resultHash = IdTokenHashUtils.getAccessTokenHash(JWSAlgorithm.HS256, mockToken256);
|
Base64URL resultHash = IdTokenHashUtils.getAccessTokenHash(JWSAlgorithm.HS256, mockToken256);
|
||||||
|
@ -107,7 +102,7 @@ public class TestIdTokenHashUtils {
|
||||||
base64url of hash = BWfFK73PQI36M1rg9R6VjMyWOE0-XvBK
|
base64url of hash = BWfFK73PQI36M1rg9R6VjMyWOE0-XvBK
|
||||||
*/
|
*/
|
||||||
|
|
||||||
String token = mockToken384.getJwt().serialize();
|
mockToken384.getJwt().serialize();
|
||||||
Base64URL expectedHash = new Base64URL("BWfFK73PQI36M1rg9R6VjMyWOE0-XvBK");
|
Base64URL expectedHash = new Base64URL("BWfFK73PQI36M1rg9R6VjMyWOE0-XvBK");
|
||||||
|
|
||||||
Base64URL resultHash = IdTokenHashUtils.getAccessTokenHash(JWSAlgorithm.ES384, mockToken384);
|
Base64URL resultHash = IdTokenHashUtils.getAccessTokenHash(JWSAlgorithm.ES384, mockToken384);
|
||||||
|
@ -124,7 +119,7 @@ public class TestIdTokenHashUtils {
|
||||||
base64url of hash = vGH3QMY-knpACkLgzdkTqu3C9jtvbf2Wk_RSu2vAx8k
|
base64url of hash = vGH3QMY-knpACkLgzdkTqu3C9jtvbf2Wk_RSu2vAx8k
|
||||||
*/
|
*/
|
||||||
|
|
||||||
String token = mockToken512.getJwt().serialize();
|
mockToken512.getJwt().serialize();
|
||||||
Base64URL expectedHash = new Base64URL("vGH3QMY-knpACkLgzdkTqu3C9jtvbf2Wk_RSu2vAx8k");
|
Base64URL expectedHash = new Base64URL("vGH3QMY-knpACkLgzdkTqu3C9jtvbf2Wk_RSu2vAx8k");
|
||||||
|
|
||||||
Base64URL resultHash = IdTokenHashUtils.getAccessTokenHash(JWSAlgorithm.RS512, mockToken512);
|
Base64URL resultHash = IdTokenHashUtils.getAccessTokenHash(JWSAlgorithm.RS512, mockToken512);
|
||||||
|
|
Loading…
Reference in New Issue