added flag to allow introspection, relaxed same-client restrictions on introspection and chained tokens

pull/263/head
Justin Richer 12 years ago
parent 6eabc895b9
commit 18ddd8333f

@ -64,8 +64,9 @@ public class ClientDetailsEntity implements ClientDetails {
/** Our own fields **/ /** Our own fields **/
private String clientDescription = ""; // human-readable description private String clientDescription = ""; // human-readable description
private boolean allowMultipleAccessTokens = false; // do we allow multiple access tokens, or not? private boolean allowMultipleAccessTokens = false; // do we allow multiple access tokens, or not?
private boolean reuseRefreshToken = false; // do we let someone reuse a refresh token? private boolean reuseRefreshToken = true; // do we let someone reuse a refresh token?
private boolean dynamicallyRegistered = false; // was this client dynamically registered? private boolean dynamicallyRegistered = false; // was this client dynamically registered?
private boolean allowIntrospection = false; // do we let this client call the introspection endpoint?
private Integer idTokenValiditySeconds; //timeout for id tokens private Integer idTokenValiditySeconds; //timeout for id tokens
/** Fields from ClientDetails interface **/ /** Fields from ClientDetails interface **/
@ -301,6 +302,22 @@ public class ClientDetailsEntity implements ClientDetails {
/**
* @return the allowIntrospection
*/
@Basic
@Column(name="allow_introspection")
public boolean isAllowIntrospection() {
return allowIntrospection;
}
/**
* @param allowIntrospection the allowIntrospection to set
*/
public void setAllowIntrospection(boolean allowIntrospection) {
this.allowIntrospection = allowIntrospection;
}
/** /**
* If the clientSecret is not null, then it is always required. * If the clientSecret is not null, then it is always required.
*/ */

@ -76,13 +76,6 @@ public class ChainedTokenGranter extends AbstractTokenGranter {
requestedScopes = new HashSet<String>(); requestedScopes = new HashSet<String>();
} }
// Check the incoming client id against the client that was issued the original token
// TODO: right now, this only lets a client chain a request, not a resource server. We need
// a way to let one client get a token chained from another client's token, securely.
if (!client.getClientId().equals(authorizationRequest.getClientId())) {
throw new InvalidClientException("Not the right client for this token");
}
// if our scopes are a valid subset of what's allowed, we can continue // if our scopes are a valid subset of what's allowed, we can continue
if (approvedScopes.containsAll(requestedScopes)) { if (approvedScopes.containsAll(requestedScopes)) {

@ -26,6 +26,7 @@ import org.mitre.oauth2.service.OAuth2TokenEntityService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.oauth2.common.exceptions.InvalidClientException; import org.springframework.security.oauth2.common.exceptions.InvalidClientException;
import org.springframework.security.oauth2.common.exceptions.InvalidScopeException;
import org.springframework.security.oauth2.common.exceptions.InvalidTokenException; import org.springframework.security.oauth2.common.exceptions.InvalidTokenException;
import org.springframework.security.oauth2.provider.OAuth2Authentication; import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetails; import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetails;
@ -102,14 +103,20 @@ public class IntrospectionEndpoint {
ClientDetailsEntity authClient = clientService.loadClientByClientId(clientId); ClientDetailsEntity authClient = clientService.loadClientByClientId(clientId);
if (tokenClient != null && authClient != null) { if (tokenClient != null && authClient != null) {
if (Objects.equal(authClient, tokenClient)) { // TODO: this lets a client introspect but not an RS if (authClient.isAllowIntrospection()) {
// if it's a valid token, we'll print out information on it // if it's the same client that the token was issued to, or it at least has all the scopes the token was issued with
modelAndView.setViewName("tokenIntrospection"); if (authClient.equals(tokenClient) || authClient.getScope().containsAll(token.getScope())) {
modelAndView.addObject("entity", token);
return modelAndView; // if it's a valid token, we'll print out information on it
modelAndView.setViewName("tokenIntrospection");
modelAndView.addObject("entity", token);
return modelAndView;
} else {
throw new InvalidScopeException("Tried to introspect a token of different scope");
}
} else { } else {
throw new InvalidClientException("Clients did not match."); throw new InvalidClientException("Clients can't introspect.");
} }
} else { } else {
throw new InvalidClientException("No client found."); throw new InvalidClientException("No client found.");

@ -72,6 +72,7 @@ CREATE TABLE IF NOT EXISTS client_details (
allow_multiple_access_tokens BOOLEAN NOT NULL DEFAULT true, allow_multiple_access_tokens BOOLEAN NOT NULL DEFAULT true,
reuse_refresh_tokens BOOLEAN NOT NULL DEFAULT true, reuse_refresh_tokens BOOLEAN NOT NULL DEFAULT true,
dynamically_registered BOOLEAN NOT NULL DEFAULT false, dynamically_registered BOOLEAN NOT NULL DEFAULT false,
allow_introspection BOOLEAN NOT NULL DEFAULT false,
id_token_validity_seconds BIGINT, id_token_validity_seconds BIGINT,
client_id VARCHAR(256), client_id VARCHAR(256),

@ -64,9 +64,10 @@ CREATE TABLE blacklisted_site (
CREATE TABLE client_details ( CREATE TABLE client_details (
id BIGINT AUTO_INCREMENT PRIMARY KEY, id BIGINT AUTO_INCREMENT PRIMARY KEY,
client_description VARCHAR(256), client_description VARCHAR(256),
allow_multiple_access_tokens TINYINT NOT NULL DEFAULT 0, allow_multiple_access_tokens BOOLEAN NOT NULL DEFAULT 0,
reuse_refresh_tokens TINYINT NOT NULL DEFAULT 0, reuse_refresh_tokens BOOLEAN NOT NULL DEFAULT 1,
dynamically_registered TINYINT NOT NULL DEFAULT 0, dynamically_registered BOOLEAN NOT NULL DEFAULT 0,
allow_introspection BOOLEAN NOT NULL DEFAULT 0,
id_token_validity_seconds BIGINT, id_token_validity_seconds BIGINT,
client_id VARCHAR(256), client_id VARCHAR(256),
@ -103,7 +104,7 @@ CREATE TABLE client_details (
id_token_encrypted_response_int VARCHAR(256), id_token_encrypted_response_int VARCHAR(256),
default_max_age BIGINT, default_max_age BIGINT,
require_auth_time TINYINT NOT NULL DEFAULT 0, require_auth_time BOOLEAN NOT NULL DEFAULT 0,
default_acr VARCHAR(256) default_acr VARCHAR(256)
); );

Loading…
Cancel
Save