Applied code cleanup

pull/477/head
Amanda Anganes 2013-07-12 16:58:41 -04:00
parent 3e23967b46
commit 15aea61fbe
160 changed files with 15273 additions and 9048 deletions

View File

@ -27,178 +27,178 @@ import com.google.gson.JsonParser;
public class IntrospectingTokenService implements ResourceServerTokenServices { public class IntrospectingTokenService implements ResourceServerTokenServices {
private String clientId;
private String clientSecret;
private String introspectionUrl;
// Inner class to store in the hash map
private class TokenCacheObject { OAuth2AccessToken token; OAuth2Authentication auth;
private TokenCacheObject(OAuth2AccessToken token, OAuth2Authentication auth) {
this.token = token;
this.auth = auth;
}
}
private Map<String, TokenCacheObject> authCache = new HashMap<String, TokenCacheObject>();
public String getIntrospectionUrl() { private String clientId;
return introspectionUrl; private String clientSecret;
} private String introspectionUrl;
public void setIntrospectionUrl(String introspectionUrl) { // Inner class to store in the hash map
this.introspectionUrl = introspectionUrl; private class TokenCacheObject { OAuth2AccessToken token; OAuth2Authentication auth;
} private TokenCacheObject(OAuth2AccessToken token, OAuth2Authentication auth) {
this.token = token;
this.auth = auth;
}
}
private Map<String, TokenCacheObject> authCache = new HashMap<String, TokenCacheObject>();
public String getClientId() { public String getIntrospectionUrl() {
return clientId; return introspectionUrl;
} }
public void setClientId(String clientId) { public void setIntrospectionUrl(String introspectionUrl) {
this.clientId = clientId; this.introspectionUrl = introspectionUrl;
} }
public String getClientSecret() { public String getClientId() {
return clientSecret; return clientId;
} }
public void setClientSecret(String clientSecret) { public void setClientId(String clientId) {
this.clientSecret = clientSecret; this.clientId = clientId;
} }
// Check if there is a token and authentication in the cache
// and check if it is not expired.
private TokenCacheObject checkCache(String key) {
if(authCache.containsKey(key)) {
TokenCacheObject tco = authCache.get(key);
if (tco.token.getExpiration().after(new Date())) {
return tco;
} else {
// if the token is expired, don't keep things around.
authCache.remove(key);
}
}
return null;
}
private OAuth2Request createStoredRequest(final JsonObject token) {
clientId = token.get("client_id").getAsString();
Set<String> scopes = new HashSet<String>();
for (JsonElement e : token.get("scope").getAsJsonArray()) {
scopes.add(e.getAsString());
}
Map<String, String> parameters = new HashMap<String, String>();
parameters.put("client_id", clientId);
parameters.put("scope", OAuth2Utils.formatParameterList(scopes));
OAuth2Request storedRequest = new OAuth2Request(parameters, clientId, null, true, scopes, null, null, null);
return storedRequest;
}
// create a default authentication object with authority ROLE_API
private Authentication createAuthentication(JsonObject token){
// TODO: make role/authority configurable somehow
return new PreAuthenticatedAuthenticationToken(token.get("subject").getAsString(), null, AuthorityUtils.createAuthorityList("ROLE_API"));
}
private OAuth2AccessToken createAccessToken(final JsonObject token, final String tokenString){
OAuth2AccessToken accessToken = new OAuth2AccessTokenImpl(token, tokenString);
return accessToken;
}
// Validate a token string against the introspection endpoint,
// then parse it and store it in the local cache. Return true on
// sucess, false otherwise.
private boolean parseToken(String accessToken) {
String validatedToken = null;
// Use the SpringFramework RestTemplate to send the request to the endpoint
RestTemplate restTemplate = new RestTemplate();
MultiValueMap<String, String> form = new LinkedMultiValueMap<String, String>();
form.add("token",accessToken);
form.add("client_id", this.clientId);
form.add("client_secret", this.clientSecret);
try {
validatedToken = restTemplate.postForObject(introspectionUrl, form, String.class);
} catch (RestClientException rce) {
// TODO: LOG THIS!?
LoggerFactory.getLogger(IntrospectingTokenService.class).error("validateToken", rce);
}
if (validatedToken != null) {
// parse the json
JsonElement jsonRoot = new JsonParser().parse(validatedToken);
if (!jsonRoot.isJsonObject()) {
return false; // didn't get a proper JSON object
}
JsonObject tokenResponse = jsonRoot.getAsJsonObject();
if (tokenResponse.get("error") != null) {
// report an error?
return false;
}
if (!tokenResponse.get("valid").getAsBoolean()){
// non-valid token
return false;
}
// create an OAuth2Authentication
OAuth2Authentication auth = new OAuth2Authentication(createStoredRequest(tokenResponse), createAuthentication(tokenResponse));
// create an OAuth2AccessToken
OAuth2AccessToken token = createAccessToken(tokenResponse, accessToken);
if (token.getExpiration().after(new Date())){
// Store them in the cache
authCache.put(accessToken, new TokenCacheObject(token,auth));
return true;
}
}
// If we never put a token and an authentication in the cache...
return false;
}
@Override
public OAuth2Authentication loadAuthentication(String accessToken) throws AuthenticationException {
// First check if the in memory cache has an Authentication object, and that it is still valid
// If Valid, return it
TokenCacheObject cacheAuth = checkCache(accessToken);
if (cacheAuth != null) {
return cacheAuth.auth;
} else {
if (parseToken(accessToken)) {
cacheAuth = authCache.get(accessToken);
if (cacheAuth != null && (cacheAuth.token.getExpiration().after(new Date()))) {
return cacheAuth.auth;
} else {
return null;
}
} else {
return null;
}
}
}
@Override public String getClientSecret() {
public OAuth2AccessToken readAccessToken(String accessToken) { return clientSecret;
// First check if the in memory cache has a Token object, and that it is still valid }
// If Valid, return it
TokenCacheObject cacheAuth = checkCache(accessToken); public void setClientSecret(String clientSecret) {
if (cacheAuth != null) { this.clientSecret = clientSecret;
return cacheAuth.token; }
} else {
if (parseToken(accessToken)) { // Check if there is a token and authentication in the cache
cacheAuth = authCache.get(accessToken); // and check if it is not expired.
if (cacheAuth != null && (cacheAuth.token.getExpiration().after(new Date()))) { private TokenCacheObject checkCache(String key) {
return cacheAuth.token; if(authCache.containsKey(key)) {
} else { TokenCacheObject tco = authCache.get(key);
return null; if (tco.token.getExpiration().after(new Date())) {
} return tco;
} else { } else {
return null; // if the token is expired, don't keep things around.
} authCache.remove(key);
} }
} }
return null;
}
private OAuth2Request createStoredRequest(final JsonObject token) {
clientId = token.get("client_id").getAsString();
Set<String> scopes = new HashSet<String>();
for (JsonElement e : token.get("scope").getAsJsonArray()) {
scopes.add(e.getAsString());
}
Map<String, String> parameters = new HashMap<String, String>();
parameters.put("client_id", clientId);
parameters.put("scope", OAuth2Utils.formatParameterList(scopes));
OAuth2Request storedRequest = new OAuth2Request(parameters, clientId, null, true, scopes, null, null, null);
return storedRequest;
}
// create a default authentication object with authority ROLE_API
private Authentication createAuthentication(JsonObject token){
// TODO: make role/authority configurable somehow
return new PreAuthenticatedAuthenticationToken(token.get("subject").getAsString(), null, AuthorityUtils.createAuthorityList("ROLE_API"));
}
private OAuth2AccessToken createAccessToken(final JsonObject token, final String tokenString){
OAuth2AccessToken accessToken = new OAuth2AccessTokenImpl(token, tokenString);
return accessToken;
}
// Validate a token string against the introspection endpoint,
// then parse it and store it in the local cache. Return true on
// sucess, false otherwise.
private boolean parseToken(String accessToken) {
String validatedToken = null;
// Use the SpringFramework RestTemplate to send the request to the endpoint
RestTemplate restTemplate = new RestTemplate();
MultiValueMap<String, String> form = new LinkedMultiValueMap<String, String>();
form.add("token",accessToken);
form.add("client_id", this.clientId);
form.add("client_secret", this.clientSecret);
try {
validatedToken = restTemplate.postForObject(introspectionUrl, form, String.class);
} catch (RestClientException rce) {
// TODO: LOG THIS!?
LoggerFactory.getLogger(IntrospectingTokenService.class).error("validateToken", rce);
}
if (validatedToken != null) {
// parse the json
JsonElement jsonRoot = new JsonParser().parse(validatedToken);
if (!jsonRoot.isJsonObject()) {
return false; // didn't get a proper JSON object
}
JsonObject tokenResponse = jsonRoot.getAsJsonObject();
if (tokenResponse.get("error") != null) {
// report an error?
return false;
}
if (!tokenResponse.get("valid").getAsBoolean()){
// non-valid token
return false;
}
// create an OAuth2Authentication
OAuth2Authentication auth = new OAuth2Authentication(createStoredRequest(tokenResponse), createAuthentication(tokenResponse));
// create an OAuth2AccessToken
OAuth2AccessToken token = createAccessToken(tokenResponse, accessToken);
if (token.getExpiration().after(new Date())){
// Store them in the cache
authCache.put(accessToken, new TokenCacheObject(token,auth));
return true;
}
}
// If we never put a token and an authentication in the cache...
return false;
}
@Override
public OAuth2Authentication loadAuthentication(String accessToken) throws AuthenticationException {
// First check if the in memory cache has an Authentication object, and that it is still valid
// If Valid, return it
TokenCacheObject cacheAuth = checkCache(accessToken);
if (cacheAuth != null) {
return cacheAuth.auth;
} else {
if (parseToken(accessToken)) {
cacheAuth = authCache.get(accessToken);
if (cacheAuth != null && (cacheAuth.token.getExpiration().after(new Date()))) {
return cacheAuth.auth;
} else {
return null;
}
} else {
return null;
}
}
}
@Override
public OAuth2AccessToken readAccessToken(String accessToken) {
// First check if the in memory cache has a Token object, and that it is still valid
// If Valid, return it
TokenCacheObject cacheAuth = checkCache(accessToken);
if (cacheAuth != null) {
return cacheAuth.token;
} else {
if (parseToken(accessToken)) {
cacheAuth = authCache.get(accessToken);
if (cacheAuth != null && (cacheAuth.token.getExpiration().after(new Date()))) {
return cacheAuth.token;
} else {
return null;
}
} else {
return null;
}
}
}
} }

View File

@ -20,73 +20,73 @@ import com.google.gson.JsonObject;
public class OAuth2AccessTokenImpl implements OAuth2AccessToken { public class OAuth2AccessTokenImpl implements OAuth2AccessToken {
private JsonObject token; private JsonObject token;
private String tokenString; private String tokenString;
private Set<String> scopes = null; private Set<String> scopes = null;
private Date expireDate; private Date expireDate;
public OAuth2AccessTokenImpl(JsonObject token, String tokenString) {
this.token = token;
this.tokenString = tokenString;
scopes = new HashSet<String>();
for (JsonElement e : token.get("scope").getAsJsonArray()) {
scopes.add(e.getAsString());
}
DateFormat dateFormater = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
try {
expireDate = dateFormater.parse(token.get("expires_at").getAsString());
} catch (ParseException ex) {
Logger.getLogger(IntrospectingTokenService.class.getName()).log(Level.SEVERE, null, ex);
}
}
@Override public OAuth2AccessTokenImpl(JsonObject token, String tokenString) {
public Map<String, Object> getAdditionalInformation() { this.token = token;
return null; this.tokenString = tokenString;
} scopes = new HashSet<String>();
for (JsonElement e : token.get("scope").getAsJsonArray()) {
scopes.add(e.getAsString());
}
@Override DateFormat dateFormater = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
public Set<String> getScope() { try {
return scopes; expireDate = dateFormater.parse(token.get("expires_at").getAsString());
} } catch (ParseException ex) {
Logger.getLogger(IntrospectingTokenService.class.getName()).log(Level.SEVERE, null, ex);
}
}
@Override
public OAuth2RefreshToken getRefreshToken() {
return null;
}
@Override @Override
public String getTokenType() { public Map<String, Object> getAdditionalInformation() {
return BEARER_TYPE; return null;
} }
@Override @Override
public boolean isExpired() { public Set<String> getScope() {
if (expireDate != null && expireDate.before(new Date())) { return scopes;
return true; }
}
return false;
}
@Override @Override
public Date getExpiration() { public OAuth2RefreshToken getRefreshToken() {
return expireDate; return null;
} }
@Override @Override
public int getExpiresIn() { public String getTokenType() {
if (expireDate != null) { return BEARER_TYPE;
return (int)TimeUnit.MILLISECONDS.toSeconds(expireDate.getTime() - (new Date()).getTime()); }
}
return 0;
}
@Override @Override
public String getValue() { public boolean isExpired() {
return tokenString; if (expireDate != null && expireDate.before(new Date())) {
} return true;
}
return false;
}
@Override
public Date getExpiration() {
return expireDate;
}
@Override
public int getExpiresIn() {
if (expireDate != null) {
return (int)TimeUnit.MILLISECONDS.toSeconds(expireDate.getTime() - (new Date()).getTime());
}
return 0;
}
@Override
public String getValue() {
return tokenString;
}
} }

View File

@ -20,8 +20,6 @@ import java.math.BigInteger;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.text.ParseException; import java.text.ParseException;
import java.util.Date; import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@ -29,8 +27,6 @@ import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.client.DefaultHttpClient;
import org.mitre.jwt.signer.service.JwtSigningAndValidationService; import org.mitre.jwt.signer.service.JwtSigningAndValidationService;
import org.mitre.jwt.signer.service.impl.JWKSetSigningAndValidationServiceCacheService; import org.mitre.jwt.signer.service.impl.JWKSetSigningAndValidationServiceCacheService;
@ -74,7 +70,7 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi
protected final static int HTTP_SOCKET_TIMEOUT = 30000; protected final static int HTTP_SOCKET_TIMEOUT = 30000;
protected final static String FILTER_PROCESSES_URL = "/openid_connect_login"; protected final static String FILTER_PROCESSES_URL = "/openid_connect_login";
// Allow for time sync issues by having a window of X seconds. // Allow for time sync issues by having a window of X seconds.
private int timeSkewAllowance = 300; private int timeSkewAllowance = 300;
@ -86,7 +82,7 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi
private ClientConfigurationService clients; private ClientConfigurationService clients;
private IssuerService issuerService; private IssuerService issuerService;
private AuthRequestUrlBuilder authRequestBuilder; private AuthRequestUrlBuilder authRequestBuilder;
protected int httpSocketTimeout = HTTP_SOCKET_TIMEOUT; protected int httpSocketTimeout = HTTP_SOCKET_TIMEOUT;
/** /**
@ -119,18 +115,18 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi
// there's an error coming back from the server, need to handle this // there's an error coming back from the server, need to handle this
handleError(request, response); handleError(request, response);
return null; // no auth, response is sent to display page or something return null; // no auth, response is sent to display page or something
} else if (!Strings.isNullOrEmpty(request.getParameter("code"))) { } else if (!Strings.isNullOrEmpty(request.getParameter("code"))) {
// we got back the code, need to process this to get our tokens // we got back the code, need to process this to get our tokens
Authentication auth = handleAuthorizationCodeResponse(request, response); Authentication auth = handleAuthorizationCodeResponse(request, response);
return auth; return auth;
} else { } else {
// not an error, not a code, must be an initial login of some type // not an error, not a code, must be an initial login of some type
handleAuthorizationRequest(request, response); handleAuthorizationRequest(request, response);
return null; // no auth, response redirected to the server's Auth Endpoint (or possibly to the account chooser) return null; // no auth, response redirected to the server's Auth Endpoint (or possibly to the account chooser)
} }
@ -149,33 +145,33 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi
protected void handleAuthorizationRequest(HttpServletRequest request, HttpServletResponse response) throws IOException { protected void handleAuthorizationRequest(HttpServletRequest request, HttpServletResponse response) throws IOException {
HttpSession session = request.getSession(); HttpSession session = request.getSession();
IssuerServiceResponse issResp = issuerService.getIssuer(request); IssuerServiceResponse issResp = issuerService.getIssuer(request);
if (issResp.shouldRedirect()) { if (issResp.shouldRedirect()) {
response.sendRedirect(issResp.getRedirectUrl()); response.sendRedirect(issResp.getRedirectUrl());
} else { } else {
String issuer = issResp.getIssuer(); String issuer = issResp.getIssuer();
session.setAttribute(ISSUER_SESSION_VARIABLE, issuer); session.setAttribute(ISSUER_SESSION_VARIABLE, issuer);
ServerConfiguration serverConfig = servers.getServerConfiguration(issuer); ServerConfiguration serverConfig = servers.getServerConfiguration(issuer);
ClientDetails clientConfig = clients.getClientConfiguration(issuer); ClientDetails clientConfig = clients.getClientConfiguration(issuer);
// our redirect URI is this current URL, with no query parameters // our redirect URI is this current URL, with no query parameters
String redirectUri = request.getRequestURL().toString(); String redirectUri = request.getRequestURL().toString();
session.setAttribute(REDIRECT_URI_SESION_VARIABLE, redirectUri); session.setAttribute(REDIRECT_URI_SESION_VARIABLE, redirectUri);
// this value comes back in the id token and is checked there // this value comes back in the id token and is checked there
String nonce = createNonce(session); String nonce = createNonce(session);
// this value comes back in the auth code response // this value comes back in the auth code response
String state = createState(session); String state = createState(session);
String authRequest = authRequestBuilder.buildAuthRequestUrl(serverConfig, clientConfig, redirectUri, nonce, state); String authRequest = authRequestBuilder.buildAuthRequestUrl(serverConfig, clientConfig, redirectUri, nonce, state);
logger.debug("Auth Request: " + authRequest); logger.debug("Auth Request: " + authRequest);
response.sendRedirect(authRequest); response.sendRedirect(authRequest);
} }
} }
@ -190,9 +186,9 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi
protected Authentication handleAuthorizationCodeResponse(HttpServletRequest request, HttpServletResponse response) { protected Authentication handleAuthorizationCodeResponse(HttpServletRequest request, HttpServletResponse response) {
String authorizationCode = request.getParameter("code"); String authorizationCode = request.getParameter("code");
HttpSession session = request.getSession(); HttpSession session = request.getSession();
// check for state, if it doesn't match we bail early // check for state, if it doesn't match we bail early
String storedState = getStoredState(session); String storedState = getStoredState(session);
if (!StringUtils.isBlank(storedState)) { if (!StringUtils.isBlank(storedState)) {
@ -204,20 +200,20 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi
// look up the issuer that we set out to talk to // look up the issuer that we set out to talk to
String issuer = getStoredSessionString(session, ISSUER_SESSION_VARIABLE); String issuer = getStoredSessionString(session, ISSUER_SESSION_VARIABLE);
// pull the configurations based on that issuer // pull the configurations based on that issuer
ServerConfiguration serverConfig = servers.getServerConfiguration(issuer); ServerConfiguration serverConfig = servers.getServerConfiguration(issuer);
ClientDetails clientConfig = clients.getClientConfiguration(issuer); ClientDetails clientConfig = clients.getClientConfiguration(issuer);
MultiValueMap<String, String> form = new LinkedMultiValueMap<String, String>(); MultiValueMap<String, String> form = new LinkedMultiValueMap<String, String>();
form.add("grant_type", "authorization_code"); form.add("grant_type", "authorization_code");
form.add("code", authorizationCode); form.add("code", authorizationCode);
String redirectUri = getStoredSessionString(session, REDIRECT_URI_SESION_VARIABLE); String redirectUri = getStoredSessionString(session, REDIRECT_URI_SESION_VARIABLE);
if (redirectUri != null) { if (redirectUri != null) {
form.add("redirect_uri", redirectUri); form.add("redirect_uri", redirectUri);
} }
// Handle Token Endpoint interaction // Handle Token Endpoint interaction
DefaultHttpClient httpClient = new DefaultHttpClient(); DefaultHttpClient httpClient = new DefaultHttpClient();
@ -232,7 +228,7 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi
*/ */
form.add("client_id", clientConfig.getClientId()); form.add("client_id", clientConfig.getClientId());
form.add("client_secret", clientConfig.getClientSecret()); form.add("client_secret", clientConfig.getClientSecret());
/**/ /**/
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient); HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);
@ -257,14 +253,14 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi
} }
logger.debug("from TokenEndpoint jsonString = " + jsonString); logger.debug("from TokenEndpoint jsonString = " + jsonString);
JsonElement jsonRoot = new JsonParser().parse(jsonString); JsonElement jsonRoot = new JsonParser().parse(jsonString);
if (!jsonRoot.isJsonObject()) { if (!jsonRoot.isJsonObject()) {
throw new AuthenticationServiceException("Token Endpoint did not return a JSON object: " + jsonRoot); throw new AuthenticationServiceException("Token Endpoint did not return a JSON object: " + jsonRoot);
} }
JsonObject tokenResponse = jsonRoot.getAsJsonObject(); JsonObject tokenResponse = jsonRoot.getAsJsonObject();
if (tokenResponse.get("error") != null) { if (tokenResponse.get("error") != null) {
// Handle error // Handle error
@ -279,125 +275,125 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi
// Extract the id_token to insert into the // Extract the id_token to insert into the
// OIDCAuthenticationToken // OIDCAuthenticationToken
// get out all the token strings // get out all the token strings
String accessTokenValue = null; String accessTokenValue = null;
String idTokenValue = null; String idTokenValue = null;
String refreshTokenValue = null; String refreshTokenValue = null;
if (tokenResponse.has("access_token")) { if (tokenResponse.has("access_token")) {
accessTokenValue = tokenResponse.get("access_token").getAsString(); accessTokenValue = tokenResponse.get("access_token").getAsString();
} else { } else {
throw new AuthenticationServiceException("Token Endpoint did not return an access_token: " + jsonString); throw new AuthenticationServiceException("Token Endpoint did not return an access_token: " + jsonString);
} }
if (tokenResponse.has("id_token")) { if (tokenResponse.has("id_token")) {
idTokenValue = tokenResponse.get("id_token").getAsString(); idTokenValue = tokenResponse.get("id_token").getAsString();
} else { } else {
logger.error("Token Endpoint did not return an id_token"); logger.error("Token Endpoint did not return an id_token");
throw new AuthenticationServiceException("Token Endpoint did not return an id_token"); throw new AuthenticationServiceException("Token Endpoint did not return an id_token");
} }
if (tokenResponse.has("refresh_token")) { if (tokenResponse.has("refresh_token")) {
refreshTokenValue = tokenResponse.get("refresh_token").getAsString(); refreshTokenValue = tokenResponse.get("refresh_token").getAsString();
} }
try { try {
SignedJWT idToken = SignedJWT.parse(idTokenValue); SignedJWT idToken = SignedJWT.parse(idTokenValue);
// validate our ID Token over a number of tests // validate our ID Token over a number of tests
ReadOnlyJWTClaimsSet idClaims = idToken.getJWTClaimsSet(); ReadOnlyJWTClaimsSet idClaims = idToken.getJWTClaimsSet();
// check the signature
JwtSigningAndValidationService jwtValidator = validationServices.get(serverConfig.getJwksUri());
if (jwtValidator != null) {
if(!jwtValidator.validateSignature(idToken)) {
throw new AuthenticationServiceException("Signature validation failed");
}
} else {
logger.info("No validation service found. Skipping signature validation");
}
// check the issuer
if (idClaims.getIssuer() == null) {
throw new AuthenticationServiceException("Id Token Issuer is null");
} else if (!idClaims.getIssuer().equals(serverConfig.getIssuer())){
throw new AuthenticationServiceException("Issuers do not match, expected " + serverConfig.getIssuer() + " got " + idClaims.getIssuer());
}
// check expiration
if (idClaims.getExpirationTime() == null) {
throw new AuthenticationServiceException("Id Token does not have required expiration claim");
} else {
// it's not null, see if it's expired
Date now = new Date(System.currentTimeMillis() - (timeSkewAllowance * 1000));
if (now.after(idClaims.getExpirationTime())) {
throw new AuthenticationServiceException("Id Token is expired: " + idClaims.getExpirationTime());
}
}
// check not before
if (idClaims.getNotBeforeTime() != null) {
Date now = new Date(System.currentTimeMillis() + (timeSkewAllowance * 1000));
if (now.before(idClaims.getNotBeforeTime())){
throw new AuthenticationServiceException("Id Token not valid untill: " + idClaims.getNotBeforeTime());
}
}
// check issued at
if (idClaims.getIssueTime() == null) {
throw new AuthenticationServiceException("Id Token does not have required issued-at claim");
} else {
// since it's not null, see if it was issued in the future
Date now = new Date(System.currentTimeMillis() + (timeSkewAllowance * 1000));
if (now.before(idClaims.getIssueTime())) {
throw new AuthenticationServiceException("Id Token was issued in the future: " + idClaims.getIssueTime());
}
}
// check audience
if (idClaims.getAudience() == null) {
throw new AuthenticationServiceException("Id token audience is null");
} else if (!idClaims.getAudience().contains(clientConfig.getClientId())) {
throw new AuthenticationServiceException("Audience does not match, expected " + clientConfig.getClientId() + " got " + idClaims.getAudience());
}
// compare the nonce to our stored claim
// FIXME: Nimbus claims as strings?
String nonce = (String) idClaims.getCustomClaim("nonce");
if (StringUtils.isBlank(nonce)) {
logger.error("ID token did not contain a nonce claim.");
throw new AuthenticationServiceException("ID token did not contain a nonce claim."); // check the signature
} JwtSigningAndValidationService jwtValidator = validationServices.get(serverConfig.getJwksUri());
if (jwtValidator != null) {
if(!jwtValidator.validateSignature(idToken)) {
throw new AuthenticationServiceException("Signature validation failed");
}
} else {
logger.info("No validation service found. Skipping signature validation");
}
String storedNonce = getStoredNonce(session); // check the issuer
if (!nonce.equals(storedNonce)) { if (idClaims.getIssuer() == null) {
logger.error("Possible replay attack detected! The comparison of the nonce in the returned " throw new AuthenticationServiceException("Id Token Issuer is null");
+ "ID Token to the session " + NONCE_SESSION_VARIABLE + " failed. Expected " + storedNonce + " got " + nonce + "."); } else if (!idClaims.getIssuer().equals(serverConfig.getIssuer())){
throw new AuthenticationServiceException("Issuers do not match, expected " + serverConfig.getIssuer() + " got " + idClaims.getIssuer());
}
throw new AuthenticationServiceException( // check expiration
"Possible replay attack detected! The comparison of the nonce in the returned " if (idClaims.getExpirationTime() == null) {
+ "ID Token to the session " + NONCE_SESSION_VARIABLE + " failed. Expected " + storedNonce + " got " + nonce + "."); throw new AuthenticationServiceException("Id Token does not have required expiration claim");
} } else {
// it's not null, see if it's expired
Date now = new Date(System.currentTimeMillis() - (timeSkewAllowance * 1000));
if (now.after(idClaims.getExpirationTime())) {
throw new AuthenticationServiceException("Id Token is expired: " + idClaims.getExpirationTime());
}
}
// pull the subject (user id) out as a claim on the id_token // check not before
if (idClaims.getNotBeforeTime() != null) {
String userId = idClaims.getSubject(); Date now = new Date(System.currentTimeMillis() + (timeSkewAllowance * 1000));
if (now.before(idClaims.getNotBeforeTime())){
// construct an OIDCAuthenticationToken and return a Authentication object w/the userId and the idToken throw new AuthenticationServiceException("Id Token not valid untill: " + idClaims.getNotBeforeTime());
}
OIDCAuthenticationToken token = new OIDCAuthenticationToken(userId, idClaims.getIssuer(), serverConfig, idTokenValue, accessTokenValue, refreshTokenValue); }
Authentication authentication = this.getAuthenticationManager().authenticate(token); // check issued at
if (idClaims.getIssueTime() == null) {
throw new AuthenticationServiceException("Id Token does not have required issued-at claim");
} else {
// since it's not null, see if it was issued in the future
Date now = new Date(System.currentTimeMillis() + (timeSkewAllowance * 1000));
if (now.before(idClaims.getIssueTime())) {
throw new AuthenticationServiceException("Id Token was issued in the future: " + idClaims.getIssueTime());
}
}
// check audience
if (idClaims.getAudience() == null) {
throw new AuthenticationServiceException("Id token audience is null");
} else if (!idClaims.getAudience().contains(clientConfig.getClientId())) {
throw new AuthenticationServiceException("Audience does not match, expected " + clientConfig.getClientId() + " got " + idClaims.getAudience());
}
// compare the nonce to our stored claim
// FIXME: Nimbus claims as strings?
String nonce = (String) idClaims.getCustomClaim("nonce");
if (StringUtils.isBlank(nonce)) {
logger.error("ID token did not contain a nonce claim.");
throw new AuthenticationServiceException("ID token did not contain a nonce claim.");
}
String storedNonce = getStoredNonce(session);
if (!nonce.equals(storedNonce)) {
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 + ".");
throw new AuthenticationServiceException(
"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 + ".");
}
// pull the subject (user id) out as a claim on the id_token
String userId = idClaims.getSubject();
// construct an OIDCAuthenticationToken and return a Authentication object w/the userId and the idToken
OIDCAuthenticationToken token = new OIDCAuthenticationToken(userId, idClaims.getIssuer(), serverConfig, idTokenValue, accessTokenValue, refreshTokenValue);
Authentication authentication = this.getAuthenticationManager().authenticate(token);
return authentication;
} catch (ParseException e) {
throw new AuthenticationServiceException("Couldn't parse idToken: ", e);
}
return authentication;
} catch (ParseException e) {
throw new AuthenticationServiceException("Couldn't parse idToken: ", e);
}
} }
} }
@ -436,7 +432,7 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi
return null; return null;
} }
} }
/** /**
* Create a cryptographically random nonce and store it in the session * Create a cryptographically random nonce and store it in the session
* @param session * @param session
@ -457,7 +453,7 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi
protected static String getStoredNonce(HttpSession session) { protected static String getStoredNonce(HttpSession session) {
return getStoredSessionString(session, NONCE_SESSION_VARIABLE); return getStoredSessionString(session, NONCE_SESSION_VARIABLE);
} }
/** /**
* Create a cryptographically random state and store it in the session * Create a cryptographically random state and store it in the session
* @param session * @param session
@ -466,10 +462,10 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi
protected static String createState(HttpSession session) { protected static String createState(HttpSession session) {
String state = new BigInteger(50, new SecureRandom()).toString(16); String state = new BigInteger(50, new SecureRandom()).toString(16);
session.setAttribute(STATE_SESSION_VARIABLE, state); session.setAttribute(STATE_SESSION_VARIABLE, state);
return state; return state;
} }
/** /**
* Get the state we stored in the session * Get the state we stored in the session
* @param session * @param session
@ -478,14 +474,14 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi
protected static String getStoredState(HttpSession session) { protected static String getStoredState(HttpSession session) {
return getStoredSessionString(session, STATE_SESSION_VARIABLE); return getStoredSessionString(session, STATE_SESSION_VARIABLE);
} }
// //
// Getters and setters for configuration variables // Getters and setters for configuration variables
// //
public int getTimeSkewAllowance() { public int getTimeSkewAllowance() {
return timeSkewAllowance; return timeSkewAllowance;
} }
@ -562,6 +558,6 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi
*/ */
public void setAuthRequestUrlBuilder(AuthRequestUrlBuilder authRequestBuilder) { public void setAuthRequestUrlBuilder(AuthRequestUrlBuilder authRequestBuilder) {
this.authRequestBuilder = authRequestBuilder; this.authRequestBuilder = authRequestBuilder;
} }
} }

View File

@ -35,10 +35,10 @@ import com.google.common.collect.Sets;
* *
*/ */
public class OIDCAuthenticationProvider implements public class OIDCAuthenticationProvider implements
AuthenticationProvider, InitializingBean { AuthenticationProvider, InitializingBean {
private UserInfoFetcher userInfoFetcher = new UserInfoFetcher(); private UserInfoFetcher userInfoFetcher = new UserInfoFetcher();
private GrantedAuthoritiesMapper authoritiesMapper = new NullAuthoritiesMapper(); private GrantedAuthoritiesMapper authoritiesMapper = new NullAuthoritiesMapper();
/* /*
@ -70,22 +70,22 @@ public class OIDCAuthenticationProvider implements
// Default authorities set // Default authorities set
// TODO: let this be configured // TODO: let this be configured
Collection<SimpleGrantedAuthority> authorities = Sets.newHashSet(new SimpleGrantedAuthority("ROLE_USER")); Collection<SimpleGrantedAuthority> authorities = Sets.newHashSet(new SimpleGrantedAuthority("ROLE_USER"));
OIDCAuthenticationToken token = (OIDCAuthenticationToken) authentication; OIDCAuthenticationToken token = (OIDCAuthenticationToken) authentication;
UserInfo userInfo = userInfoFetcher.loadUserInfo(token); UserInfo userInfo = userInfoFetcher.loadUserInfo(token);
if (userInfo == null) { if (userInfo == null) {
// TODO: user Info not found -- error? // TODO: user Info not found -- error?
} else { } else {
if (!Strings.isNullOrEmpty(userInfo.getSub()) && !userInfo.getSub().equals(token.getUserId())) { if (!Strings.isNullOrEmpty(userInfo.getSub()) && !userInfo.getSub().equals(token.getUserId())) {
// the userinfo came back and the user_id fields don't match what was in the id_token // the userinfo came back and the user_id fields don't match what was in the id_token
throw new UsernameNotFoundException("user_id mismatch between id_token and user_info call: " + userInfo.getSub() + " / " + token.getUserId()); throw new UsernameNotFoundException("user_id mismatch between id_token and user_info call: " + userInfo.getSub() + " / " + token.getUserId());
} }
} }
return new OIDCAuthenticationToken(token.getUserId(), return new OIDCAuthenticationToken(token.getUserId(),
token.getIssuer(), token.getIssuer(),
userInfo, authoritiesMapper.mapAuthorities(authorities), userInfo, authoritiesMapper.mapAuthorities(authorities),
token.getIdTokenValue(), token.getAccessTokenValue(), token.getRefreshTokenValue()); token.getIdTokenValue(), token.getAccessTokenValue(), token.getRefreshTokenValue());
} }

View File

@ -32,8 +32,8 @@ import com.google.common.collect.ImmutableMap;
*/ */
public class OIDCAuthenticationToken extends AbstractAuthenticationToken { public class OIDCAuthenticationToken extends AbstractAuthenticationToken {
private static final long serialVersionUID = 22100073066377804L; private static final long serialVersionUID = 22100073066377804L;
private final Object principal; private final Object principal;
private final String idTokenValue; // string representation of the id token private final String idTokenValue; // string representation of the id token
private final String accessTokenValue; // string representation of the access token private final String accessTokenValue; // string representation of the access token
@ -43,7 +43,7 @@ public class OIDCAuthenticationToken extends AbstractAuthenticationToken {
private final transient ServerConfiguration serverConfiguration; // server configuration used to fulfill this token, don't serialize it private final transient ServerConfiguration serverConfiguration; // server configuration used to fulfill this token, don't serialize it
private final transient UserInfo userInfo; // user info container, don't serialize it b/c it might be huge and can be re-fetched private final transient UserInfo userInfo; // user info container, don't serialize it b/c it might be huge and can be re-fetched
/** /**
* Constructs OIDCAuthenticationToken with a full set of authorities, marking this as authenticated. * Constructs OIDCAuthenticationToken with a full set of authorities, marking this as authenticated.
* *
@ -55,7 +55,7 @@ public class OIDCAuthenticationToken extends AbstractAuthenticationToken {
* @param principal * @param principal
* @param idToken * @param idToken
*/ */
public OIDCAuthenticationToken(String userId, String issuer, public OIDCAuthenticationToken(String userId, String issuer,
UserInfo userInfo, Collection<? extends GrantedAuthority> authorities, UserInfo userInfo, Collection<? extends GrantedAuthority> authorities,
String idTokenValue, String accessTokenValue, String refreshTokenValue) { String idTokenValue, String accessTokenValue, String refreshTokenValue) {
@ -70,12 +70,12 @@ public class OIDCAuthenticationToken extends AbstractAuthenticationToken {
this.refreshTokenValue = refreshTokenValue; this.refreshTokenValue = refreshTokenValue;
this.serverConfiguration = null; // we don't need a server config anymore this.serverConfiguration = null; // we don't need a server config anymore
setAuthenticated(true); setAuthenticated(true);
} }
/** /**
* Constructs OIDCAuthenticationToken for use as a data shuttle from the filter to the auth provider. * Constructs OIDCAuthenticationToken for use as a data shuttle from the filter to the auth provider.
* *
* Set to not-authenticated. * Set to not-authenticated.
* *
@ -83,8 +83,8 @@ public class OIDCAuthenticationToken extends AbstractAuthenticationToken {
* @param userId * @param userId
* @param idToken * @param idToken
*/ */
public OIDCAuthenticationToken(String userId, String issuer, public OIDCAuthenticationToken(String userId, String issuer,
ServerConfiguration serverConfiguration, ServerConfiguration serverConfiguration,
String idTokenValue, String accessTokenValue, String refreshTokenValue) { String idTokenValue, String accessTokenValue, String refreshTokenValue) {
super(new ArrayList<GrantedAuthority>(0)); super(new ArrayList<GrantedAuthority>(0));
@ -97,10 +97,10 @@ public class OIDCAuthenticationToken extends AbstractAuthenticationToken {
this.refreshTokenValue = refreshTokenValue; this.refreshTokenValue = refreshTokenValue;
this.userInfo = null; // we don't have a UserInfo yet this.userInfo = null; // we don't have a UserInfo yet
this.serverConfiguration = serverConfiguration; this.serverConfiguration = serverConfiguration;
setAuthenticated(false); setAuthenticated(false);
} }
@ -130,46 +130,46 @@ public class OIDCAuthenticationToken extends AbstractAuthenticationToken {
} }
/** /**
* @return the idTokenValue * @return the idTokenValue
*/ */
public String getIdTokenValue() { public String getIdTokenValue() {
return idTokenValue; return idTokenValue;
} }
/** /**
* @return the accessTokenValue * @return the accessTokenValue
*/ */
public String getAccessTokenValue() { public String getAccessTokenValue() {
return accessTokenValue; return accessTokenValue;
} }
/** /**
* @return the refreshTokenValue * @return the refreshTokenValue
*/ */
public String getRefreshTokenValue() { public String getRefreshTokenValue() {
return refreshTokenValue; return refreshTokenValue;
} }
/** /**
* @return the serverConfiguration * @return the serverConfiguration
*/ */
public ServerConfiguration getServerConfiguration() { public ServerConfiguration getServerConfiguration() {
return serverConfiguration; return serverConfiguration;
} }
/** /**
* @return the issuer * @return the issuer
*/ */
public String getIssuer() { public String getIssuer() {
return issuer; return issuer;
} }
/** /**
* @return the userInfo * @return the userInfo
*/ */
public UserInfo getUserInfo() { public UserInfo getUserInfo() {
return userInfo; return userInfo;
} }
} }

View File

@ -15,7 +15,7 @@ import com.google.gson.JsonParser;
public class UserInfoFetcher { public class UserInfoFetcher {
public UserInfo loadUserInfo(OIDCAuthenticationToken token) { public UserInfo loadUserInfo(OIDCAuthenticationToken token) {
HttpClient httpClient = new DefaultHttpClient(); HttpClient httpClient = new DefaultHttpClient();
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient); HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);
@ -25,15 +25,15 @@ public class UserInfoFetcher {
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());
form.add("schema", "openid"); form.add("schema", "openid");
String userInfoString = restTemplate.postForObject(token.getServerConfiguration().getUserInfoUri(), form, String.class); String userInfoString = restTemplate.postForObject(token.getServerConfiguration().getUserInfoUri(), form, String.class);
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;
} }
} }

View File

@ -34,16 +34,16 @@ public class ClientKeyPublisher implements BeanDefinitionRegistryPostProcessor {
/** /**
* If either the jwkPublishUrl or x509PublishUrl fields are set on this bean, set up a listener on that URL to publish keys. * If either the jwkPublishUrl or x509PublishUrl fields are set on this bean, set up a listener on that URL to publish keys.
*/ */
@Override @Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
if (!Strings.isNullOrEmpty(getJwkPublishUrl())) { if (!Strings.isNullOrEmpty(getJwkPublishUrl())) {
// add a mapping to this class // add a mapping to this class
BeanDefinitionBuilder clientKeyMapping = BeanDefinitionBuilder.rootBeanDefinition(ClientKeyPublisherMapping.class); BeanDefinitionBuilder clientKeyMapping = BeanDefinitionBuilder.rootBeanDefinition(ClientKeyPublisherMapping.class);
// custom view resolver // custom view resolver
BeanDefinitionBuilder viewResolver = BeanDefinitionBuilder.rootBeanDefinition(JwkViewResolver.class); BeanDefinitionBuilder viewResolver = BeanDefinitionBuilder.rootBeanDefinition(JwkViewResolver.class);
if (!Strings.isNullOrEmpty(getJwkPublishUrl())) { if (!Strings.isNullOrEmpty(getJwkPublishUrl())) {
clientKeyMapping.addPropertyValue("jwkPublishUrl", getJwkPublishUrl()); clientKeyMapping.addPropertyValue("jwkPublishUrl", getJwkPublishUrl());
@ -56,49 +56,49 @@ public class ClientKeyPublisher implements BeanDefinitionRegistryPostProcessor {
registry.registerBeanDefinition("jwkKeyList", jwkView.getBeanDefinition()); registry.registerBeanDefinition("jwkKeyList", jwkView.getBeanDefinition());
viewResolver.addPropertyReference("jwk", "jwkKeyList"); viewResolver.addPropertyReference("jwk", "jwkKeyList");
} }
registry.registerBeanDefinition("clientKeyMapping", clientKeyMapping.getBeanDefinition()); registry.registerBeanDefinition("clientKeyMapping", clientKeyMapping.getBeanDefinition());
registry.registerBeanDefinition("jwkViewResolver", viewResolver.getBeanDefinition()); registry.registerBeanDefinition("jwkViewResolver", viewResolver.getBeanDefinition());
} }
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry(org.springframework.beans.factory.support.BeanDefinitionRegistry) * @see org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry(org.springframework.beans.factory.support.BeanDefinitionRegistry)
*/ */
@Override @Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
this.registry = registry; this.registry = registry;
} }
/** /**
* Return a view to publish all keys in JWK format. Only used if jwkPublishUrl is set. * Return a view to publish all keys in JWK format. Only used if jwkPublishUrl is set.
* @return * @return
*/ */
public ModelAndView publishClientJwk() { public ModelAndView publishClientJwk() {
// map from key id to key // map from key id to key
Map<String, JWK> keys = signingAndValidationService.getAllPublicKeys(); Map<String, JWK> keys = signingAndValidationService.getAllPublicKeys();
// TODO: check if keys are empty, return a 404 here or just an empty list? // TODO: check if keys are empty, return a 404 here or just an empty list?
return new ModelAndView(jwkViewName, "keys", keys); return new ModelAndView(jwkViewName, "keys", keys);
} }
/** /**
* @return the jwkPublishUrl * @return the jwkPublishUrl
*/ */
public String getJwkPublishUrl() { public String getJwkPublishUrl() {
return jwkPublishUrl; return jwkPublishUrl;
} }
/** /**
* @param jwkPublishUrl the jwkPublishUrl to set * @param jwkPublishUrl the jwkPublishUrl to set
*/ */
public void setJwkPublishUrl(String jwkPublishUrl) { public void setJwkPublishUrl(String jwkPublishUrl) {
this.jwkPublishUrl = jwkPublishUrl; this.jwkPublishUrl = jwkPublishUrl;
} }
/** /**
* @return the signingAndValidationService * @return the signingAndValidationService

View File

@ -19,72 +19,72 @@ public class ClientKeyPublisherMapping extends RequestMappingInfoHandlerMapping
private String jwkPublishUrl; private String jwkPublishUrl;
private String x509PublishUrl; private String x509PublishUrl;
/* (non-Javadoc) /* (non-Javadoc)
* @see org.springframework.web.servlet.handler.AbstractHandlerMethodMapping#isHandler(java.lang.Class) * @see org.springframework.web.servlet.handler.AbstractHandlerMethodMapping#isHandler(java.lang.Class)
*/ */
@Override @Override
protected boolean isHandler(Class<?> beanType) { protected boolean isHandler(Class<?> beanType) {
return beanType.equals(ClientKeyPublisher.class); return beanType.equals(ClientKeyPublisher.class);
} }
/** /**
* Map the "jwkKeyPublish" method to our jwkPublishUrl. * Map the "jwkKeyPublish" method to our jwkPublishUrl.
* Map the "x509KeyPublish" method to our x509PublishUrl. * Map the "x509KeyPublish" method to our x509PublishUrl.
*/ */
@Override @Override
protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) { protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {
if (method.getName().equals("publishClientJwk") && getJwkPublishUrl() != null) { if (method.getName().equals("publishClientJwk") && getJwkPublishUrl() != null) {
return new RequestMappingInfo( return new RequestMappingInfo(
new PatternsRequestCondition(new String[] {getJwkPublishUrl()}, getUrlPathHelper(), getPathMatcher(), false, false), new PatternsRequestCondition(new String[] {getJwkPublishUrl()}, getUrlPathHelper(), getPathMatcher(), false, false),
null, null,
null, null,
null, null,
null, null,
null, null,
null); null);
} else if (method.getName().equals("publishClientx509") && getX509PublishUrl() != null) { } else if (method.getName().equals("publishClientx509") && getX509PublishUrl() != null) {
return new RequestMappingInfo( return new RequestMappingInfo(
new PatternsRequestCondition(new String[] {getX509PublishUrl()}, getUrlPathHelper(), getPathMatcher(), false, false), new PatternsRequestCondition(new String[] {getX509PublishUrl()}, getUrlPathHelper(), getPathMatcher(), false, false),
null, null,
null, null,
null, null,
null, null,
null, null,
null); null);
} else { } else {
return null; return null;
} }
} }
/** /**
* @return the jwkPublishUrl * @return the jwkPublishUrl
*/ */
public String getJwkPublishUrl() { public String getJwkPublishUrl() {
return jwkPublishUrl; return jwkPublishUrl;
} }
/** /**
* @param jwkPublishUrl the jwkPublishUrl to set * @param jwkPublishUrl the jwkPublishUrl to set
*/ */
public void setJwkPublishUrl(String jwkPublishUrl) { public void setJwkPublishUrl(String jwkPublishUrl) {
this.jwkPublishUrl = jwkPublishUrl; this.jwkPublishUrl = jwkPublishUrl;
} }
/** /**
* @return the x509PublishUrl * @return the x509PublishUrl
*/ */
public String getX509PublishUrl() { public String getX509PublishUrl() {
return x509PublishUrl; return x509PublishUrl;
} }
/** /**
* @param x509PublishUrl the x509PublishUrl to set * @param x509PublishUrl the x509PublishUrl to set
*/ */
public void setX509PublishUrl(String x509PublishUrl) { public void setX509PublishUrl(String x509PublishUrl) {
this.x509PublishUrl = x509PublishUrl; this.x509PublishUrl = x509PublishUrl;
} }
} }

View File

@ -20,12 +20,12 @@ public class JwkViewResolver implements ViewResolver, Ordered {
private String jwkViewName = "jwkKeyList"; private String jwkViewName = "jwkKeyList";
private View jwk; private View jwk;
private String x509ViewName = "x509certs"; private String x509ViewName = "x509certs";
private View x509; private View x509;
private int order = HIGHEST_PRECEDENCE; // highest precedence, most specific -- avoids hitting the catch-all view resolvers private int order = HIGHEST_PRECEDENCE; // highest precedence, most specific -- avoids hitting the catch-all view resolvers
/** /**
* Map "jwkKeyList" to the jwk property and "x509certs" to the x509 property on this bean. * Map "jwkKeyList" to the jwk property and "x509certs" to the x509 property on this bean.
* Everything else returns null * Everything else returns null
@ -46,74 +46,74 @@ public class JwkViewResolver implements ViewResolver, Ordered {
} }
/** /**
* @return the x509 * @return the x509
*/ */
public View getX509() { public View getX509() {
return x509; return x509;
} }
/** /**
* @param x509 the x509 to set * @param x509 the x509 to set
*/ */
public void setX509(View x509) { public void setX509(View x509) {
this.x509 = x509; this.x509 = x509;
} }
/** /**
* @return the jwk * @return the jwk
*/ */
public View getJwk() { public View getJwk() {
return jwk; return jwk;
} }
/** /**
* @param jwk the jwk to set * @param jwk the jwk to set
*/ */
public void setJwk(View jwk) { public void setJwk(View jwk) {
this.jwk = jwk; this.jwk = jwk;
} }
/** /**
* @return the order * @return the order
*/ */
@Override @Override
public int getOrder() { public int getOrder() {
return order; return order;
} }
/** /**
* @param order the order to set * @param order the order to set
*/ */
public void setOrder(int order) { public void setOrder(int order) {
this.order = order; this.order = order;
} }
/** /**
* @return the jwkViewName * @return the jwkViewName
*/ */
public String getJwkViewName() { public String getJwkViewName() {
return jwkViewName; return jwkViewName;
} }
/** /**
* @param jwkViewName the jwkViewName to set * @param jwkViewName the jwkViewName to set
*/ */
public void setJwkViewName(String jwkViewName) { public void setJwkViewName(String jwkViewName) {
this.jwkViewName = jwkViewName; this.jwkViewName = jwkViewName;
} }
/** /**
* @return the x509ViewName * @return the x509ViewName
*/ */
public String getX509ViewName() { public String getX509ViewName() {
return x509ViewName; return x509ViewName;
} }
/** /**
* @param x509ViewName the x509ViewName to set * @param x509ViewName the x509ViewName to set
*/ */
public void setX509ViewName(String x509ViewName) { public void setX509ViewName(String x509ViewName) {
this.x509ViewName = x509ViewName; this.x509ViewName = x509ViewName;
} }
} }

View File

@ -16,24 +16,24 @@ public class IssuerServiceResponse {
private String loginHint; private String loginHint;
private String targetLinkUri; private String targetLinkUri;
private String redirectUrl; private String redirectUrl;
/** /**
* @param issuer * @param issuer
* @param loginHint * @param loginHint
* @param targetLinkUri * @param targetLinkUri
*/ */
public IssuerServiceResponse(String issuer, String loginHint, String targetLinkUri) { public IssuerServiceResponse(String issuer, String loginHint, String targetLinkUri) {
this.issuer = issuer; this.issuer = issuer;
this.loginHint = loginHint; this.loginHint = loginHint;
this.targetLinkUri = targetLinkUri; this.targetLinkUri = targetLinkUri;
} }
/** /**
* @param redirectUrl * @param redirectUrl
*/ */
public IssuerServiceResponse(String redirectUrl) { public IssuerServiceResponse(String redirectUrl) {
this.redirectUrl = redirectUrl; this.redirectUrl = redirectUrl;
} }
/** /**
* @return the issuer * @return the issuer
*/ */
@ -82,12 +82,12 @@ public class IssuerServiceResponse {
public void setRedirectUrl(String redirectUrl) { public void setRedirectUrl(String redirectUrl) {
this.redirectUrl = redirectUrl; this.redirectUrl = redirectUrl;
} }
/** /**
* If the redirect url has been set, then we should send a redirect using it instead of processing things. * If the redirect url has been set, then we should send a redirect using it instead of processing things.
*/ */
public boolean shouldRedirect() { public boolean shouldRedirect() {
return this.redirectUrl != null; return this.redirectUrl != null;
} }
} }

View File

@ -20,6 +20,6 @@ public interface AuthRequestUrlBuilder {
* @param state * @param state
* @return * @return
*/ */
public String buildAuthRequestUrl(ServerConfiguration serverConfig, ClientDetails clientConfig, String redirectUri, String nonce, String state); public String buildAuthRequestUrl(ServerConfiguration serverConfig, ClientDetails clientConfig, String redirectUri, String nonce, String state);
} }

View File

@ -12,5 +12,5 @@ import org.springframework.security.oauth2.provider.ClientDetails;
public interface ClientConfigurationService { public interface ClientConfigurationService {
public ClientDetails getClientConfiguration(String issuer); public ClientDetails getClientConfiguration(String issuer);
} }

View File

@ -17,5 +17,5 @@ import org.mitre.openid.connect.client.model.IssuerServiceResponse;
public interface IssuerService { public interface IssuerService {
public IssuerServiceResponse getIssuer(HttpServletRequest request); public IssuerServiceResponse getIssuer(HttpServletRequest request);
} }

View File

@ -12,5 +12,5 @@ import org.mitre.openid.connect.config.ServerConfiguration;
public interface ServerConfigurationService { public interface ServerConfigurationService {
public ServerConfiguration getServerConfiguration(String issuer); public ServerConfiguration getServerConfiguration(String issuer);
} }

View File

@ -28,7 +28,7 @@ public class PlainAuthRequestUrlBuilder implements AuthRequestUrlBuilder {
@Override @Override
public String buildAuthRequestUrl(ServerConfiguration serverConfig, ClientDetails clientConfig, String redirectUri, String nonce, String state) { public String buildAuthRequestUrl(ServerConfiguration serverConfig, ClientDetails clientConfig, String redirectUri, String nonce, String state) {
try { try {
URIBuilder uriBuilder = new URIBuilder(serverConfig.getAuthorizationEndpointUri()); URIBuilder uriBuilder = new URIBuilder(serverConfig.getAuthorizationEndpointUri());
uriBuilder.addParameter("response_type", "code"); uriBuilder.addParameter("response_type", "code");
uriBuilder.addParameter("client_id", clientConfig.getClientId()); uriBuilder.addParameter("client_id", clientConfig.getClientId());
@ -39,20 +39,20 @@ public class PlainAuthRequestUrlBuilder implements AuthRequestUrlBuilder {
uriBuilder.addParameter("nonce", nonce); uriBuilder.addParameter("nonce", nonce);
uriBuilder.addParameter("state", state); uriBuilder.addParameter("state", state);
// Optional parameters: // Optional parameters:
// TODO: display, prompt // TODO: display, prompt
return uriBuilder.build().toString();
} catch (URISyntaxException e) {
throw new AuthenticationServiceException("Malformed Authorization Endpoint Uri", e);
}
return uriBuilder.build().toString();
} catch (URISyntaxException e) {
throw new AuthenticationServiceException("Malformed Authorization Endpoint Uri", e);
}
} }
} }

View File

@ -4,11 +4,6 @@
package org.mitre.openid.connect.client.service.impl; package org.mitre.openid.connect.client.service.impl;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.security.NoSuchAlgorithmException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.http.client.utils.URIBuilder; import org.apache.http.client.utils.URIBuilder;
import org.mitre.jwt.signer.service.JwtSigningAndValidationService; import org.mitre.jwt.signer.service.JwtSigningAndValidationService;
@ -38,34 +33,34 @@ public class SignedAuthRequestUrlBuilder implements AuthRequestUrlBuilder {
// create our signed JWT for the request object // create our signed JWT for the request object
JWTClaimsSet claims = new JWTClaimsSet(); JWTClaimsSet claims = new JWTClaimsSet();
//set parameters to JwtClaims //set parameters to JwtClaims
claims.setCustomClaim("response_type", "code"); claims.setCustomClaim("response_type", "code");
claims.setCustomClaim("client_id", clientConfig.getClientId()); claims.setCustomClaim("client_id", clientConfig.getClientId());
claims.setCustomClaim("scope", Joiner.on(" ").join(clientConfig.getScope())); claims.setCustomClaim("scope", Joiner.on(" ").join(clientConfig.getScope()));
// build our redirect URI // build our redirect URI
claims.setCustomClaim("redirect_uri", redirectUri); claims.setCustomClaim("redirect_uri", redirectUri);
// this comes back in the id token // this comes back in the id token
claims.setCustomClaim("nonce", nonce); claims.setCustomClaim("nonce", nonce);
// this comes back in the auth request return // this comes back in the auth request return
claims.setCustomClaim("state", state); claims.setCustomClaim("state", state);
SignedJWT jwt = new SignedJWT(new JWSHeader(signingAndValidationService.getDefaultSigningAlgorithm()), claims); SignedJWT jwt = new SignedJWT(new JWSHeader(signingAndValidationService.getDefaultSigningAlgorithm()), claims);
signingAndValidationService.signJwt(jwt); signingAndValidationService.signJwt(jwt);
try { try {
URIBuilder uriBuilder = new URIBuilder(serverConfig.getAuthorizationEndpointUri()); URIBuilder uriBuilder = new URIBuilder(serverConfig.getAuthorizationEndpointUri());
uriBuilder.addParameter("request", jwt.serialize()); uriBuilder.addParameter("request", jwt.serialize());
// build out the URI // build out the URI
return uriBuilder.build().toString(); return uriBuilder.build().toString();
} catch (URISyntaxException e) { } catch (URISyntaxException e) {
throw new AuthenticationServiceException("Malformed Authorization Endpoint Uri", e); throw new AuthenticationServiceException("Malformed Authorization Endpoint Uri", e);
} }
} }
/** /**

View File

@ -21,7 +21,7 @@ public class StaticClientConfigurationService implements ClientConfigurationServ
// Map of issuer URL -> client configuration information // Map of issuer URL -> client configuration information
private Map<String, ClientDetails> clients; private Map<String, ClientDetails> clients;
/** /**
* @return the clients * @return the clients
*/ */
@ -43,19 +43,19 @@ public class StaticClientConfigurationService implements ClientConfigurationServ
*/ */
@Override @Override
public ClientDetails getClientConfiguration(String issuer) { public ClientDetails getClientConfiguration(String issuer) {
return clients.get(issuer); return clients.get(issuer);
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/ */
@Override @Override
public void afterPropertiesSet() throws Exception { public void afterPropertiesSet() throws Exception {
if (clients == null || clients.isEmpty()) { if (clients == null || clients.isEmpty()) {
throw new IllegalArgumentException("Clients map cannot be null or empty"); throw new IllegalArgumentException("Clients map cannot be null or empty");
} }
} }
} }

View File

@ -45,12 +45,12 @@ public class StaticServerConfigurationService implements ServerConfigurationServ
/* (non-Javadoc) /* (non-Javadoc)
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/ */
@Override @Override
public void afterPropertiesSet() throws Exception { public void afterPropertiesSet() throws Exception {
if (servers == null || servers.isEmpty()) { if (servers == null || servers.isEmpty()) {
throw new IllegalArgumentException("Servers map cannot be null or empty."); throw new IllegalArgumentException("Servers map cannot be null or empty.");
} }
} }
} }

View File

@ -16,7 +16,7 @@ import com.google.common.base.Strings;
* *
*/ */
public class StaticSingleIssuerService implements IssuerService, InitializingBean { public class StaticSingleIssuerService implements IssuerService, InitializingBean {
private String issuer; private String issuer;
/** /**
@ -46,13 +46,13 @@ public class StaticSingleIssuerService implements IssuerService, InitializingBea
/* (non-Javadoc) /* (non-Javadoc)
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/ */
@Override @Override
public void afterPropertiesSet() throws Exception { public void afterPropertiesSet() throws Exception {
if (Strings.isNullOrEmpty(issuer)) { if (Strings.isNullOrEmpty(issuer)) {
throw new IllegalArgumentException("Issuer must not be null or empty."); throw new IllegalArgumentException("Issuer must not be null or empty.");
} }
} }
} }

View File

@ -25,34 +25,34 @@ import com.google.common.base.Strings;
public class ThirdPartyIssuerService implements IssuerService, InitializingBean { public class ThirdPartyIssuerService implements IssuerService, InitializingBean {
private String accountChooserUrl; private String accountChooserUrl;
/* (non-Javadoc) /* (non-Javadoc)
* @see org.mitre.openid.connect.client.service.IssuerService#getIssuer(javax.servlet.http.HttpServletRequest) * @see org.mitre.openid.connect.client.service.IssuerService#getIssuer(javax.servlet.http.HttpServletRequest)
*/ */
@Override @Override
public IssuerServiceResponse getIssuer(HttpServletRequest request) { public IssuerServiceResponse getIssuer(HttpServletRequest request) {
// if the issuer is passed in, return that // if the issuer is passed in, return that
if (!Strings.isNullOrEmpty(request.getParameter("iss"))) { if (!Strings.isNullOrEmpty(request.getParameter("iss"))) {
return new IssuerServiceResponse(request.getParameter("iss"), request.getParameter("login_hint"), request.getParameter("target_link_uri")); return new IssuerServiceResponse(request.getParameter("iss"), request.getParameter("login_hint"), request.getParameter("target_link_uri"));
} else { } else {
try { try {
// otherwise, need to forward to the account chooser // otherwise, need to forward to the account chooser
String redirectUri = request.getRequestURL().toString(); String redirectUri = request.getRequestURL().toString();
URIBuilder builder = new URIBuilder(accountChooserUrl); URIBuilder builder = new URIBuilder(accountChooserUrl);
builder.addParameter("redirect_uri", redirectUri); builder.addParameter("redirect_uri", redirectUri);
return new IssuerServiceResponse(builder.build().toString()); return new IssuerServiceResponse(builder.build().toString());
} catch (URISyntaxException e) { } catch (URISyntaxException e) {
throw new AuthenticationServiceException("Account Chooser URL is not valid", e); throw new AuthenticationServiceException("Account Chooser URL is not valid", e);
} }
} }
} }
/** /**
@ -72,12 +72,12 @@ public class ThirdPartyIssuerService implements IssuerService, InitializingBean
/* (non-Javadoc) /* (non-Javadoc)
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/ */
@Override @Override
public void afterPropertiesSet() throws Exception { public void afterPropertiesSet() throws Exception {
if (Strings.isNullOrEmpty(this.accountChooserUrl)) { if (Strings.isNullOrEmpty(this.accountChooserUrl)) {
throw new IllegalArgumentException("Account Chooser URL cannot be null or empty"); throw new IllegalArgumentException("Account Chooser URL cannot be null or empty");
} }
} }
} }

View File

@ -1,10 +1,5 @@
package org.mitre.openid.connect.client; package org.mitre.openid.connect.client;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/** /**
* Unit test for OIDCAuthenticationFilter * Unit test for OIDCAuthenticationFilter
@ -18,10 +13,10 @@ public class AbstractOIDCAuthenticationFilterTest {
//@Autowired //@Autowired
private OIDCAuthenticationFilter filter; private OIDCAuthenticationFilter filter;
//@Test //@Test
public void testUrlConstruction() { public void testUrlConstruction() {
} }
/** /**
@ -37,7 +32,7 @@ public class AbstractOIDCAuthenticationFilterTest {
public void setFilter(OIDCAuthenticationFilter filter) { public void setFilter(OIDCAuthenticationFilter filter) {
this.filter = filter; this.filter = filter;
} }
} }

View File

@ -5,7 +5,6 @@ package org.mitre.jose;
import javax.persistence.Basic; import javax.persistence.Basic;
import javax.persistence.Embeddable; import javax.persistence.Embeddable;
import javax.persistence.Entity;
import javax.persistence.Transient; import javax.persistence.Transient;
import com.google.common.base.Strings; import com.google.common.base.Strings;
@ -22,16 +21,16 @@ import com.nimbusds.jose.JWEAlgorithm;
public class JWEAlgorithmEmbed { public class JWEAlgorithmEmbed {
public static final JWEAlgorithmEmbed NONE = getForAlgorithmName("none"); public static final JWEAlgorithmEmbed NONE = getForAlgorithmName("none");
private JWEAlgorithm algorithm; private JWEAlgorithm algorithm;
public JWEAlgorithmEmbed() { public JWEAlgorithmEmbed() {
} }
public JWEAlgorithmEmbed(JWEAlgorithm algorithm) { public JWEAlgorithmEmbed(JWEAlgorithm algorithm) {
this.algorithm = algorithm; this.algorithm = algorithm;
} }
public static JWEAlgorithmEmbed getForAlgorithmName (String algorithmName) { public static JWEAlgorithmEmbed getForAlgorithmName (String algorithmName) {
JWEAlgorithmEmbed ent = new JWEAlgorithmEmbed(); JWEAlgorithmEmbed ent = new JWEAlgorithmEmbed();
@ -42,7 +41,7 @@ public class JWEAlgorithmEmbed {
return ent; return ent;
} }
} }
/** /**
* Get the name of this algorithm, return null if no algorithm set. * Get the name of this algorithm, return null if no algorithm set.
* @return * @return
@ -55,9 +54,9 @@ public class JWEAlgorithmEmbed {
return null; return null;
} }
} }
/** /**
* Set the name of this algorithm. * Set the name of this algorithm.
* Calls JWEAlgorithm.parse() * Calls JWEAlgorithm.parse()
* @param algorithmName * @param algorithmName
*/ */
@ -72,15 +71,15 @@ public class JWEAlgorithmEmbed {
/* (non-Javadoc) /* (non-Javadoc)
* @see java.lang.Object#toString() * @see java.lang.Object#toString()
*/ */
@Override @Override
public String toString() { public String toString() {
return "JWEAlgorithmEmbed [algorithm=" + algorithm + "]"; return "JWEAlgorithmEmbed [algorithm=" + algorithm + "]";
} }
/** /**
* @return the algorithm * @return the algorithm
*/ */
@Transient @Transient
public JWEAlgorithm getAlgorithm() { public JWEAlgorithm getAlgorithm() {
return algorithm; return algorithm;
} }
@ -91,5 +90,5 @@ public class JWEAlgorithmEmbed {
public void setAlgorithm(JWEAlgorithm algorithm) { public void setAlgorithm(JWEAlgorithm algorithm) {
this.algorithm = algorithm; this.algorithm = algorithm;
} }
} }

View File

@ -9,7 +9,6 @@ import javax.persistence.Transient;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.nimbusds.jose.EncryptionMethod; import com.nimbusds.jose.EncryptionMethod;
import com.nimbusds.jose.JWEAlgorithm;
/** /**
* @author jricher * @author jricher
@ -19,16 +18,16 @@ import com.nimbusds.jose.JWEAlgorithm;
public class JWEEncryptionMethodEmbed { public class JWEEncryptionMethodEmbed {
public static final JWEEncryptionMethodEmbed NONE = getForAlgorithmName("none"); public static final JWEEncryptionMethodEmbed NONE = getForAlgorithmName("none");
private EncryptionMethod algorithm; private EncryptionMethod algorithm;
public JWEEncryptionMethodEmbed() { public JWEEncryptionMethodEmbed() {
} }
public JWEEncryptionMethodEmbed(EncryptionMethod algorithm) { public JWEEncryptionMethodEmbed(EncryptionMethod algorithm) {
this.algorithm = algorithm; this.algorithm = algorithm;
} }
public static JWEEncryptionMethodEmbed getForAlgorithmName (String algorithmName) { public static JWEEncryptionMethodEmbed getForAlgorithmName (String algorithmName) {
JWEEncryptionMethodEmbed ent = new JWEEncryptionMethodEmbed(); JWEEncryptionMethodEmbed ent = new JWEEncryptionMethodEmbed();
@ -39,7 +38,7 @@ public class JWEEncryptionMethodEmbed {
return ent; return ent;
} }
} }
/** /**
* Get the name of this algorithm, return null if no algorithm set. * Get the name of this algorithm, return null if no algorithm set.
* @return * @return
@ -52,9 +51,9 @@ public class JWEEncryptionMethodEmbed {
return null; return null;
} }
} }
/** /**
* Set the name of this algorithm. * Set the name of this algorithm.
* Calls EncryptionMethod.parse() * Calls EncryptionMethod.parse()
* @param algorithmName * @param algorithmName
*/ */
@ -69,15 +68,15 @@ public class JWEEncryptionMethodEmbed {
/* (non-Javadoc) /* (non-Javadoc)
* @see java.lang.Object#toString() * @see java.lang.Object#toString()
*/ */
@Override @Override
public String toString() { public String toString() {
return "JWEEncryptionMethodEmbed [algorithm=" + algorithm + "]"; return "JWEEncryptionMethodEmbed [algorithm=" + algorithm + "]";
} }
/** /**
* @return the algorithm * @return the algorithm
*/ */
@Transient @Transient
public EncryptionMethod getAlgorithm() { public EncryptionMethod getAlgorithm() {
return algorithm; return algorithm;
} }
@ -88,6 +87,6 @@ public class JWEEncryptionMethodEmbed {
public void setAlgorithm(EncryptionMethod algorithm) { public void setAlgorithm(EncryptionMethod algorithm) {
this.algorithm = algorithm; this.algorithm = algorithm;
} }
} }

View File

@ -5,8 +5,6 @@ package org.mitre.jose;
import javax.persistence.Basic; import javax.persistence.Basic;
import javax.persistence.Embeddable; import javax.persistence.Embeddable;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Transient; import javax.persistence.Transient;
import com.google.common.base.Strings; import com.google.common.base.Strings;
@ -23,17 +21,17 @@ import com.nimbusds.jose.JWSAlgorithm;
public class JWSAlgorithmEmbed { public class JWSAlgorithmEmbed {
public static final JWSAlgorithmEmbed NONE = getForAlgorithmName("none"); public static final JWSAlgorithmEmbed NONE = getForAlgorithmName("none");
private JWSAlgorithm algorithm; private JWSAlgorithm algorithm;
public JWSAlgorithmEmbed() { public JWSAlgorithmEmbed() {
} }
public JWSAlgorithmEmbed(JWSAlgorithm algorithm) { public JWSAlgorithmEmbed(JWSAlgorithm algorithm) {
this.algorithm = algorithm; this.algorithm = algorithm;
} }
public static JWSAlgorithmEmbed getForAlgorithmName (String algorithmName) { public static JWSAlgorithmEmbed getForAlgorithmName (String algorithmName) {
JWSAlgorithmEmbed ent = new JWSAlgorithmEmbed(); JWSAlgorithmEmbed ent = new JWSAlgorithmEmbed();
ent.setAlgorithmName(algorithmName); ent.setAlgorithmName(algorithmName);
@ -56,9 +54,9 @@ public class JWSAlgorithmEmbed {
return null; return null;
} }
} }
/** /**
* Set the name of this algorithm. * Set the name of this algorithm.
* Calls JWSAlgorithm.parse() * Calls JWSAlgorithm.parse()
* @param algorithmName * @param algorithmName
*/ */
@ -88,11 +86,11 @@ public class JWSAlgorithmEmbed {
/* (non-Javadoc) /* (non-Javadoc)
* @see java.lang.Object#toString() * @see java.lang.Object#toString()
*/ */
@Override @Override
public String toString() { public String toString() {
return "JWSAlgorithmEmbed [algorithm=" + algorithm + "]"; return "JWSAlgorithmEmbed [algorithm=" + algorithm + "]";
} }
} }

View File

@ -21,26 +21,26 @@ import com.nimbusds.jose.jwk.JWKSet;
public class JWKSetKeyStore implements InitializingBean { public class JWKSetKeyStore implements InitializingBean {
private JWKSet jwkSet; private JWKSet jwkSet;
private Resource location; private Resource location;
public JWKSetKeyStore() { public JWKSetKeyStore() {
} }
public JWKSetKeyStore(JWKSet jwkSet) { public JWKSetKeyStore(JWKSet jwkSet) {
this.jwkSet = jwkSet; this.jwkSet = jwkSet;
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/ */
@Override @Override
public void afterPropertiesSet() throws Exception { public void afterPropertiesSet() throws Exception {
if (jwkSet == null) { if (jwkSet == null) {
if (location != null) { if (location != null) {
if (location.exists() && location.isReadable()) { if (location.exists() && location.isReadable()) {
// read in the file from disk // read in the file from disk
@ -48,11 +48,11 @@ public class JWKSetKeyStore implements InitializingBean {
// parse it into a jwkSet object // parse it into a jwkSet object
jwkSet = JWKSet.parse(s); jwkSet = JWKSet.parse(s);
} else { } else {
throw new IllegalArgumentException("Key Set resource could not be read: " + location); throw new IllegalArgumentException("Key Set resource could not be read: " + location);
} }
} else { } else {
throw new IllegalArgumentException("Key store must be initialized with at least one of a jwkSet or a location."); throw new IllegalArgumentException("Key store must be initialized with at least one of a jwkSet or a location.");
} }
@ -90,10 +90,10 @@ public class JWKSetKeyStore implements InitializingBean {
/** /**
* Get the list of keys in this keystore. This is a passthrough to the underlying JWK Set * Get the list of keys in this keystore. This is a passthrough to the underlying JWK Set
*/ */
public List<JWK> getKeys() { public List<JWK> getKeys() {
return jwkSet.getKeys(); return jwkSet.getKeys();
} }
} }

View File

@ -16,7 +16,6 @@
package org.mitre.jwt.signer.service; package org.mitre.jwt.signer.service;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.util.Map; import java.util.Map;
import com.nimbusds.jose.JWSAlgorithm; import com.nimbusds.jose.JWSAlgorithm;
@ -29,7 +28,7 @@ public interface JwtSigningAndValidationService {
* Get all public keys for this service, mapped by their Key ID * Get all public keys for this service, mapped by their Key ID
*/ */
public Map<String, JWK> getAllPublicKeys(); public Map<String, JWK> getAllPublicKeys();
/** /**
* Checks the signature of the given JWT against all configured signers, * Checks the signature of the given JWT against all configured signers,
* returns true if at least one of the signers validates it. * returns true if at least one of the signers validates it.
@ -37,17 +36,17 @@ public interface JwtSigningAndValidationService {
* @param jwtString * @param jwtString
* the string representation of the JWT as sent on the wire * the string representation of the JWT as sent on the wire
* @return true if the signature is valid, false if not * @return true if the signature is valid, false if not
* @throws NoSuchAlgorithmException * @throws NoSuchAlgorithmException
*/ */
public boolean validateSignature(SignedJWT jwtString); public boolean validateSignature(SignedJWT jwtString);
/** /**
* Called to sign a jwt in place for a client that hasn't registered a preferred signing algorithm. * Called to sign a jwt in place for a client that hasn't registered a preferred signing algorithm.
* Use the default algorithm to sign. * Use the default algorithm to sign.
* *
* @param jwt the jwt to sign * @param jwt the jwt to sign
* @return the signed jwt * @return the signed jwt
* @throws NoSuchAlgorithmException * @throws NoSuchAlgorithmException
*/ */
public void signJwt(SignedJWT jwt); public void signJwt(SignedJWT jwt);
@ -55,7 +54,7 @@ public interface JwtSigningAndValidationService {
* Get the default signing algorithm for use when nothing else has been specified. * Get the default signing algorithm for use when nothing else has been specified.
* @return * @return
*/ */
public JWSAlgorithm getDefaultSigningAlgorithm(); public JWSAlgorithm getDefaultSigningAlgorithm();
/** /**
* Sign a jwt using the selected algorithm. The algorithm is selected using the String parameter values specified * Sign a jwt using the selected algorithm. The algorithm is selected using the String parameter values specified
@ -67,7 +66,7 @@ public interface JwtSigningAndValidationService {
*/ */
//TODO: implement later; only need signJwt(Jwt jwt) for now //TODO: implement later; only need signJwt(Jwt jwt) for now
//public Jwt signJwt(Jwt jwt, String alg); //public Jwt signJwt(Jwt jwt, String alg);
/** /**
* TODO: method to sign a jwt using a specified algorithm and a key id * TODO: method to sign a jwt using a specified algorithm and a key id
*/ */

View File

@ -52,9 +52,9 @@ public class DefaultJwtSigningAndValidationService implements JwtSigningAndValid
private static Logger logger = LoggerFactory.getLogger(DefaultJwtSigningAndValidationService.class); private static Logger logger = LoggerFactory.getLogger(DefaultJwtSigningAndValidationService.class);
private String defaultSignerKeyId; private String defaultSignerKeyId;
private JWSAlgorithm defaultAlgorithm; private JWSAlgorithm defaultAlgorithm;
// map of identifier to key // map of identifier to key
private Map<String, JWK> keys = new HashMap<String, JWK>(); private Map<String, JWK> keys = new HashMap<String, JWK>();
@ -70,10 +70,10 @@ public class DefaultJwtSigningAndValidationService implements JwtSigningAndValid
* @throws NoSuchAlgorithmException * @throws NoSuchAlgorithmException
* If there is no appropriate algorithm to tie the keys to. * If there is no appropriate algorithm to tie the keys to.
*/ */
public DefaultJwtSigningAndValidationService(Map<String, JWK> keys) throws NoSuchAlgorithmException, InvalidKeySpecException { public DefaultJwtSigningAndValidationService(Map<String, JWK> keys) throws NoSuchAlgorithmException, InvalidKeySpecException {
this.keys = keys; this.keys = keys;
buildSignersAndVerifiers(); buildSignersAndVerifiers();
} }
/** /**
* Build this service based on the given keystore. All keys must have a key * Build this service based on the given keystore. All keys must have a key
@ -87,18 +87,18 @@ public class DefaultJwtSigningAndValidationService implements JwtSigningAndValid
* @throws NoSuchAlgorithmException * @throws NoSuchAlgorithmException
* If there is no appropriate algorithm to tie the keys to. * If there is no appropriate algorithm to tie the keys to.
*/ */
public DefaultJwtSigningAndValidationService(JWKSetKeyStore keyStore) throws NoSuchAlgorithmException, InvalidKeySpecException { public DefaultJwtSigningAndValidationService(JWKSetKeyStore keyStore) throws NoSuchAlgorithmException, InvalidKeySpecException {
// convert all keys in the keystore to a map based on key id // convert all keys in the keystore to a map based on key id
for (JWK key : keyStore.getKeys()) { for (JWK key : keyStore.getKeys()) {
if (!Strings.isNullOrEmpty(key.getKeyID())) { if (!Strings.isNullOrEmpty(key.getKeyID())) {
this.keys.put(key.getKeyID(), key); this.keys.put(key.getKeyID(), key);
} else { } else {
throw new IllegalArgumentException("Tried to load a key from a keystore without a 'kid' field: " + key); throw new IllegalArgumentException("Tried to load a key from a keystore without a 'kid' field: " + key);
} }
} }
buildSignersAndVerifiers(); buildSignersAndVerifiers();
} }
/** /**
* @return the defaultSignerKeyId * @return the defaultSignerKeyId
*/ */
@ -117,22 +117,22 @@ public class DefaultJwtSigningAndValidationService implements JwtSigningAndValid
* @return * @return
*/ */
@Override @Override
public JWSAlgorithm getDefaultSigningAlgorithm() { public JWSAlgorithm getDefaultSigningAlgorithm() {
return defaultAlgorithm; return defaultAlgorithm;
} }
public void setDefaultSigningAlgorithmName(String algName) { public void setDefaultSigningAlgorithmName(String algName) {
defaultAlgorithm = JWSAlgorithm.parse(algName); defaultAlgorithm = JWSAlgorithm.parse(algName);
} }
public String getDefaultSigningAlgorithmName() { public String getDefaultSigningAlgorithmName() {
if (defaultAlgorithm != null) { if (defaultAlgorithm != null) {
return defaultAlgorithm.getName(); return defaultAlgorithm.getName();
} else { } else {
return null; return null;
} }
} }
/* /*
* (non-Javadoc) * (non-Javadoc)
* *
@ -145,9 +145,9 @@ public class DefaultJwtSigningAndValidationService implements JwtSigningAndValid
if (keys == null) { if (keys == null) {
throw new IllegalArgumentException("Signing and validation service must have at least one key configured."); throw new IllegalArgumentException("Signing and validation service must have at least one key configured.");
} }
buildSignersAndVerifiers(); buildSignersAndVerifiers();
logger.info("DefaultJwtSigningAndValidationService is ready: " + this.toString()); logger.info("DefaultJwtSigningAndValidationService is ready: " + this.toString());
} }
@ -156,45 +156,45 @@ public class DefaultJwtSigningAndValidationService implements JwtSigningAndValid
* @throws InvalidKeySpecException If the keys in the JWKs are not valid * @throws InvalidKeySpecException If the keys in the JWKs are not valid
* @throws NoSuchAlgorithmException If there is no appropriate algorithm to tie the keys to. * @throws NoSuchAlgorithmException If there is no appropriate algorithm to tie the keys to.
*/ */
private void buildSignersAndVerifiers() throws NoSuchAlgorithmException, InvalidKeySpecException { private void buildSignersAndVerifiers() throws NoSuchAlgorithmException, InvalidKeySpecException {
for (Map.Entry<String, JWK> jwkEntry : keys.entrySet()) { for (Map.Entry<String, JWK> jwkEntry : keys.entrySet()) {
String id = jwkEntry.getKey(); String id = jwkEntry.getKey();
JWK jwk = jwkEntry.getValue(); JWK jwk = jwkEntry.getValue();
if (jwk instanceof RSAKey) { if (jwk instanceof RSAKey) {
// build RSA signers & verifiers // build RSA signers & verifiers
if (jwk.isPrivate()) { // only add the signer if there's a private key if (jwk.isPrivate()) { // only add the signer if there's a private key
RSASSASigner signer = new RSASSASigner(((RSAKey) jwk).toRSAPrivateKey()); RSASSASigner signer = new RSASSASigner(((RSAKey) jwk).toRSAPrivateKey());
signers.put(id, signer); signers.put(id, signer);
} }
RSASSAVerifier verifier = new RSASSAVerifier(((RSAKey) jwk).toRSAPublicKey()); RSASSAVerifier verifier = new RSASSAVerifier(((RSAKey) jwk).toRSAPublicKey());
verifiers.put(id, verifier); verifiers.put(id, verifier);
} else if (jwk instanceof ECKey) { } else if (jwk instanceof ECKey) {
// build EC signers & verifiers // build EC signers & verifiers
// TODO: add support for EC keys // TODO: add support for EC keys
logger.warn("EC Keys are not yet supported."); logger.warn("EC Keys are not yet supported.");
} else if (jwk instanceof OctetSequenceKey) { } else if (jwk instanceof OctetSequenceKey) {
// build HMAC signers & verifiers // build HMAC signers & verifiers
if (jwk.isPrivate()) { // technically redundant check because all HMAC keys are private if (jwk.isPrivate()) { // technically redundant check because all HMAC keys are private
MACSigner signer = new MACSigner(((OctetSequenceKey) jwk).toByteArray()); MACSigner signer = new MACSigner(((OctetSequenceKey) jwk).toByteArray());
signers.put(id, signer); signers.put(id, signer);
} }
MACVerifier verifier = new MACVerifier(((OctetSequenceKey) jwk).toByteArray()); MACVerifier verifier = new MACVerifier(((OctetSequenceKey) jwk).toByteArray());
verifiers.put(id, verifier); verifiers.put(id, verifier);
} else { } else {
logger.warn("Unknown key type: " + jwk); logger.warn("Unknown key type: " + jwk);
} }
} }
} }
/** /**
* Sign a jwt in place using the configured default signer. * Sign a jwt in place using the configured default signer.
@ -204,18 +204,18 @@ public class DefaultJwtSigningAndValidationService implements JwtSigningAndValid
if (getDefaultSignerKeyId() == null) { if (getDefaultSignerKeyId() == null) {
throw new IllegalStateException("Tried to call default signing with no default signer ID set"); throw new IllegalStateException("Tried to call default signing with no default signer ID set");
} }
JWSSigner signer = signers.get(getDefaultSignerKeyId()); JWSSigner signer = signers.get(getDefaultSignerKeyId());
try { try {
jwt.sign(signer); jwt.sign(signer);
} catch (JOSEException e) { } catch (JOSEException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
} }
} }
@Override @Override
public boolean validateSignature(SignedJWT jwt) { public boolean validateSignature(SignedJWT jwt) {
@ -225,9 +225,9 @@ public class DefaultJwtSigningAndValidationService implements JwtSigningAndValid
return true; return true;
} }
} catch (JOSEException e) { } catch (JOSEException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
} }
} }
return false; return false;
} }
@ -235,17 +235,17 @@ public class DefaultJwtSigningAndValidationService implements JwtSigningAndValid
@Override @Override
public Map<String, JWK> getAllPublicKeys() { public Map<String, JWK> getAllPublicKeys() {
Map<String, JWK> pubKeys = new HashMap<String, JWK>(); Map<String, JWK> pubKeys = new HashMap<String, JWK>();
// pull all keys out of the verifiers if we know how // pull all keys out of the verifiers if we know how
for (String keyId : keys.keySet()) { for (String keyId : keys.keySet()) {
JWK key = keys.get(keyId); JWK key = keys.get(keyId);
JWK pub = key.toPublicJWK(); JWK pub = key.toPublicJWK();
if (pub != null) { if (pub != null) {
pubKeys.put(keyId, pub); pubKeys.put(keyId, pub);
} }
} }
return pubKeys; return pubKeys;
} }
} }

View File

@ -3,12 +3,6 @@
*/ */
package org.mitre.jwt.signer.service.impl; package org.mitre.jwt.signer.service.impl;
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.RSAPublicKeySpec;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import org.apache.http.client.HttpClient; import org.apache.http.client.HttpClient;
@ -22,16 +16,11 @@ import org.springframework.web.client.RestTemplate;
import com.google.common.cache.Cache; import com.google.common.cache.Cache;
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.nimbusds.jose.JWSVerifier;
import com.nimbusds.jose.crypto.RSASSAVerifier;
import com.nimbusds.jose.jwk.JWK;
import com.nimbusds.jose.jwk.JWKSet; import com.nimbusds.jose.jwk.JWKSet;
import com.nimbusds.jose.jwk.KeyType;
import com.nimbusds.jose.jwk.RSAKey;
/** /**
* *
* Creates a * Creates a
* *
* @author jricher * @author jricher
* *
@ -46,49 +35,49 @@ public class JWKSetSigningAndValidationServiceCacheService {
.maximumSize(100) .maximumSize(100)
.build(new JWKSetVerifierFetcher()); .build(new JWKSetVerifierFetcher());
} }
/** /**
* @param key * @param key
* @return * @return
* @throws ExecutionException * @throws ExecutionException
* @see com.google.common.cache.Cache#get(java.lang.Object) * @see com.google.common.cache.Cache#get(java.lang.Object)
*/ */
public JwtSigningAndValidationService get(String key) { public JwtSigningAndValidationService get(String key) {
try { try {
return cache.get(key); return cache.get(key);
} catch (ExecutionException e) { } catch (ExecutionException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
return null; return null;
} }
} }
/** /**
* @author jricher * @author jricher
* *
*/ */
private class JWKSetVerifierFetcher extends CacheLoader<String, JwtSigningAndValidationService> { private class JWKSetVerifierFetcher extends CacheLoader<String, JwtSigningAndValidationService> {
private HttpClient httpClient = new DefaultHttpClient(); private HttpClient httpClient = new DefaultHttpClient();
private HttpComponentsClientHttpRequestFactory httpFactory = new HttpComponentsClientHttpRequestFactory(httpClient); private HttpComponentsClientHttpRequestFactory httpFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
private RestTemplate restTemplate = new RestTemplate(httpFactory); private RestTemplate restTemplate = new RestTemplate(httpFactory);
/**
* Load the JWK Set and build the appropriate signing service.
*/
@Override
public JwtSigningAndValidationService load(String key) throws Exception {
String jsonString = restTemplate.getForObject(key, String.class); /**
JWKSet jwkSet = JWKSet.parse(jsonString); * Load the JWK Set and build the appropriate signing service.
*/
JWKSetKeyStore keyStore = new JWKSetKeyStore(jwkSet); @Override
public JwtSigningAndValidationService load(String key) throws Exception {
JwtSigningAndValidationService service = new DefaultJwtSigningAndValidationService(keyStore);
return service; String jsonString = restTemplate.getForObject(key, String.class);
JWKSet jwkSet = JWKSet.parse(jsonString);
}
} JWKSetKeyStore keyStore = new JWKSetKeyStore(jwkSet);
JwtSigningAndValidationService service = new DefaultJwtSigningAndValidationService(keyStore);
return service;
}
}
} }

View File

@ -22,13 +22,13 @@ import org.springframework.security.oauth2.provider.OAuth2Authentication;
public class AuthenticationHolderEntity { public class AuthenticationHolderEntity {
private Long id; private Long id;
private Long ownerId; private Long ownerId;
private OAuth2Authentication authentication; private OAuth2Authentication authentication;
public AuthenticationHolderEntity() { public AuthenticationHolderEntity() {
} }
@Id @Id
@ -60,7 +60,7 @@ public class AuthenticationHolderEntity {
public void setAuthentication(OAuth2Authentication authentication) { public void setAuthentication(OAuth2Authentication authentication) {
this.authentication = authentication; this.authentication = authentication;
} }
} }

View File

@ -28,18 +28,18 @@ import org.springframework.security.oauth2.provider.OAuth2Authentication;
public class AuthorizationCodeEntity { public class AuthorizationCodeEntity {
private Long id; private Long id;
private String code; private String code;
private OAuth2Authentication authentication; private OAuth2Authentication authentication;
/** /**
* Default constructor. * Default constructor.
*/ */
public AuthorizationCodeEntity() { public AuthorizationCodeEntity() {
} }
/** /**
* Create a new AuthorizationCodeEntity with the given code and AuthorizationRequestHolder. * Create a new AuthorizationCodeEntity with the given code and AuthorizationRequestHolder.
* *
@ -50,12 +50,12 @@ public class AuthorizationCodeEntity {
this.code = code; this.code = code;
this.authentication = authRequest; this.authentication = authRequest;
} }
/** /**
* @return the id * @return the id
*/ */
@Id @Id
@GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue(strategy = GenerationType.IDENTITY)
public Long getId() { public Long getId() {
return id; return id;
} }
@ -98,5 +98,5 @@ public class AuthorizationCodeEntity {
public void setAuthentication(OAuth2Authentication authentication) { public void setAuthentication(OAuth2Authentication authentication) {
this.authentication = authentication; this.authentication = authentication;
} }
} }

View File

@ -67,7 +67,7 @@ public class ClientDetailsEntity implements ClientDetails {
private static final long serialVersionUID = -1617727085733786296L; private static final long serialVersionUID = -1617727085733786296L;
private Long id; private Long id;
/** Fields from the OAuth2 Dynamic Registration Specification */ /** Fields from the OAuth2 Dynamic Registration Specification */
private String clientId = null; // client_id private String clientId = null; // client_id
private String clientSecret = null; // client_secret private String clientSecret = null; // client_secret
@ -75,7 +75,7 @@ public class ClientDetailsEntity implements ClientDetails {
private String clientName; // client_name private String clientName; // client_name
private String clientUri; // client_uri private String clientUri; // client_uri
private String logoUri; // logo_uri private String logoUri; // logo_uri
private Set<String> contacts; // contacts private Set<String> contacts; // contacts
private String tosUri; // tos_uri private String tosUri; // tos_uri
private AuthMethod tokenEndpointAuthMethod = AuthMethod.SECRET_BASIC; // token_endpoint_auth_method private AuthMethod tokenEndpointAuthMethod = AuthMethod.SECRET_BASIC; // token_endpoint_auth_method
private Set<String> scope = new HashSet<String>(); // scope private Set<String> scope = new HashSet<String>(); // scope
@ -83,38 +83,38 @@ public class ClientDetailsEntity implements ClientDetails {
private Set<String> responseTypes = new HashSet<String>(); // response_types private Set<String> responseTypes = new HashSet<String>(); // response_types
private String policyUri; private String policyUri;
private String jwksUri; private String jwksUri;
/** Fields from OIDC Client Registration Specification **/ /** Fields from OIDC Client Registration Specification **/
private AppType applicationType; // application_type private AppType applicationType; // application_type
private String sectorIdentifierUri; // sector_identifier_uri private String sectorIdentifierUri; // sector_identifier_uri
private SubjectType subjectType; // subject_type private SubjectType subjectType; // subject_type
private JWSAlgorithmEmbed requestObjectSigningAlg = JWSAlgorithmEmbed.NONE; // request_object_signing_alg private JWSAlgorithmEmbed requestObjectSigningAlg = JWSAlgorithmEmbed.NONE; // request_object_signing_alg
private JWSAlgorithmEmbed userInfoSignedResponseAlg = JWSAlgorithmEmbed.NONE; // user_info_signed_response_alg private JWSAlgorithmEmbed userInfoSignedResponseAlg = JWSAlgorithmEmbed.NONE; // user_info_signed_response_alg
private JWEAlgorithmEmbed userInfoEncryptedResponseAlg = JWEAlgorithmEmbed.NONE; // user_info_encrypted_response_alg private JWEAlgorithmEmbed userInfoEncryptedResponseAlg = JWEAlgorithmEmbed.NONE; // user_info_encrypted_response_alg
private JWEEncryptionMethodEmbed userInfoEncryptedResponseEnc = JWEEncryptionMethodEmbed.NONE; // user_info_encrypted_response_enc private JWEEncryptionMethodEmbed userInfoEncryptedResponseEnc = JWEEncryptionMethodEmbed.NONE; // user_info_encrypted_response_enc
private JWSAlgorithmEmbed idTokenSignedResponseAlg = JWSAlgorithmEmbed.NONE; // id_token_signed_response_alg private JWSAlgorithmEmbed idTokenSignedResponseAlg = JWSAlgorithmEmbed.NONE; // id_token_signed_response_alg
private JWEAlgorithmEmbed idTokenEncryptedResponseAlg = JWEAlgorithmEmbed.NONE; // id_token_encrypted_response_alg private JWEAlgorithmEmbed idTokenEncryptedResponseAlg = JWEAlgorithmEmbed.NONE; // id_token_encrypted_response_alg
private JWEEncryptionMethodEmbed idTokenEncryptedResponseEnc = JWEEncryptionMethodEmbed.NONE; // id_token_encrypted_response_enc private JWEEncryptionMethodEmbed idTokenEncryptedResponseEnc = JWEEncryptionMethodEmbed.NONE; // id_token_encrypted_response_enc
private Integer defaultMaxAge; // default_max_age private Integer defaultMaxAge; // default_max_age
private Boolean requireAuthTime; // require_auth_time private Boolean requireAuthTime; // require_auth_time
private Set<String> defaultACRvalues; // default_acr_values private Set<String> defaultACRvalues; // default_acr_values
private String initiateLoginUri; // initiate_login_uri private String initiateLoginUri; // initiate_login_uri
private String postLogoutRedirectUri; // post_logout_redirect_uri private String postLogoutRedirectUri; // post_logout_redirect_uri
private Set<String> requestUris; // request_uris private Set<String> requestUris; // request_uris
/** Fields to support the ClientDetails interface **/ /** Fields to support the ClientDetails interface **/
private Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>(); private Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
private Integer accessTokenValiditySeconds = 0; // in seconds private Integer accessTokenValiditySeconds = 0; // in seconds
private Integer refreshTokenValiditySeconds = 0; // in seconds private Integer refreshTokenValiditySeconds = 0; // in seconds
private Set<String> resourceIds = new HashSet<String>(); private Set<String> resourceIds = new HashSet<String>();
private Map<String, Object> additionalInformation = new HashMap<String, Object>(); private Map<String, Object> additionalInformation = new HashMap<String, Object>();
/** Our own fields **/ /** Our own fields **/
private String clientDescription = ""; // human-readable description private String clientDescription = ""; // human-readable description
private boolean reuseRefreshToken = true; // do we let someone reuse a refresh token? private boolean reuseRefreshToken = true; // do we let someone reuse a refresh token?
@ -122,16 +122,16 @@ public class ClientDetailsEntity implements ClientDetails {
private boolean allowIntrospection = false; // do we let this client call the introspection endpoint? 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
private Date createdAt; // time the client was created private Date createdAt; // time the client was created
public enum AuthMethod { public enum AuthMethod {
SECRET_POST("client_secret_post"), SECRET_POST("client_secret_post"),
SECRET_BASIC("client_secret_basic"), SECRET_BASIC("client_secret_basic"),
SECRET_JWT("client_secret_jwt"), SECRET_JWT("client_secret_jwt"),
PRIVATE_KEY("private_key_jwt"), PRIVATE_KEY("private_key_jwt"),
NONE("none"); NONE("none");
private final String value; private final String value;
// map to aid reverse lookup // map to aid reverse lookup
private static final Map<String, AuthMethod> lookup = new HashMap<String, AuthMethod>(); private static final Map<String, AuthMethod> lookup = new HashMap<String, AuthMethod>();
static { static {
@ -139,77 +139,77 @@ public class ClientDetailsEntity implements ClientDetails {
lookup.put(a.getValue(), a); lookup.put(a.getValue(), a);
} }
} }
AuthMethod(String value) { AuthMethod(String value) {
this.value = value; this.value = value;
} }
public String getValue() { public String getValue() {
return value; return value;
} }
public static AuthMethod getByValue(String value) { public static AuthMethod getByValue(String value) {
return lookup.get(value); return lookup.get(value);
} }
} }
public enum AppType { public enum AppType {
WEB("web"), NATIVE("native"); WEB("web"), NATIVE("native");
private final String value; private final String value;
// map to aid reverse lookup // map to aid reverse lookup
private static final Map<String, AppType> lookup = new HashMap<String, AppType>(); private static final Map<String, AppType> lookup = new HashMap<String, AppType>();
static { static {
for (AppType a : AppType.values()) { for (AppType a : AppType.values()) {
lookup.put(a.getValue(), a); lookup.put(a.getValue(), a);
} }
} }
AppType(String value) { AppType(String value) {
this.value = value; this.value = value;
} }
public String getValue() { public String getValue() {
return value; return value;
} }
public static AppType getByValue(String value) { public static AppType getByValue(String value) {
return lookup.get(value); return lookup.get(value);
} }
} }
public enum SubjectType { public enum SubjectType {
PAIRWISE("pairwise"), PUBLIC("public"); PAIRWISE("pairwise"), PUBLIC("public");
private final String value; private final String value;
// map to aid reverse lookup // map to aid reverse lookup
private static final Map<String, SubjectType> lookup = new HashMap<String, SubjectType>(); private static final Map<String, SubjectType> lookup = new HashMap<String, SubjectType>();
static { static {
for (SubjectType u : SubjectType.values()) { for (SubjectType u : SubjectType.values()) {
lookup.put(u.getValue(), u); lookup.put(u.getValue(), u);
} }
} }
SubjectType(String value) { SubjectType(String value) {
this.value = value; this.value = value;
} }
public String getValue() { public String getValue() {
return value; return value;
} }
public static SubjectType getByValue(String value) { public static SubjectType getByValue(String value) {
return lookup.get(value); return lookup.get(value);
} }
} }
/** /**
* Create a blank ClientDetailsEntity * Create a blank ClientDetailsEntity
*/ */
public ClientDetailsEntity() { public ClientDetailsEntity() {
} }
/** /**
@ -228,34 +228,34 @@ public class ClientDetailsEntity implements ClientDetails {
public void setId(Long id) { public void setId(Long id) {
this.id = id; this.id = id;
} }
/** /**
* @return the clientDescription * @return the clientDescription
*/ */
@Basic @Basic
@Column(name="client_description") @Column(name="client_description")
public String getClientDescription() { public String getClientDescription() {
return clientDescription; return clientDescription;
} }
/** /**
* @param clientDescription Human-readable long description of the client (optional) * @param clientDescription Human-readable long description of the client (optional)
*/ */
public void setClientDescription(String clientDescription) { public void setClientDescription(String clientDescription) {
this.clientDescription = clientDescription; this.clientDescription = clientDescription;
} }
/** /**
* @return the allowRefresh * @return the allowRefresh
*/ */
@Transient @Transient
public boolean isAllowRefresh() { public boolean isAllowRefresh() {
if (grantTypes != null) { if (grantTypes != null) {
return getAuthorizedGrantTypes().contains("refresh_token"); return getAuthorizedGrantTypes().contains("refresh_token");
} else { } else {
return false; // if there are no grants, we can't be refreshing them, can we? return false; // if there are no grants, we can't be refreshing them, can we?
} }
} }
@Basic @Basic
@Column(name="reuse_refresh_tokens") @Column(name="reuse_refresh_tokens")
@ -266,7 +266,7 @@ public class ClientDetailsEntity implements ClientDetails {
public void setReuseRefreshToken(boolean reuseRefreshToken) { public void setReuseRefreshToken(boolean reuseRefreshToken) {
this.reuseRefreshToken = reuseRefreshToken; this.reuseRefreshToken = reuseRefreshToken;
} }
/** /**
* @return the idTokenValiditySeconds * @return the idTokenValiditySeconds
*/ */
@ -282,7 +282,7 @@ public class ClientDetailsEntity implements ClientDetails {
public void setIdTokenValiditySeconds(Integer idTokenValiditySeconds) { public void setIdTokenValiditySeconds(Integer idTokenValiditySeconds) {
this.idTokenValiditySeconds = idTokenValiditySeconds; this.idTokenValiditySeconds = idTokenValiditySeconds;
} }
/** /**
* @return the dynamicallyRegistered * @return the dynamicallyRegistered
*/ */
@ -298,148 +298,149 @@ public class ClientDetailsEntity implements ClientDetails {
public void setDynamicallyRegistered(boolean dynamicallyRegistered) { public void setDynamicallyRegistered(boolean dynamicallyRegistered) {
this.dynamicallyRegistered = dynamicallyRegistered; this.dynamicallyRegistered = dynamicallyRegistered;
} }
/** /**
* @return the allowIntrospection * @return the allowIntrospection
*/ */
@Basic @Basic
@Column(name="allow_introspection") @Column(name="allow_introspection")
public boolean isAllowIntrospection() { public boolean isAllowIntrospection() {
return allowIntrospection; return allowIntrospection;
} }
/** /**
* @param allowIntrospection the allowIntrospection to set * @param allowIntrospection the allowIntrospection to set
*/ */
public void setAllowIntrospection(boolean allowIntrospection) { public void setAllowIntrospection(boolean allowIntrospection) {
this.allowIntrospection = allowIntrospection; this.allowIntrospection = allowIntrospection;
} }
/** /**
* *
*/ */
@Override @Override
@Transient @Transient
public boolean isSecretRequired() { public boolean isSecretRequired() {
// TODO: this should check the auth method field instead // TODO: this should check the auth method field instead
return getClientSecret() != null; return getClientSecret() != null;
} }
/** /**
* If the scope list is not null or empty, then this client has been scoped. * If the scope list is not null or empty, then this client has been scoped.
*/ */
@Override @Override
@Transient @Transient
public boolean isScoped() { public boolean isScoped() {
return getScope() != null && !getScope().isEmpty(); return getScope() != null && !getScope().isEmpty();
} }
/** /**
* @return the clientId * @return the clientId
*/ */
@Basic @Basic
@Override @Override
@Column(name="client_id") @Column(name="client_id")
public String getClientId() { public String getClientId() {
return clientId; return clientId;
} }
/** /**
* @param clientId The OAuth2 client_id, must be unique to this client * @param clientId The OAuth2 client_id, must be unique to this client
*/ */
public void setClientId(String clientId) { public void setClientId(String clientId) {
this.clientId = clientId; this.clientId = clientId;
} }
/** /**
* @return the clientSecret * @return the clientSecret
*/ */
@Basic @Basic
@Override @Override
@Column(name="client_secret") @Column(name="client_secret")
public String getClientSecret() { public String getClientSecret() {
return clientSecret; return clientSecret;
} }
/** /**
* @param clientSecret the OAuth2 client_secret (optional) * @param clientSecret the OAuth2 client_secret (optional)
*/ */
public void setClientSecret(String clientSecret) { public void setClientSecret(String clientSecret) {
this.clientSecret = clientSecret; this.clientSecret = clientSecret;
} }
/** /**
* @return the scope * @return the scope
*/ */
@ElementCollection(fetch = FetchType.EAGER) @ElementCollection(fetch = FetchType.EAGER)
@CollectionTable( @CollectionTable(
name="client_scope", name="client_scope",
joinColumns=@JoinColumn(name="owner_id") joinColumns=@JoinColumn(name="owner_id")
) )
@Override @Override
@Column(name="scope") @Column(name="scope")
public Set<String> getScope() { public Set<String> getScope() {
return scope; return scope;
} }
/** /**
* @param scope the set of scopes allowed to be issued to this client * @param scope the set of scopes allowed to be issued to this client
*/ */
public void setScope(Set<String> scope) { public void setScope(Set<String> scope) {
this.scope = scope; this.scope = scope;
} }
/** /**
* @return the authorizedGrantTypes * @return the authorizedGrantTypes
*/ */
@ElementCollection(fetch = FetchType.EAGER) @ElementCollection(fetch = FetchType.EAGER)
@CollectionTable( @CollectionTable(
name="client_grant_type", name="client_grant_type",
joinColumns=@JoinColumn(name="owner_id") joinColumns=@JoinColumn(name="owner_id")
) )
@Column(name="grant_type") @Column(name="grant_type")
public Set<String> getGrantTypes() { public Set<String> getGrantTypes() {
return grantTypes; return grantTypes;
} }
/** /**
* @param authorizedGrantTypes the OAuth2 grant types that this client is allowed to use * @param authorizedGrantTypes the OAuth2 grant types that this client is allowed to use
*/ */
public void setGrantTypes(Set<String> grantTypes) { public void setGrantTypes(Set<String> grantTypes) {
this.grantTypes = grantTypes; this.grantTypes = grantTypes;
} }
/**
* passthrough for SECOAUTH api
*/
public Set<String> getAuthorizedGrantTypes() {
return getGrantTypes();
}
/** /**
* @return the authorities * passthrough for SECOAUTH api
*/ */
@Override
public Set<String> getAuthorizedGrantTypes() {
return getGrantTypes();
}
/**
* @return the authorities
*/
@ElementCollection(fetch = FetchType.EAGER) @ElementCollection(fetch = FetchType.EAGER)
@CollectionTable( @CollectionTable(
name="client_authority", name="client_authority",
joinColumns=@JoinColumn(name="owner_id") joinColumns=@JoinColumn(name="owner_id")
) )
@Override @Override
@Column(name="authority") @Column(name="authority")
public Set<GrantedAuthority> getAuthorities() { public Set<GrantedAuthority> getAuthorities() {
return authorities; return authorities;
} }
/** /**
* @param authorities the Spring Security authorities this client is given * @param authorities the Spring Security authorities this client is given
*/ */
public void setAuthorities(Set<GrantedAuthority> authorities) { public void setAuthorities(Set<GrantedAuthority> authorities) {
this.authorities = authorities; this.authorities = authorities;
} }
@Override @Override
@Basic @Basic
@ -447,13 +448,13 @@ public class ClientDetailsEntity implements ClientDetails {
public Integer getAccessTokenValiditySeconds() { public Integer getAccessTokenValiditySeconds() {
return accessTokenValiditySeconds; return accessTokenValiditySeconds;
} }
/** /**
* @param accessTokenTimeout the accessTokenTimeout to set * @param accessTokenTimeout the accessTokenTimeout to set
*/ */
public void setAccessTokenValiditySeconds(Integer accessTokenValiditySeconds) { public void setAccessTokenValiditySeconds(Integer accessTokenValiditySeconds) {
this.accessTokenValiditySeconds = accessTokenValiditySeconds; this.accessTokenValiditySeconds = accessTokenValiditySeconds;
} }
@Override @Override
@Basic @Basic
@ -461,64 +462,65 @@ public class ClientDetailsEntity implements ClientDetails {
public Integer getRefreshTokenValiditySeconds() { public Integer getRefreshTokenValiditySeconds() {
return refreshTokenValiditySeconds; return refreshTokenValiditySeconds;
} }
/** /**
* @param refreshTokenTimeout Lifetime of refresh tokens, in seconds (optional - leave null for no timeout) * @param refreshTokenTimeout Lifetime of refresh tokens, in seconds (optional - leave null for no timeout)
*/ */
public void setRefreshTokenValiditySeconds(Integer refreshTokenValiditySeconds) { public void setRefreshTokenValiditySeconds(Integer refreshTokenValiditySeconds) {
this.refreshTokenValiditySeconds = refreshTokenValiditySeconds; this.refreshTokenValiditySeconds = refreshTokenValiditySeconds;
} }
/** /**
* @return the registeredRedirectUri * @return the registeredRedirectUri
*/ */
@ElementCollection(fetch = FetchType.EAGER) @ElementCollection(fetch = FetchType.EAGER)
@CollectionTable( @CollectionTable(
name="client_redirect_uri", name="client_redirect_uri",
joinColumns=@JoinColumn(name="owner_id") joinColumns=@JoinColumn(name="owner_id")
) )
@Column(name="redirect_uri") @Column(name="redirect_uri")
public Set<String> getRedirectUris() { public Set<String> getRedirectUris() {
return redirectUris; return redirectUris;
} }
/** /**
* @param registeredRedirectUri the registeredRedirectUri to set * @param registeredRedirectUri the registeredRedirectUri to set
*/ */
public void setRedirectUris(Set<String> redirectUris) { public void setRedirectUris(Set<String> redirectUris) {
this.redirectUris = redirectUris; this.redirectUris = redirectUris;
} }
/**
* Pass-through method to fulfill the ClientDetails interface with a bad name
*/
@Override
@Transient
public Set<String> getRegisteredRedirectUri() {
return getRedirectUris();
}
/** /**
* @return the resourceIds * Pass-through method to fulfill the ClientDetails interface with a bad name
*/ */
@Override
@Transient
public Set<String> getRegisteredRedirectUri() {
return getRedirectUris();
}
/**
* @return the resourceIds
*/
@Override
@ElementCollection(fetch = FetchType.EAGER) @ElementCollection(fetch = FetchType.EAGER)
@CollectionTable( @CollectionTable(
name="client_resource", name="client_resource",
joinColumns=@JoinColumn(name="owner_id") joinColumns=@JoinColumn(name="owner_id")
) )
@Column(name="resource_id") @Column(name="resource_id")
public Set<String> getResourceIds() { public Set<String> getResourceIds() {
return resourceIds; return resourceIds;
} }
/** /**
* @param resourceIds the resourceIds to set * @param resourceIds the resourceIds to set
*/ */
public void setResourceIds(Set<String> resourceIds) { public void setResourceIds(Set<String> resourceIds) {
this.resourceIds = resourceIds; this.resourceIds = resourceIds;
} }
/** /**
* This library does not make use of this field, so it is not * This library does not make use of this field, so it is not
* stored using our persistence layer. * stored using our persistence layer.
@ -533,7 +535,7 @@ public class ClientDetailsEntity implements ClientDetails {
return this.additionalInformation; return this.additionalInformation;
} }
@Enumerated(EnumType.STRING) @Enumerated(EnumType.STRING)
@ -580,7 +582,7 @@ public class ClientDetailsEntity implements ClientDetails {
@CollectionTable( @CollectionTable(
name="client_contact", name="client_contact",
joinColumns=@JoinColumn(name="owner_id") joinColumns=@JoinColumn(name="owner_id")
) )
@Column(name="contact") @Column(name="contact")
public Set<String> getContacts() { public Set<String> getContacts() {
return contacts; return contacts;
@ -599,7 +601,7 @@ public class ClientDetailsEntity implements ClientDetails {
public void setLogoUri(String logoUri) { public void setLogoUri(String logoUri) {
this.logoUri = logoUri; this.logoUri = logoUri;
} }
@Basic @Basic
@Column(name="policy_uri") @Column(name="policy_uri")
public String getPolicyUri() { public String getPolicyUri() {
@ -611,36 +613,36 @@ public class ClientDetailsEntity implements ClientDetails {
} }
/** /**
* @return the clientUrl * @return the clientUrl
*/ */
@Basic @Basic
@Column(name="client_uri") @Column(name="client_uri")
public String getClientUri() { public String getClientUri() {
return clientUri; return clientUri;
} }
/** /**
* @param clientUrl the clientUrl to set * @param clientUrl the clientUrl to set
*/ */
public void setClientUri(String clientUri) { public void setClientUri(String clientUri) {
this.clientUri = clientUri; this.clientUri = clientUri;
} }
/** /**
* @return the tosUrl * @return the tosUrl
*/ */
@Basic @Basic
@Column(name="tos_uri") @Column(name="tos_uri")
public String getTosUri() { public String getTosUri() {
return tosUri; return tosUri;
} }
/** /**
* @param tosUrl the tosUrl to set * @param tosUrl the tosUrl to set
*/ */
public void setTosUri(String tosUri) { public void setTosUri(String tosUri) {
this.tosUri = tosUri; this.tosUri = tosUri;
} }
@Basic @Basic
@Column(name="jwks_uri") @Column(name="jwks_uri")
@ -708,7 +710,7 @@ public class ClientDetailsEntity implements ClientDetails {
public void setUserInfoEncryptedResponseEnc(JWEEncryptionMethodEmbed userInfoEncryptedResponseEnc) { public void setUserInfoEncryptedResponseEnc(JWEEncryptionMethodEmbed userInfoEncryptedResponseEnc) {
this.userInfoEncryptedResponseEnc = userInfoEncryptedResponseEnc; this.userInfoEncryptedResponseEnc = userInfoEncryptedResponseEnc;
} }
@Embedded @Embedded
@AttributeOverrides({ @AttributeOverrides({
@ -773,7 +775,7 @@ public class ClientDetailsEntity implements ClientDetails {
@CollectionTable( @CollectionTable(
name="client_response_type", name="client_response_type",
joinColumns=@JoinColumn(name="response_type") joinColumns=@JoinColumn(name="response_type")
) )
@Column(name="response_type") @Column(name="response_type")
public Set<String> getResponseTypes() { public Set<String> getResponseTypes() {
return responseTypes; return responseTypes;
@ -793,7 +795,7 @@ public class ClientDetailsEntity implements ClientDetails {
@CollectionTable( @CollectionTable(
name="client_default_acr_value", name="client_default_acr_value",
joinColumns=@JoinColumn(name="owner_id") joinColumns=@JoinColumn(name="owner_id")
) )
@Column(name="default_acr_value") @Column(name="default_acr_value")
public Set<String> getDefaultACRvalues() { public Set<String> getDefaultACRvalues() {
return defaultACRvalues; return defaultACRvalues;
@ -845,7 +847,7 @@ public class ClientDetailsEntity implements ClientDetails {
@CollectionTable( @CollectionTable(
name="client_request_uri", name="client_request_uri",
joinColumns=@JoinColumn(name="owner_id") joinColumns=@JoinColumn(name="owner_id")
) )
@Column(name="request_uri") @Column(name="request_uri")
public Set<String> getRequestUris() { public Set<String> getRequestUris() {
return requestUris; return requestUris;
@ -863,15 +865,15 @@ public class ClientDetailsEntity implements ClientDetails {
*/ */
@Temporal(TemporalType.TIMESTAMP) @Temporal(TemporalType.TIMESTAMP)
@Column(name="created_at") @Column(name="created_at")
public Date getCreatedAt() { public Date getCreatedAt() {
return createdAt; return createdAt;
} }
/** /**
* @param createdAt the createdAt to set * @param createdAt the createdAt to set
*/ */
public void setCreatedAt(Date createdAt) { public void setCreatedAt(Date createdAt) {
this.createdAt = createdAt; this.createdAt = createdAt;
} }
} }

View File

@ -71,17 +71,17 @@ public class OAuth2AccessTokenEntity implements OAuth2AccessToken {
public static final String REGISTRATION_TOKEN_SCOPE = "registration-token"; public static final String REGISTRATION_TOKEN_SCOPE = "registration-token";
public static String ID_TOKEN = "id_token"; public static String ID_TOKEN = "id_token";
private Long id; private Long id;
private ClientDetailsEntity client; private ClientDetailsEntity client;
private AuthenticationHolderEntity authenticationHolder; // the authentication that made this access private AuthenticationHolderEntity authenticationHolder; // the authentication that made this access
private JWT jwtValue; // JWT-encoded access token value private JWT jwtValue; // JWT-encoded access token value
private OAuth2AccessTokenEntity idToken; // JWT-encoded OpenID Connect IdToken private OAuth2AccessTokenEntity idToken; // JWT-encoded OpenID Connect IdToken
private Date expiration; private Date expiration;
private String tokenType = OAuth2AccessToken.BEARER_TYPE; private String tokenType = OAuth2AccessToken.BEARER_TYPE;
@ -89,14 +89,14 @@ public class OAuth2AccessTokenEntity implements OAuth2AccessToken {
private OAuth2RefreshTokenEntity refreshToken; private OAuth2RefreshTokenEntity refreshToken;
private Set<String> scope; private Set<String> scope;
/** /**
* Create a new, blank access token * Create a new, blank access token
*/ */
public OAuth2AccessTokenEntity() { public OAuth2AccessTokenEntity() {
} }
/** /**
* @return the id * @return the id
*/ */
@ -114,8 +114,9 @@ public class OAuth2AccessTokenEntity implements OAuth2AccessToken {
} }
/** /**
* Get all additional information to be sent to the serializer. Inserts a copy of the IdToken (in JWT String form). * Get all additional information to be sent to the serializer. Inserts a copy of the IdToken (in JWT String form).
*/ */
@Override
@Transient @Transient
public Map<String, Object> getAdditionalInformation() { public Map<String, Object> getAdditionalInformation() {
Map<String, Object> map = new HashMap<String, Object>(); //super.getAdditionalInformation(); Map<String, Object> map = new HashMap<String, Object>(); //super.getAdditionalInformation();
@ -124,121 +125,127 @@ public class OAuth2AccessTokenEntity implements OAuth2AccessToken {
} }
return map; return map;
} }
/** /**
* The authentication in place when this token was created. * The authentication in place when this token was created.
* @return the authentication * @return the authentication
*/ */
@ManyToOne @ManyToOne
@JoinColumn(name = "auth_holder_id") @JoinColumn(name = "auth_holder_id")
public AuthenticationHolderEntity getAuthenticationHolder() { public AuthenticationHolderEntity getAuthenticationHolder() {
return authenticationHolder; return authenticationHolder;
} }
/** /**
* @param authentication the authentication to set * @param authentication the authentication to set
*/ */
public void setAuthenticationHolder(AuthenticationHolderEntity authenticationHolder) { public void setAuthenticationHolder(AuthenticationHolderEntity authenticationHolder) {
this.authenticationHolder = authenticationHolder; this.authenticationHolder = authenticationHolder;
} }
/** /**
* @return the client * @return the client
*/ */
@ManyToOne @ManyToOne
@JoinColumn(name = "client_id") @JoinColumn(name = "client_id")
public ClientDetailsEntity getClient() { public ClientDetailsEntity getClient() {
return client; return client;
} }
/** /**
* @param client the client to set * @param client the client to set
*/ */
public void setClient(ClientDetailsEntity client) { public void setClient(ClientDetailsEntity client) {
this.client = client; this.client = client;
} }
/** /**
* Get the string-encoded value of this access token. * Get the string-encoded value of this access token.
*/ */
@Basic @Override
@Column(name="token_value") @Basic
public String getValue() { @Column(name="token_value")
public String getValue() {
return jwtValue.serialize(); return jwtValue.serialize();
} }
/** /**
* Set the "value" of this Access Token * Set the "value" of this Access Token
* *
* @param value the JWT string * @param value the JWT string
* @throws ParseException if "value" is not a properly formatted JWT string * @throws ParseException if "value" is not a properly formatted JWT string
*/ */
public void setValue(String value) throws ParseException { public void setValue(String value) throws ParseException {
setJwt(JWTParser.parse(value)); setJwt(JWTParser.parse(value));
} }
@Basic @Override
@Temporal(javax.persistence.TemporalType.TIMESTAMP) @Basic
public Date getExpiration() { @Temporal(javax.persistence.TemporalType.TIMESTAMP)
return expiration; public Date getExpiration() {
} return expiration;
}
public void setExpiration(Date expiration) { public void setExpiration(Date expiration) {
this.expiration = expiration; this.expiration = expiration;
} }
@Basic @Override
@Column(name="token_type") @Basic
public String getTokenType() { @Column(name="token_type")
return tokenType; public String getTokenType() {
} return tokenType;
}
public void setTokenType(String tokenType) { public void setTokenType(String tokenType) {
this.tokenType = tokenType; this.tokenType = tokenType;
} }
@ManyToOne @Override
@JoinColumn(name="refresh_token_id") @ManyToOne
public OAuth2RefreshTokenEntity getRefreshToken() { @JoinColumn(name="refresh_token_id")
return refreshToken; public OAuth2RefreshTokenEntity getRefreshToken() {
} return refreshToken;
}
public void setRefreshToken(OAuth2RefreshTokenEntity refreshToken) { public void setRefreshToken(OAuth2RefreshTokenEntity refreshToken) {
this.refreshToken = refreshToken; this.refreshToken = refreshToken;
} }
public void setRefreshToken(OAuth2RefreshToken refreshToken) { public void setRefreshToken(OAuth2RefreshToken refreshToken) {
if (!(refreshToken instanceof OAuth2RefreshTokenEntity)) { if (!(refreshToken instanceof OAuth2RefreshTokenEntity)) {
// TODO: make a copy constructor instead.... // TODO: make a copy constructor instead....
throw new IllegalArgumentException("Not a storable refresh token entity!"); throw new IllegalArgumentException("Not a storable refresh token entity!");
} }
// force a pass through to the entity version // force a pass through to the entity version
setRefreshToken((OAuth2RefreshTokenEntity)refreshToken); setRefreshToken((OAuth2RefreshTokenEntity)refreshToken);
} }
@ElementCollection(fetch=FetchType.EAGER)
@CollectionTable(
joinColumns=@JoinColumn(name="owner_id"),
name="token_scope"
)
public Set<String> getScope() {
return scope;
}
public void setScope(Set<String> scope) { @Override
this.scope = scope; @ElementCollection(fetch=FetchType.EAGER)
} @CollectionTable(
joinColumns=@JoinColumn(name="owner_id"),
name="token_scope"
)
public Set<String> getScope() {
return scope;
}
@Transient public void setScope(Set<String> scope) {
this.scope = scope;
}
@Override
@Transient
public boolean isExpired() { public boolean isExpired() {
return getExpiration() == null ? false : System.currentTimeMillis() > getExpiration().getTime(); return getExpiration() == null ? false : System.currentTimeMillis() > getExpiration().getTime();
} }
/** /**
* @return the idToken * @return the idToken
*/ */
@OneToOne(cascade=CascadeType.ALL) // one-to-one mapping for now @OneToOne(cascade=CascadeType.ALL) // one-to-one mapping for now
@JoinColumn(name = "id_token_id") @JoinColumn(name = "id_token_id")
public OAuth2AccessTokenEntity getIdToken() { public OAuth2AccessTokenEntity getIdToken() {
return idToken; return idToken;
} }
@ -249,7 +256,7 @@ public class OAuth2AccessTokenEntity implements OAuth2AccessToken {
public void setIdToken(OAuth2AccessTokenEntity idToken) { public void setIdToken(OAuth2AccessTokenEntity idToken) {
this.idToken = idToken; this.idToken = idToken;
} }
/** /**
* @return the idTokenString * @return the idTokenString
*/ */

View File

@ -39,9 +39,7 @@ import javax.persistence.Transient;
import org.springframework.security.oauth2.common.OAuth2RefreshToken; import org.springframework.security.oauth2.common.OAuth2RefreshToken;
import com.nimbusds.jwt.JWT; import com.nimbusds.jwt.JWT;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.JWTParser; import com.nimbusds.jwt.JWTParser;
import com.nimbusds.jwt.PlainJWT;
/** /**
* @author jricher * @author jricher
@ -58,14 +56,14 @@ import com.nimbusds.jwt.PlainJWT;
public class OAuth2RefreshTokenEntity implements OAuth2RefreshToken { public class OAuth2RefreshTokenEntity implements OAuth2RefreshToken {
private Long id; private Long id;
private AuthenticationHolderEntity authenticationHolder; private AuthenticationHolderEntity authenticationHolder;
private ClientDetailsEntity client; private ClientDetailsEntity client;
//JWT-encoded representation of this access token entity //JWT-encoded representation of this access token entity
private JWT jwt; private JWT jwt;
// our refresh tokens might expire // our refresh tokens might expire
private Date expiration; private Date expiration;
@ -91,97 +89,98 @@ public class OAuth2RefreshTokenEntity implements OAuth2RefreshToken {
public void setId(Long id) { public void setId(Long id) {
this.id = id; this.id = id;
} }
/**
* The authentication in place when the original access token was
* created
*
* @return the authentication
*/
@ManyToOne
@JoinColumn(name = "auth_holder_id")
public AuthenticationHolderEntity getAuthenticationHolder() {
return authenticationHolder;
}
/** /**
* @param authentication the authentication to set * The authentication in place when the original access token was
*/ * created
public void setAuthenticationHolder(AuthenticationHolderEntity authenticationHolder) { *
this.authenticationHolder = authenticationHolder; * @return the authentication
} */
@ManyToOne
@JoinColumn(name = "auth_holder_id")
public AuthenticationHolderEntity getAuthenticationHolder() {
return authenticationHolder;
}
/**
* @param authentication the authentication to set
*/
public void setAuthenticationHolder(AuthenticationHolderEntity authenticationHolder) {
this.authenticationHolder = authenticationHolder;
}
/** /**
* Get the JWT-encoded value of this token * Get the JWT-encoded value of this token
*/ */
@Basic @Override
@Column(name="token_value") @Basic
public String getValue() { @Column(name="token_value")
return jwt.serialize(); public String getValue() {
} return jwt.serialize();
}
/** /**
* Set the value of this token as a string. Parses the string into a JWT. * Set the value of this token as a string. Parses the string into a JWT.
* @param value * @param value
* @throws ParseException if the value is not a valid JWT string * @throws ParseException if the value is not a valid JWT string
*/ */
public void setValue(String value) throws ParseException { public void setValue(String value) throws ParseException {
setJwt(JWTParser.parse(value)); setJwt(JWTParser.parse(value));
} }
@Basic @Basic
@Temporal(javax.persistence.TemporalType.TIMESTAMP) @Temporal(javax.persistence.TemporalType.TIMESTAMP)
public Date getExpiration() { public Date getExpiration() {
return expiration; return expiration;
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.springframework.security.oauth2.common.ExpiringOAuth2RefreshToken#setExpiration(java.util.Date) * @see org.springframework.security.oauth2.common.ExpiringOAuth2RefreshToken#setExpiration(java.util.Date)
*/ */
public void setExpiration(Date expiration) {
this.expiration = expiration;
}
/** public void setExpiration(Date expiration) {
* Has this token expired? this.expiration = expiration;
* @return true if it has a timeout set and the timeout has passed }
*/
@Transient /**
* Has this token expired?
* @return true if it has a timeout set and the timeout has passed
*/
@Transient
public boolean isExpired() { public boolean isExpired() {
return getExpiration() == null ? false : System.currentTimeMillis() > getExpiration().getTime(); return getExpiration() == null ? false : System.currentTimeMillis() > getExpiration().getTime();
} }
/** /**
* @return the client * @return the client
*/ */
@ManyToOne(fetch = FetchType.EAGER) @ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "client_id") @JoinColumn(name = "client_id")
public ClientDetailsEntity getClient() { public ClientDetailsEntity getClient() {
return client; return client;
} }
/** /**
* @param client the client to set * @param client the client to set
*/ */
public void setClient(ClientDetailsEntity client) { public void setClient(ClientDetailsEntity client) {
this.client = client; this.client = client;
} }
/**
* Get the JWT object directly
* @return the jwt
*/
@Transient
public JWT getJwt() {
return jwt;
}
/**
* @param jwt the jwt to set
*/
public void setJwt(JWT jwt) {
this.jwt = jwt;
}
/**
* Get the JWT object directly
* @return the jwt
*/
@Transient
public JWT getJwt() {
return jwt;
}
/**
* @param jwt the jwt to set
*/
public void setJwt(JWT jwt) {
this.jwt = jwt;
}
} }

View File

@ -28,7 +28,7 @@ public class SystemScope {
private Long id; private Long id;
private String value; // scope value private String value; // scope value
private String description; // human-readable description private String description; // human-readable description
private String icon; // class of the icon to display on the auth page private String icon; // class of the icon to display on the auth page
private boolean allowDynReg = false; // can a dynamically registered client ask for this scope? private boolean allowDynReg = false; // can a dynamically registered client ask for this scope?
private boolean defaultScope = false; // is this a default scope for newly-registered clients? private boolean defaultScope = false; // is this a default scope for newly-registered clients?
@ -36,16 +36,16 @@ public class SystemScope {
* Make a blank system scope with no value * Make a blank system scope with no value
*/ */
public SystemScope() { public SystemScope() {
} }
/** /**
* Make a system scope with the given scope value * Make a system scope with the given scope value
* @param value * @param value
*/ */
public SystemScope(String value) { public SystemScope(String value) {
this.value = value; this.value = value;
} }
/** /**
* @return the id * @return the id
*/ */
@ -117,7 +117,7 @@ public class SystemScope {
public void setAllowDynReg(boolean allowDynReg) { public void setAllowDynReg(boolean allowDynReg) {
this.allowDynReg = allowDynReg; this.allowDynReg = allowDynReg;
} }
/** /**
* @return the defaultScope * @return the defaultScope
*/ */
@ -136,71 +136,71 @@ public class SystemScope {
/* (non-Javadoc) /* (non-Javadoc)
* @see java.lang.Object#hashCode() * @see java.lang.Object#hashCode()
*/ */
@Override @Override
public int hashCode() { public int hashCode() {
final int prime = 31; final int prime = 31;
int result = 1; int result = 1;
result = prime * result + (allowDynReg ? 1231 : 1237); result = prime * result + (allowDynReg ? 1231 : 1237);
result = prime * result + (defaultScope ? 1231 : 1237); result = prime * result + (defaultScope ? 1231 : 1237);
result = prime * result + ((description == null) ? 0 : description.hashCode()); result = prime * result + ((description == null) ? 0 : description.hashCode());
result = prime * result + ((icon == null) ? 0 : icon.hashCode()); result = prime * result + ((icon == null) ? 0 : icon.hashCode());
result = prime * result + ((id == null) ? 0 : id.hashCode()); result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((value == null) ? 0 : value.hashCode()); result = prime * result + ((value == null) ? 0 : value.hashCode());
return result; return result;
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object) * @see java.lang.Object#equals(java.lang.Object)
*/ */
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (this == obj) { if (this == obj) {
return true; return true;
} }
if (obj == null) { if (obj == null) {
return false; return false;
} }
if (getClass() != obj.getClass()) { if (getClass() != obj.getClass()) {
return false; return false;
} }
SystemScope other = (SystemScope) obj; SystemScope other = (SystemScope) obj;
if (allowDynReg != other.allowDynReg) { if (allowDynReg != other.allowDynReg) {
return false; return false;
} }
if (defaultScope != other.defaultScope) { if (defaultScope != other.defaultScope) {
return false; return false;
} }
if (description == null) { if (description == null) {
if (other.description != null) { if (other.description != null) {
return false; return false;
} }
} else if (!description.equals(other.description)) { } else if (!description.equals(other.description)) {
return false; return false;
} }
if (icon == null) { if (icon == null) {
if (other.icon != null) { if (other.icon != null) {
return false; return false;
} }
} else if (!icon.equals(other.icon)) { } else if (!icon.equals(other.icon)) {
return false; return false;
} }
if (id == null) { if (id == null) {
if (other.id != null) { if (other.id != null) {
return false; return false;
} }
} else if (!id.equals(other.id)) { } else if (!id.equals(other.id)) {
return false; return false;
} }
if (value == null) { if (value == null) {
if (other.value != null) { if (other.value != null) {
return false; return false;
} }
} else if (!value.equals(other.value)) { } else if (!value.equals(other.value)) {
return false; return false;
} }
return true; return true;
} }
} }

View File

@ -6,13 +6,13 @@ import org.springframework.security.oauth2.provider.OAuth2Authentication;
public interface AuthenticationHolderRepository { public interface AuthenticationHolderRepository {
public AuthenticationHolderEntity getById(Long id); public AuthenticationHolderEntity getById(Long id);
public AuthenticationHolderEntity getByAuthentication(OAuth2Authentication a); public AuthenticationHolderEntity getByAuthentication(OAuth2Authentication a);
public void removeById(Long id); public void removeById(Long id);
public void remove(AuthenticationHolderEntity a); public void remove(AuthenticationHolderEntity a);
public AuthenticationHolderEntity save(AuthenticationHolderEntity a); public AuthenticationHolderEntity save(AuthenticationHolderEntity a);
} }

View File

@ -5,7 +5,7 @@ import org.springframework.security.oauth2.common.exceptions.InvalidGrantExcepti
import org.springframework.security.oauth2.provider.OAuth2Authentication; import org.springframework.security.oauth2.provider.OAuth2Authentication;
/** /**
* Interface for saving and consuming OAuth2 authorization codes as AuthorizationCodeEntitys. * Interface for saving and consuming OAuth2 authorization codes as AuthorizationCodeEntitys.
* *
* @author aanganes * @author aanganes
* *
@ -19,14 +19,14 @@ public interface AuthorizationCodeRepository {
* @return the saved AuthorizationCodeEntity * @return the saved AuthorizationCodeEntity
*/ */
public AuthorizationCodeEntity save(AuthorizationCodeEntity authorizationCode); public AuthorizationCodeEntity save(AuthorizationCodeEntity authorizationCode);
/** /**
* Consume an authorization code. * Consume an authorization code.
* *
* @param code the authorization code value * @param code the authorization code value
* @return the authentication associated with the code * @return the authentication associated with the code
* @throws InvalidGrantException if no AuthorizationCodeEntity is found with the given value * @throws InvalidGrantException if no AuthorizationCodeEntity is found with the given value
*/ */
public OAuth2Authentication consume(String code) throws InvalidGrantException; public OAuth2Authentication consume(String code) throws InvalidGrantException;
} }

View File

@ -20,7 +20,7 @@ import java.util.Collection;
import org.mitre.oauth2.model.ClientDetailsEntity; import org.mitre.oauth2.model.ClientDetailsEntity;
public interface OAuth2ClientRepository { public interface OAuth2ClientRepository {
public ClientDetailsEntity getById(Long id); public ClientDetailsEntity getById(Long id);
public ClientDetailsEntity getClientByClientId(String clientId); public ClientDetailsEntity getClientByClientId(String clientId);

View File

@ -27,17 +27,17 @@ public interface OAuth2TokenRepository {
public OAuth2AccessTokenEntity saveAccessToken(OAuth2AccessTokenEntity token); public OAuth2AccessTokenEntity saveAccessToken(OAuth2AccessTokenEntity token);
public OAuth2RefreshTokenEntity getRefreshTokenByValue(String refreshTokenValue); public OAuth2RefreshTokenEntity getRefreshTokenByValue(String refreshTokenValue);
public OAuth2RefreshTokenEntity getRefreshTokenById(Long Id); public OAuth2RefreshTokenEntity getRefreshTokenById(Long Id);
public void clearAccessTokensForRefreshToken(OAuth2RefreshTokenEntity refreshToken); public void clearAccessTokensForRefreshToken(OAuth2RefreshTokenEntity refreshToken);
public void removeRefreshToken(OAuth2RefreshTokenEntity refreshToken); public void removeRefreshToken(OAuth2RefreshTokenEntity refreshToken);
public OAuth2RefreshTokenEntity saveRefreshToken(OAuth2RefreshTokenEntity refreshToken); public OAuth2RefreshTokenEntity saveRefreshToken(OAuth2RefreshTokenEntity refreshToken);
public OAuth2AccessTokenEntity getAccessTokenByValue(String accessTokenValue); public OAuth2AccessTokenEntity getAccessTokenByValue(String accessTokenValue);
public OAuth2AccessTokenEntity getAccessTokenById(Long id); public OAuth2AccessTokenEntity getAccessTokenById(Long id);
public void removeAccessToken(OAuth2AccessTokenEntity accessToken); public void removeAccessToken(OAuth2AccessTokenEntity accessToken);
@ -55,8 +55,8 @@ public interface OAuth2TokenRepository {
public OAuth2AccessTokenEntity getByAuthentication(OAuth2Authentication auth); public OAuth2AccessTokenEntity getByAuthentication(OAuth2Authentication auth);
/** /**
* @return * @return
*/ */
public OAuth2AccessTokenEntity getAccessTokenForIdToken(OAuth2AccessTokenEntity idToken); public OAuth2AccessTokenEntity getAccessTokenForIdToken(OAuth2AccessTokenEntity idToken);
} }

View File

@ -14,13 +14,13 @@ import org.mitre.oauth2.model.SystemScope;
public interface SystemScopeRepository { public interface SystemScopeRepository {
public Set<SystemScope> getAll(); public Set<SystemScope> getAll();
public SystemScope getById(Long id); public SystemScope getById(Long id);
public SystemScope getByValue(String value); public SystemScope getByValue(String value);
public void remove(SystemScope scope); public void remove(SystemScope scope);
public SystemScope save(SystemScope scope); public SystemScope save(SystemScope scope);
} }

View File

@ -24,19 +24,20 @@ import org.springframework.security.oauth2.provider.ClientDetailsService;
public interface ClientDetailsEntityService extends ClientDetailsService { public interface ClientDetailsEntityService extends ClientDetailsService {
public ClientDetailsEntity saveNewClient(ClientDetailsEntity client); public ClientDetailsEntity saveNewClient(ClientDetailsEntity client);
public ClientDetailsEntity getClientById(Long id); public ClientDetailsEntity getClientById(Long id);
@Override
public ClientDetailsEntity loadClientByClientId(String clientId) throws OAuth2Exception; public ClientDetailsEntity loadClientByClientId(String clientId) throws OAuth2Exception;
public void deleteClient(ClientDetailsEntity client); public void deleteClient(ClientDetailsEntity client);
public ClientDetailsEntity updateClient(ClientDetailsEntity oldClient, ClientDetailsEntity newClient); public ClientDetailsEntity updateClient(ClientDetailsEntity oldClient, ClientDetailsEntity newClient);
public Collection<ClientDetailsEntity> getAllClients(); public Collection<ClientDetailsEntity> getAllClients();
public ClientDetailsEntity generateClientId(ClientDetailsEntity client); public ClientDetailsEntity generateClientId(ClientDetailsEntity client);
public ClientDetailsEntity generateClientSecret(ClientDetailsEntity client); public ClientDetailsEntity generateClientSecret(ClientDetailsEntity client);
} }

View File

@ -26,32 +26,34 @@ import org.springframework.security.oauth2.provider.token.ResourceServerTokenSer
public interface OAuth2TokenEntityService extends AuthorizationServerTokenServices, ResourceServerTokenServices { public interface OAuth2TokenEntityService extends AuthorizationServerTokenServices, ResourceServerTokenServices {
@Override
public OAuth2AccessTokenEntity readAccessToken(String accessTokenValue); public OAuth2AccessTokenEntity readAccessToken(String accessTokenValue);
public OAuth2RefreshTokenEntity getRefreshToken(String refreshTokenValue); public OAuth2RefreshTokenEntity getRefreshToken(String refreshTokenValue);
public void revokeRefreshToken(OAuth2RefreshTokenEntity refreshToken); public void revokeRefreshToken(OAuth2RefreshTokenEntity refreshToken);
public void revokeAccessToken(OAuth2AccessTokenEntity accessToken); public void revokeAccessToken(OAuth2AccessTokenEntity accessToken);
public List<OAuth2AccessTokenEntity> getAccessTokensForClient(ClientDetailsEntity client); public List<OAuth2AccessTokenEntity> getAccessTokensForClient(ClientDetailsEntity client);
public List<OAuth2RefreshTokenEntity> getRefreshTokensForClient(ClientDetailsEntity client); public List<OAuth2RefreshTokenEntity> getRefreshTokensForClient(ClientDetailsEntity client);
public void clearExpiredTokens(); public void clearExpiredTokens();
public OAuth2AccessTokenEntity saveAccessToken(OAuth2AccessTokenEntity accessToken); public OAuth2AccessTokenEntity saveAccessToken(OAuth2AccessTokenEntity accessToken);
public OAuth2RefreshTokenEntity saveRefreshToken(OAuth2RefreshTokenEntity refreshToken); public OAuth2RefreshTokenEntity saveRefreshToken(OAuth2RefreshTokenEntity refreshToken);
@Override
public OAuth2AccessTokenEntity getAccessToken(OAuth2Authentication authentication); public OAuth2AccessTokenEntity getAccessToken(OAuth2Authentication authentication);
public OAuth2AccessTokenEntity getAccessTokenById(Long id); public OAuth2AccessTokenEntity getAccessTokenById(Long id);
/** /**
* @param incomingToken * @param incomingToken
* @return * @return
*/ */
public OAuth2AccessTokenEntity getAccessTokenForIdToken(OAuth2AccessTokenEntity idToken); public OAuth2AccessTokenEntity getAccessTokenForIdToken(OAuth2AccessTokenEntity idToken);
} }

View File

@ -12,15 +12,15 @@ import org.mitre.oauth2.model.SystemScope;
* *
*/ */
public interface SystemScopeService { public interface SystemScopeService {
public Set<SystemScope> getAll(); public Set<SystemScope> getAll();
/** /**
* Get all scopes that are defaulted to new clients on this system * Get all scopes that are defaulted to new clients on this system
* @return * @return
*/ */
public Set<SystemScope> getDefaults(); public Set<SystemScope> getDefaults();
/** /**
* Get all scopes that are allowed for dynamic registration on this system * Get all scopes that are allowed for dynamic registration on this system
* @return * @return
@ -28,20 +28,20 @@ public interface SystemScopeService {
public Set<SystemScope> getDynReg(); public Set<SystemScope> getDynReg();
public SystemScope getById(Long id); public SystemScope getById(Long id);
public SystemScope getByValue(String value); public SystemScope getByValue(String value);
public void remove(SystemScope scope); public void remove(SystemScope scope);
public SystemScope save(SystemScope scope); public SystemScope save(SystemScope scope);
/** /**
* Translate the set of scope strings into a set of SystemScope objects. * Translate the set of scope strings into a set of SystemScope objects.
* @param scope * @param scope
* @return * @return
*/ */
public Set<SystemScope> fromStrings(Set<String> scope); public Set<SystemScope> fromStrings(Set<String> scope);
/** /**
* Pluck the scope values from the set of SystemScope objects and return a list of strings * Pluck the scope values from the set of SystemScope objects and return a list of strings
* @param scope * @param scope

View File

@ -17,7 +17,6 @@ package org.mitre.oauth2.service.impl;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException; import org.springframework.dao.DataAccessException;
@ -44,32 +43,32 @@ public class DefaultClientUserDetailsService implements UserDetailsService {
private ClientDetailsService clientDetailsService; private ClientDetailsService clientDetailsService;
@Override @Override
public UserDetails loadUserByUsername(String clientId) throws UsernameNotFoundException, DataAccessException { public UserDetails loadUserByUsername(String clientId) throws UsernameNotFoundException, DataAccessException {
ClientDetails client = clientDetailsService.loadClientByClientId(clientId); ClientDetails client = clientDetailsService.loadClientByClientId(clientId);
if (client != null) { if (client != null) {
String password = client.getClientSecret(); String password = client.getClientSecret();
boolean enabled = true; boolean enabled = true;
boolean accountNonExpired = true; boolean accountNonExpired = true;
boolean credentialsNonExpired = true; boolean credentialsNonExpired = true;
boolean accountNonLocked = true; boolean accountNonLocked = true;
Collection<GrantedAuthority> authorities = client.getAuthorities(); Collection<GrantedAuthority> authorities = client.getAuthorities();
if (authorities == null || authorities.isEmpty()) { if (authorities == null || authorities.isEmpty()) {
// automatically inject ROLE_CLIENT if none exists ... // automatically inject ROLE_CLIENT if none exists ...
// TODO: this should probably happen on the client service side instead to keep it in the real data model // TODO: this should probably happen on the client service side instead to keep it in the real data model
authorities = new ArrayList<GrantedAuthority>(); authorities = new ArrayList<GrantedAuthority>();
GrantedAuthority roleClient = new SimpleGrantedAuthority("ROLE_CLIENT"); GrantedAuthority roleClient = new SimpleGrantedAuthority("ROLE_CLIENT");
authorities.add(roleClient); authorities.add(roleClient);
} }
return new User(clientId, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities); return new User(clientId, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);
} else { } else {
throw new UsernameNotFoundException("Client not found: " + clientId); throw new UsernameNotFoundException("Client not found: " + clientId);
} }
} }
public ClientDetailsService getClientDetailsService() { public ClientDetailsService getClientDetailsService() {
return clientDetailsService; return clientDetailsService;
@ -78,5 +77,5 @@ public class DefaultClientUserDetailsService implements UserDetailsService {
public void setClientDetailsService(ClientDetailsService clientDetailsService) { public void setClientDetailsService(ClientDetailsService clientDetailsService) {
this.clientDetailsService = clientDetailsService; this.clientDetailsService = clientDetailsService;
} }
} }

View File

@ -20,7 +20,7 @@ package org.mitre.openid.connect.config;
/** /**
* Bean to hold configuration information that must be injected into various parts * Bean to hold configuration information that must be injected into various parts
* of our application. Set all of the properties here, and autowire a reference * of our application. Set all of the properties here, and autowire a reference
* to this bean if you need access to any configuration properties. * to this bean if you need access to any configuration properties.
* *
* @author AANGANES * @author AANGANES
* *
@ -28,22 +28,22 @@ package org.mitre.openid.connect.config;
public class ConfigurationPropertiesBean { public class ConfigurationPropertiesBean {
private String issuer; private String issuer;
private String topbarTitle; private String topbarTitle;
private String logoImageUrl; private String logoImageUrl;
public ConfigurationPropertiesBean() { public ConfigurationPropertiesBean() {
} }
/** /**
* @return the issuer baseUrl * @return the issuer baseUrl
*/ */
public String getIssuer() { public String getIssuer() {
return issuer; return issuer;
} }
/** /**
* @param iss the issuer to set * @param iss the issuer to set
*/ */

View File

@ -31,9 +31,9 @@ public class ServerConfiguration {
private String tokenEndpointUri; private String tokenEndpointUri;
private String issuer; private String issuer;
private String jwksUri; private String jwksUri;
private String userInfoUri; private String userInfoUri;
/** /**
@ -105,5 +105,5 @@ public class ServerConfiguration {
public void setUserInfoUri(String userInfoUri) { public void setUserInfoUri(String userInfoUri) {
this.userInfoUri = userInfoUri; this.userInfoUri = userInfoUri;
} }
} }

View File

@ -27,7 +27,7 @@ import javax.persistence.Table;
@Table(name="address") @Table(name="address")
public class Address { public class Address {
private Long id; private Long id;
private String formatted; private String formatted;
private String streetAddress; private String streetAddress;
@ -35,14 +35,14 @@ public class Address {
private String region; private String region;
private String postalCode; private String postalCode;
private String country; private String country;
/** /**
* Empty constructor * Empty constructor
*/ */
public Address() { public Address() {
} }
/** /**
* @return the formatted address string * @return the formatted address string
*/ */
@ -125,19 +125,19 @@ public class Address {
} }
/** /**
* @return the id * @return the id
*/ */
@Id @Id
@GeneratedValue(strategy=GenerationType.IDENTITY) @GeneratedValue(strategy=GenerationType.IDENTITY)
public Long getId() { public Long getId() {
return id; return id;
} }
/** /**
* @param id the id to set * @param id the id to set
*/ */
public void setId(Long id) { public void setId(Long id) {
this.id = id; this.id = id;
} }
} }

View File

@ -52,164 +52,164 @@ import com.google.common.collect.Sets;
public class ApprovedSite { public class ApprovedSite {
// unique id // unique id
private Long id; private Long id;
// which user made the approval // which user made the approval
private String userId; private String userId;
// which OAuth2 client is this tied to // which OAuth2 client is this tied to
private String clientId; private String clientId;
// when was this first approved? // when was this first approved?
private Date creationDate; private Date creationDate;
// when was this last accessed? // when was this last accessed?
private Date accessDate; private Date accessDate;
// if this is a time-limited access, when does it run out? // if this is a time-limited access, when does it run out?
private Date timeoutDate; private Date timeoutDate;
// what scopes have been allowed // what scopes have been allowed
// this should include all information for what data to access // this should include all information for what data to access
private Set<String> allowedScopes; private Set<String> allowedScopes;
// If this AP is a WS, link to the WS // If this AP is a WS, link to the WS
private WhitelistedSite whitelistedSite; private WhitelistedSite whitelistedSite;
//Link to any access tokens approved through this stored decision //Link to any access tokens approved through this stored decision
private Set<OAuth2AccessTokenEntity> approvedAccessTokens = Sets.newHashSet(); private Set<OAuth2AccessTokenEntity> approvedAccessTokens = Sets.newHashSet();
/** /**
* Empty constructor * Empty constructor
*/ */
public ApprovedSite() { public ApprovedSite() {
} }
/** /**
* @return the id * @return the id
*/ */
@Id @Id
@GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue(strategy = GenerationType.IDENTITY)
public Long getId() { public Long getId() {
return id; return id;
} }
/** /**
* @param id the id to set * @param id the id to set
*/ */
public void setId(Long id) { public void setId(Long id) {
this.id = id; this.id = id;
} }
/** /**
* @return the userInfo * @return the userInfo
*/ */
@Basic @Basic
@Column(name="user_id") @Column(name="user_id")
public String getUserId() { public String getUserId() {
return userId; return userId;
} }
/** /**
* @param userInfo the userInfo to set * @param userInfo the userInfo to set
*/ */
public void setUserId(String userId) { public void setUserId(String userId) {
this.userId = userId; this.userId = userId;
} }
/** /**
* @return the clientId * @return the clientId
*/ */
@Basic @Basic
@Column(name="client_id") @Column(name="client_id")
public String getClientId() { public String getClientId() {
return clientId; return clientId;
} }
/** /**
* @param clientId the clientId to set * @param clientId the clientId to set
*/ */
public void setClientId(String clientId) { public void setClientId(String clientId) {
this.clientId = clientId; this.clientId = clientId;
} }
/** /**
* @return the creationDate * @return the creationDate
*/ */
@Basic @Basic
@Temporal(javax.persistence.TemporalType.TIMESTAMP) @Temporal(javax.persistence.TemporalType.TIMESTAMP)
@Column(name="creation_date") @Column(name="creation_date")
public Date getCreationDate() { public Date getCreationDate() {
return creationDate; return creationDate;
} }
/** /**
* @param creationDate the creationDate to set * @param creationDate the creationDate to set
*/ */
public void setCreationDate(Date creationDate) { public void setCreationDate(Date creationDate) {
this.creationDate = creationDate; this.creationDate = creationDate;
} }
/** /**
* @return the accessDate * @return the accessDate
*/ */
@Basic @Basic
@Temporal(javax.persistence.TemporalType.TIMESTAMP) @Temporal(javax.persistence.TemporalType.TIMESTAMP)
@Column(name="access_date") @Column(name="access_date")
public Date getAccessDate() { public Date getAccessDate() {
return accessDate; return accessDate;
} }
/** /**
* @param accessDate the accessDate to set * @param accessDate the accessDate to set
*/ */
public void setAccessDate(Date accessDate) { public void setAccessDate(Date accessDate) {
this.accessDate = accessDate; this.accessDate = accessDate;
} }
/** /**
* @return the allowedScopes * @return the allowedScopes
*/ */
@ElementCollection(fetch = FetchType.EAGER) @ElementCollection(fetch = FetchType.EAGER)
@CollectionTable( @CollectionTable(
name="approved_site_scope", name="approved_site_scope",
joinColumns=@JoinColumn(name="owner_id") joinColumns=@JoinColumn(name="owner_id")
) )
@Column(name="scope") @Column(name="scope")
public Set<String> getAllowedScopes() { public Set<String> getAllowedScopes() {
return allowedScopes; return allowedScopes;
} }
/** /**
* @param allowedScopes the allowedScopes to set * @param allowedScopes the allowedScopes to set
*/ */
public void setAllowedScopes(Set<String> allowedScopes) { public void setAllowedScopes(Set<String> allowedScopes) {
this.allowedScopes = allowedScopes; this.allowedScopes = allowedScopes;
} }
/** /**
* @return the timeoutDate * @return the timeoutDate
*/ */
@Basic @Basic
@Temporal(javax.persistence.TemporalType.TIMESTAMP) @Temporal(javax.persistence.TemporalType.TIMESTAMP)
@Column(name="timeout_date") @Column(name="timeout_date")
public Date getTimeoutDate() { public Date getTimeoutDate() {
return timeoutDate; return timeoutDate;
} }
/** /**
* @param timeoutDate the timeoutDate to set * @param timeoutDate the timeoutDate to set
*/ */
public void setTimeoutDate(Date timeoutDate) { public void setTimeoutDate(Date timeoutDate) {
this.timeoutDate = timeoutDate; this.timeoutDate = timeoutDate;
} }
/** /**
* Does this AP entry correspond to a WS? * Does this AP entry correspond to a WS?
* @return * @return
*/ */
@Transient @Transient
public Boolean getIsWhitelisted() { public Boolean getIsWhitelisted() {
return (whitelistedSite != null); return (whitelistedSite != null);
} }
@ -227,10 +227,10 @@ public class ApprovedSite {
/** /**
* Has this approval expired? * Has this approval expired?
* @return * @return
*/ */
@Transient @Transient
public boolean isExpired() { public boolean isExpired() {
if (getTimeoutDate() != null) { if (getTimeoutDate() != null) {
Date now = new Date(); Date now = new Date();
if (now.after(getTimeoutDate())) { if (now.after(getTimeoutDate())) {
@ -241,7 +241,7 @@ public class ApprovedSite {
} else { } else {
return false; return false;
} }
} }
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER) @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
@JoinColumn(name="approved_site_id") @JoinColumn(name="approved_site_id")
@ -255,5 +255,5 @@ public class ApprovedSite {
public void setApprovedAccessTokens(Set<OAuth2AccessTokenEntity> approvedAccessTokens) { public void setApprovedAccessTokens(Set<OAuth2AccessTokenEntity> approvedAccessTokens) {
this.approvedAccessTokens = approvedAccessTokens; this.approvedAccessTokens = approvedAccessTokens;
} }
} }

View File

@ -24,41 +24,41 @@ import javax.persistence.Table;
}) })
public class BlacklistedSite { public class BlacklistedSite {
// unique id // unique id
private Long id; private Long id;
// URI pattern to black list // URI pattern to black list
private String uri; private String uri;
public BlacklistedSite() { public BlacklistedSite() {
} }
/** /**
* @return the id * @return the id
*/ */
@Id @Id
@GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue(strategy = GenerationType.IDENTITY)
public Long getId() { public Long getId() {
return id; return id;
} }
/** /**
* @param id the id to set * @param id the id to set
*/ */
public void setId(Long id) { public void setId(Long id) {
this.id = id; this.id = id;
} }
@Basic @Basic
@Column(name="uri") @Column(name="uri")
public String getUri() { public String getUri() {
return uri; return uri;
} }
public void setUri(String uri) {
this.uri = uri;
}
public void setUri(String uri) {
this.uri = uri;
}
} }

View File

@ -33,21 +33,21 @@ import com.google.gson.JsonObject;
@Table(name="user_info") @Table(name="user_info")
@NamedQueries({ @NamedQueries({
@NamedQuery(name="DefaultUserInfo.getAll", query = "select u from DefaultUserInfo u"), @NamedQuery(name="DefaultUserInfo.getAll", query = "select u from DefaultUserInfo u"),
@NamedQuery(name="DefaultUserInfo.getByUsername", query = "select u from DefaultUserInfo u WHERE u.preferredUsername = :username"), @NamedQuery(name="DefaultUserInfo.getByUsername", query = "select u from DefaultUserInfo u WHERE u.preferredUsername = :username"),
@NamedQuery(name="DefaultUserInfo.getBySubject", query = "select u from DefaultUserInfo u WHERE u.sub = :sub") @NamedQuery(name="DefaultUserInfo.getBySubject", query = "select u from DefaultUserInfo u WHERE u.sub = :sub")
}) })
public class DefaultUserInfo implements UserInfo { public class DefaultUserInfo implements UserInfo {
private Long id; private Long id;
private String sub; private String sub;
private String preferredUsername; private String preferredUsername;
private String name; private String name;
private String givenName; private String givenName;
private String familyName; private String familyName;
private String middleName; private String middleName;
private String nickname; private String nickname;
private String profile; private String profile;
private String picture; private String picture;
private String website; private String website;
private String email; private String email;
private Boolean emailVerified; private Boolean emailVerified;
@ -58,8 +58,8 @@ public class DefaultUserInfo implements UserInfo {
private Address address; private Address address;
private String updatedTime; private String updatedTime;
private String birthdate; private String birthdate;
/** /**
* @return the id * @return the id
*/ */
@ -356,21 +356,23 @@ public class DefaultUserInfo implements UserInfo {
} }
/** /**
* @return the birthdate * @return the birthdate
*/ */
@Override
@Basic @Basic
@Column(name="birthdate") @Column(name="birthdate")
public String getBirthdate() { public String getBirthdate() {
return birthdate; return birthdate;
} }
/** /**
* @param birthdate the birthdate to set * @param birthdate the birthdate to set
*/ */
public void setBirthdate(String birthdate) { @Override
this.birthdate = birthdate; public void setBirthdate(String birthdate) {
} this.birthdate = birthdate;
}
/** /**
* Parse a JsonObject into a UserInfo. * Parse a JsonObject into a UserInfo.
* @param o * @param o
* @return * @return
@ -379,7 +381,7 @@ public class DefaultUserInfo implements UserInfo {
DefaultUserInfo ui = new DefaultUserInfo(); DefaultUserInfo ui = new DefaultUserInfo();
ui.setSub(obj.has("sub") ? obj.get("sub").getAsString() : null); ui.setSub(obj.has("sub") ? obj.get("sub").getAsString() : null);
ui.setName(obj.has("name") ? obj.get("name").getAsString() : null); ui.setName(obj.has("name") ? obj.get("name").getAsString() : null);
ui.setPreferredUsername(obj.has("preferred_username") ? obj.get("preferred_username").getAsString() : null); ui.setPreferredUsername(obj.has("preferred_username") ? obj.get("preferred_username").getAsString() : null);
ui.setGivenName(obj.has("given_name") ? obj.get("given_name").getAsString() : null); ui.setGivenName(obj.has("given_name") ? obj.get("given_name").getAsString() : null);
@ -394,29 +396,29 @@ public class DefaultUserInfo implements UserInfo {
ui.setLocale(obj.has("locale") ? obj.get("locale").getAsString() : null); ui.setLocale(obj.has("locale") ? obj.get("locale").getAsString() : null);
ui.setUpdatedTime(obj.has("updated_time") ? obj.get("updated_time").getAsString() : null); ui.setUpdatedTime(obj.has("updated_time") ? obj.get("updated_time").getAsString() : null);
ui.setBirthdate(obj.has("birthdate") ? obj.get("birthdate").getAsString() : null); ui.setBirthdate(obj.has("birthdate") ? obj.get("birthdate").getAsString() : null);
ui.setEmail(obj.has("email") ? obj.get("email").getAsString() : null); ui.setEmail(obj.has("email") ? obj.get("email").getAsString() : null);
ui.setEmailVerified(obj.has("email_verified") ? obj.get("email_verified").getAsBoolean() : null); ui.setEmailVerified(obj.has("email_verified") ? obj.get("email_verified").getAsBoolean() : null);
ui.setPhoneNumber(obj.has("phone_number") ? obj.get("phone_number").getAsString() : null); ui.setPhoneNumber(obj.has("phone_number") ? obj.get("phone_number").getAsString() : null);
if (obj.has("address") && obj.get("address").isJsonObject()) { if (obj.has("address") && obj.get("address").isJsonObject()) {
JsonObject addr = obj.get("address").getAsJsonObject(); JsonObject addr = obj.get("address").getAsJsonObject();
ui.setAddress(new Address()); ui.setAddress(new Address());
ui.getAddress().setFormatted(addr.has("formatted") ? addr.get("formatted").getAsString() : null); ui.getAddress().setFormatted(addr.has("formatted") ? addr.get("formatted").getAsString() : null);
ui.getAddress().setStreetAddress(addr.has("street_address") ? addr.get("street_address").getAsString() : null); ui.getAddress().setStreetAddress(addr.has("street_address") ? addr.get("street_address").getAsString() : null);
ui.getAddress().setLocality(addr.has("locality") ? addr.get("locality").getAsString() : null); ui.getAddress().setLocality(addr.has("locality") ? addr.get("locality").getAsString() : null);
ui.getAddress().setRegion(addr.has("region") ? addr.get("region").getAsString() : null); ui.getAddress().setRegion(addr.has("region") ? addr.get("region").getAsString() : null);
ui.getAddress().setPostalCode(addr.has("postal_code") ? addr.get("postal_code").getAsString() : null); ui.getAddress().setPostalCode(addr.has("postal_code") ? addr.get("postal_code").getAsString() : null);
ui.getAddress().setCountry(addr.has("country") ? addr.get("country").getAsString() : null); ui.getAddress().setCountry(addr.has("country") ? addr.get("country").getAsString() : null);
} }
return ui; return ui;
} }
} }

View File

@ -37,50 +37,50 @@ import javax.persistence.Temporal;
public class Event { public class Event {
public static enum EventType { LOGIN, AUTHORIZATION, ACCESS } public static enum EventType { LOGIN, AUTHORIZATION, ACCESS }
private Long id; private Long id;
private EventType type; private EventType type;
private Date timestamp; private Date timestamp;
/** /**
* @return the id * @return the id
*/ */
@Id @Id
@GeneratedValue(strategy=GenerationType.IDENTITY) @GeneratedValue(strategy=GenerationType.IDENTITY)
public Long getId() { public Long getId() {
return id; return id;
} }
/** /**
* @param id the id to set * @param id the id to set
*/ */
public void setId(Long id) { public void setId(Long id) {
this.id = id; this.id = id;
} }
/** /**
* @return the type * @return the type
*/ */
public EventType getType() { public EventType getType() {
return type; return type;
} }
/** /**
* @param type the type to set * @param type the type to set
*/ */
public void setType(EventType type) { public void setType(EventType type) {
this.type = type; this.type = type;
} }
/** /**
* @return the timestamp * @return the timestamp
*/ */
@Basic @Basic
@Temporal(javax.persistence.TemporalType.TIMESTAMP) @Temporal(javax.persistence.TemporalType.TIMESTAMP)
public Date getTimestamp() { public Date getTimestamp() {
return timestamp; return timestamp;
} }
/** /**
* @param timestamp the timestamp to set * @param timestamp the timestamp to set
*/ */
public void setTimestamp(Date timestamp) { public void setTimestamp(Date timestamp) {
this.timestamp = timestamp; this.timestamp = timestamp;
} }
} }

View File

@ -23,16 +23,16 @@ import javax.persistence.Temporal;
}) })
public class Nonce { public class Nonce {
private Long id; //the ID of this Nonce private Long id; //the ID of this Nonce
private String value; //the value of this Nonce private String value; //the value of this Nonce
private String clientId;//The id of the client who used this Nonce private String clientId;//The id of the client who used this Nonce
private Date useDate; //the date this Nonce was used private Date useDate; //the date this Nonce was used
private Date expireDate; //the date after which this Nonce should be removed from the database private Date expireDate; //the date after which this Nonce should be removed from the database
/** /**
* @return the id * @return the id
@ -86,7 +86,7 @@ public class Nonce {
* @return the useDate * @return the useDate
*/ */
@Basic @Basic
@Temporal(javax.persistence.TemporalType.TIMESTAMP) @Temporal(javax.persistence.TemporalType.TIMESTAMP)
@Column(name="use_date") @Column(name="use_date")
public Date getUseDate() { public Date getUseDate() {
return useDate; return useDate;
@ -103,7 +103,7 @@ public class Nonce {
* @return the expireDate * @return the expireDate
*/ */
@Basic @Basic
@Temporal(javax.persistence.TemporalType.TIMESTAMP) @Temporal(javax.persistence.TemporalType.TIMESTAMP)
@Column(name="expire_date") @Column(name="expire_date")
public Date getExpireDate() { public Date getExpireDate() {
return expireDate; return expireDate;
@ -115,8 +115,8 @@ public class Nonce {
public void setExpireDate(Date expireDate) { public void setExpireDate(Date expireDate) {
this.expireDate = expireDate; this.expireDate = expireDate;
} }
} }

View File

@ -12,12 +12,12 @@ public interface UserInfo {
* @param sub the userId to set * @param sub the userId to set
*/ */
public abstract void setSub(String sub); public abstract void setSub(String sub);
/** /**
* @return the preferred username * @return the preferred username
*/ */
public abstract String getPreferredUsername(); public abstract String getPreferredUsername();
/** /**
* @param preferredUsername the preferredUsername to set * @param preferredUsername the preferredUsername to set
*/ */
@ -189,7 +189,7 @@ public interface UserInfo {
* @return * @return
*/ */
public abstract String getBirthdate(); public abstract String getBirthdate();
/** /**
* *
* @param birthdate * @param birthdate

View File

@ -32,7 +32,7 @@ import javax.persistence.NamedQuery;
import javax.persistence.Table; import javax.persistence.Table;
/** /**
* Indicator that login to a site should be automatically granted * Indicator that login to a site should be automatically granted
* without user interaction. * without user interaction.
* @author jricher, aanganes * @author jricher, aanganes
* *
@ -40,21 +40,21 @@ import javax.persistence.Table;
@Entity @Entity
@Table(name="whitelisted_site") @Table(name="whitelisted_site")
@NamedQueries({ @NamedQueries({
@NamedQuery(name = "WhitelistedSite.getAll", query = "select w from WhitelistedSite w"), @NamedQuery(name = "WhitelistedSite.getAll", query = "select w from WhitelistedSite w"),
@NamedQuery(name = "WhitelistedSite.getByClientId", query = "select w from WhitelistedSite w where w.clientId = :clientId"), @NamedQuery(name = "WhitelistedSite.getByClientId", query = "select w from WhitelistedSite w where w.clientId = :clientId"),
@NamedQuery(name = "WhitelistedSite.getByCreatoruserId", query = "select w from WhitelistedSite w where w.creatorUserId = :userId") @NamedQuery(name = "WhitelistedSite.getByCreatoruserId", query = "select w from WhitelistedSite w where w.creatorUserId = :userId")
}) })
public class WhitelistedSite { public class WhitelistedSite {
// unique id // unique id
private Long id; private Long id;
// Reference to the admin user who created this entry // Reference to the admin user who created this entry
private String creatorUserId; private String creatorUserId;
// which OAuth2 client is this tied to // which OAuth2 client is this tied to
private String clientId; private String clientId;
// what scopes be allowed by default // what scopes be allowed by default
// this should include all information for what data to access // this should include all information for what data to access
private Set<String> allowedScopes; private Set<String> allowedScopes;
@ -63,14 +63,14 @@ public class WhitelistedSite {
* Empty constructor * Empty constructor
*/ */
public WhitelistedSite() { public WhitelistedSite() {
} }
/** /**
* @return the id * @return the id
*/ */
@Id @Id
@GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue(strategy = GenerationType.IDENTITY)
public Long getId() { public Long getId() {
return id; return id;
} }
@ -103,9 +103,9 @@ public class WhitelistedSite {
*/ */
@ElementCollection(fetch = FetchType.EAGER) @ElementCollection(fetch = FetchType.EAGER)
@CollectionTable( @CollectionTable(
name="whitelisted_site_scope", name="whitelisted_site_scope",
joinColumns=@JoinColumn(name="owner_id") joinColumns=@JoinColumn(name="owner_id")
) )
@Column(name="scope") @Column(name="scope")
public Set<String> getAllowedScopes() { public Set<String> getAllowedScopes() {
return allowedScopes; return allowedScopes;

View File

@ -50,7 +50,7 @@ public interface ApprovedSiteRepository {
* @param clientId * @param clientId
* @param userId * @param userId
* @return * @return
*/ */
public Collection<ApprovedSite> getByClientIdAndUserId(String clientId, String userId); public Collection<ApprovedSite> getByClientIdAndUserId(String clientId, String userId);
/** /**
@ -69,14 +69,14 @@ public interface ApprovedSiteRepository {
* @return the persisted entity * @return the persisted entity
*/ */
public ApprovedSite save(ApprovedSite approvedSite); public ApprovedSite save(ApprovedSite approvedSite);
/** /**
* Get all sites approved by this user * Get all sites approved by this user
* @param userId * @param userId
* @return * @return
*/ */
public Collection<ApprovedSite> getByUserId(String userId); public Collection<ApprovedSite> getByUserId(String userId);
/** /**
* Get all sites associated with this client * Get all sites associated with this client
* @param clientId * @param clientId

View File

@ -14,13 +14,13 @@ import org.mitre.openid.connect.model.BlacklistedSite;
public interface BlacklistedSiteRepository { public interface BlacklistedSiteRepository {
public Collection<BlacklistedSite> getAll(); public Collection<BlacklistedSite> getAll();
public BlacklistedSite getById(Long id); public BlacklistedSite getById(Long id);
public void remove(BlacklistedSite blacklistedSite); public void remove(BlacklistedSite blacklistedSite);
public BlacklistedSite save(BlacklistedSite blacklistedSite); public BlacklistedSite save(BlacklistedSite blacklistedSite);
public BlacklistedSite update(BlacklistedSite oldBlacklistedSite, BlacklistedSite blacklistedSite); public BlacklistedSite update(BlacklistedSite oldBlacklistedSite, BlacklistedSite blacklistedSite);
} }

View File

@ -47,8 +47,8 @@ public interface EventRepository {
* @param startChunk * @param startChunk
* the start chuck of a list you desire * the start chuck of a list you desire
* @param chunkSize * @param chunkSize
* the size of the chunk you desire * the size of the chunk you desire
* *
* @return a Collection of Events * @return a Collection of Events
*/ */
public Collection<Event> getEventsDuringPeriod(Date start, Date end, int startChunk, int chunkSize); public Collection<Event> getEventsDuringPeriod(Date start, Date end, int startChunk, int chunkSize);

View File

@ -1,6 +1,7 @@
package org.mitre.openid.connect.repository; package org.mitre.openid.connect.repository;
import java.util.Collection; import java.util.Collection;
import org.mitre.openid.connect.model.Nonce; import org.mitre.openid.connect.model.Nonce;
/** /**
@ -19,14 +20,14 @@ public interface NonceRepository {
* @return the nonce, if found * @return the nonce, if found
*/ */
public Nonce getById(Long id); public Nonce getById(Long id);
/** /**
* Remove the given Nonce from the database * Remove the given Nonce from the database
* *
* @param nonce the Nonce to remove * @param nonce the Nonce to remove
*/ */
public void remove(Nonce nonce); public void remove(Nonce nonce);
/** /**
* Save a new Nonce in the database * Save a new Nonce in the database
* *
@ -34,21 +35,21 @@ public interface NonceRepository {
* @return the saved Nonce * @return the saved Nonce
*/ */
public Nonce save(Nonce nonce); public Nonce save(Nonce nonce);
/** /**
* Return all nonces stored in the database * Return all nonces stored in the database
* *
* @return the set of nonces * @return the set of nonces
*/ */
public Collection<Nonce> getAll(); public Collection<Nonce> getAll();
/** /**
* Return all expired nonces stored in the database * Return all expired nonces stored in the database
* *
* @return the set of expired nonces * @return the set of expired nonces
*/ */
public Collection<Nonce> getExpired(); public Collection<Nonce> getExpired();
/** /**
* Return the set of nonces registered to the given client ID * Return the set of nonces registered to the given client ID
* *
@ -56,5 +57,5 @@ public interface NonceRepository {
* @return the set of nonces registered to the client * @return the set of nonces registered to the client
*/ */
public Collection<Nonce> getByClientId(String clientId); public Collection<Nonce> getByClientId(String clientId);
} }

View File

@ -26,24 +26,24 @@ import org.mitre.openid.connect.model.UserInfo;
* *
*/ */
public interface UserInfoRepository { public interface UserInfoRepository {
/** /**
* Returns the UserInfo for the given subject * Returns the UserInfo for the given subject
* *
* @param sub * @param sub
* the subject of the UserInfo * the subject of the UserInfo
* @return a valid UserInfo if it exists, null otherwise * @return a valid UserInfo if it exists, null otherwise
*/ */
public UserInfo getBySubject(String sub); public UserInfo getBySubject(String sub);
/** /**
* Persists a UserInfo * Persists a UserInfo
* *
* @param user * @param user
* @return * @return
*/ */
public UserInfo save(UserInfo userInfo); public UserInfo save(UserInfo userInfo);
/** /**
* Removes the given UserInfo from the repository * Removes the given UserInfo from the repository
* *
@ -64,6 +64,6 @@ public interface UserInfoRepository {
* @param username * @param username
* @return * @return
*/ */
public UserInfo getByUsername(String username); public UserInfo getByUsername(String username);
} }

View File

@ -42,7 +42,7 @@ public interface WhitelistedSiteRepository {
* @return a valid WhitelistedSite if it exists, null otherwise * @return a valid WhitelistedSite if it exists, null otherwise
*/ */
public WhitelistedSite getById(Long id); public WhitelistedSite getById(Long id);
/** /**
* Find a WhitelistedSite by its associated ClientDetails reference * Find a WhitelistedSite by its associated ClientDetails reference
* *
@ -50,7 +50,7 @@ public interface WhitelistedSiteRepository {
* @return the corresponding WhitelistedSite if one exists for the RP, or null * @return the corresponding WhitelistedSite if one exists for the RP, or null
*/ */
public WhitelistedSite getByClientId(String clientId); public WhitelistedSite getByClientId(String clientId);
/** /**
* Return a collection of the WhitelistedSites created by a given user * Return a collection of the WhitelistedSites created by a given user
* *
@ -77,10 +77,10 @@ public interface WhitelistedSiteRepository {
/** /**
* Persist changes to a whitelistedSite. The ID of oldWhitelistedSite is retained. * Persist changes to a whitelistedSite. The ID of oldWhitelistedSite is retained.
* @param oldWhitelistedSite * @param oldWhitelistedSite
* @param whitelistedSite * @param whitelistedSite
* @return * @return
*/ */
public WhitelistedSite update(WhitelistedSite oldWhitelistedSite, WhitelistedSite whitelistedSite); public WhitelistedSite update(WhitelistedSite oldWhitelistedSite, WhitelistedSite whitelistedSite);
} }

View File

@ -30,17 +30,17 @@ import org.springframework.security.oauth2.provider.ClientDetails;
* *
*/ */
public interface ApprovedSiteService { public interface ApprovedSiteService {
public ApprovedSite createApprovedSite(String clientId, String userId, Date timeoutDate, Set<String> allowedScopes, WhitelistedSite whitelistedSite); public ApprovedSite createApprovedSite(String clientId, String userId, Date timeoutDate, Set<String> allowedScopes, WhitelistedSite whitelistedSite);
/** /**
* Return a collection of all ApprovedSites * Return a collection of all ApprovedSites
* *
* @return the ApprovedSite collection, or null * @return the ApprovedSite collection, or null
*/ */
public Collection<ApprovedSite> getAll(); public Collection<ApprovedSite> getAll();
/** /**
* Return a collection of ApprovedSite managed by this repository matching the * Return a collection of ApprovedSite managed by this repository matching the
* provided client ID and user ID * provided client ID and user ID
@ -48,9 +48,9 @@ public interface ApprovedSiteService {
* @param clientId * @param clientId
* @param userId * @param userId
* @return * @return
*/ */
public Collection<ApprovedSite> getByClientIdAndUserId(String clientId, String userId); public Collection<ApprovedSite> getByClientIdAndUserId(String clientId, String userId);
/** /**
* Save an ApprovedSite * Save an ApprovedSite
* *
@ -82,14 +82,14 @@ public interface ApprovedSiteService {
* @return * @return
*/ */
public Collection<ApprovedSite> getByUserId(String userId); public Collection<ApprovedSite> getByUserId(String userId);
/** /**
* Get all sites associated with this client * Get all sites associated with this client
* @param clientId * @param clientId
* @return * @return
*/ */
public Collection<ApprovedSite> getByClientId(String clientId); public Collection<ApprovedSite> getByClientId(String clientId);
/** /**
* Clear out any approved sites for a given client. * Clear out any approved sites for a given client.
* @param client * @param client

View File

@ -14,15 +14,15 @@ import org.mitre.openid.connect.model.BlacklistedSite;
public interface BlacklistedSiteService { public interface BlacklistedSiteService {
public Collection<BlacklistedSite> getAll(); public Collection<BlacklistedSite> getAll();
public BlacklistedSite getById(Long id); public BlacklistedSite getById(Long id);
public void remove(BlacklistedSite blacklistedSite); public void remove(BlacklistedSite blacklistedSite);
public BlacklistedSite saveNew(BlacklistedSite blacklistedSite); public BlacklistedSite saveNew(BlacklistedSite blacklistedSite);
public BlacklistedSite update(BlacklistedSite oldBlacklistedSite, BlacklistedSite blacklistedSite); public BlacklistedSite update(BlacklistedSite oldBlacklistedSite, BlacklistedSite blacklistedSite);
public boolean isBlacklisted(String uri); public boolean isBlacklisted(String uri);
} }

View File

@ -15,24 +15,24 @@ import org.mitre.openid.connect.model.Nonce;
public interface NonceService { public interface NonceService {
/** /**
* Create a new nonce. * Create a new nonce.
* *
* @param clientId the ID of the client * @param clientId the ID of the client
* @param value the value of the Nonce * @param value the value of the Nonce
* @return the saved Nonce * @return the saved Nonce
*/ */
public Nonce create(String clientId, String value); public Nonce create(String clientId, String value);
/** /**
* Check whether a given nonce value has been previously used and stored * Check whether a given nonce value has been previously used and stored
* by the client. * by the client.
* *
* @param clientId the ID of the client * @param clientId the ID of the client
* @param value the value of the nonce * @param value the value of the nonce
* @return true if the nonce has already been used, false otherwise * @return true if the nonce has already been used, false otherwise
*/ */
public boolean alreadyUsed(String clientId, String value); public boolean alreadyUsed(String clientId, String value);
/** /**
* Return the nonce with the given ID * Return the nonce with the given ID
* *
@ -40,14 +40,14 @@ public interface NonceService {
* @return the nonce, if found * @return the nonce, if found
*/ */
public Nonce getById(Long id); public Nonce getById(Long id);
/** /**
* Remove the given Nonce from the database * Remove the given Nonce from the database
* *
* @param nonce the Nonce to remove * @param nonce the Nonce to remove
*/ */
public void remove(Nonce nonce); public void remove(Nonce nonce);
/** /**
* Save a new Nonce in the database * Save a new Nonce in the database
* *
@ -55,21 +55,21 @@ public interface NonceService {
* @return the saved Nonce * @return the saved Nonce
*/ */
public Nonce save(Nonce nonce); public Nonce save(Nonce nonce);
/** /**
* Return all nonces stored in the database * Return all nonces stored in the database
* *
* @return the set of nonces * @return the set of nonces
*/ */
public Collection<Nonce> getAll(); public Collection<Nonce> getAll();
/** /**
* Return all expired nonces stored in the database * Return all expired nonces stored in the database
* *
* @return the set of expired nonces * @return the set of expired nonces
*/ */
public Collection<Nonce> getExpired(); public Collection<Nonce> getExpired();
/** /**
* Return the set of nonces registered to the given client ID * Return the set of nonces registered to the given client ID
* *
@ -82,5 +82,5 @@ public interface NonceService {
* Clear expired nonces from the database * Clear expired nonces from the database
*/ */
void clearExpiredNonces(); void clearExpiredNonces();
} }

View File

@ -14,9 +14,9 @@ public interface StatsService {
/** /**
* Calculate summary statistics * Calculate summary statistics
* approvalCount: total approved sites * approvalCount: total approved sites
* userCount: unique users * userCount: unique users
* clientCount: unique clients * clientCount: unique clients
* *
* @return * @return
*/ */
public Map<String, Integer> calculateSummaryStats(); public Map<String, Integer> calculateSummaryStats();

View File

@ -41,7 +41,7 @@ public interface UserInfoService {
* @return UserInfo for sub, or null * @return UserInfo for sub, or null
*/ */
public UserInfo getBySubject(String userId); public UserInfo getBySubject(String userId);
/** /**
* Remove the UserInfo * Remove the UserInfo
* *

View File

@ -33,7 +33,7 @@ public interface WhitelistedSiteService {
* @return the WhitelistedSite collection, or null * @return the WhitelistedSite collection, or null
*/ */
public Collection<WhitelistedSite> getAll(); public Collection<WhitelistedSite> getAll();
/** /**
* Returns the WhitelistedSite for the given id * Returns the WhitelistedSite for the given id
* *
@ -50,7 +50,7 @@ public interface WhitelistedSiteService {
* @return the corresponding WhitelistedSite if one exists for the RP, or null * @return the corresponding WhitelistedSite if one exists for the RP, or null
*/ */
public WhitelistedSite getByClientId(String clientId); public WhitelistedSite getByClientId(String clientId);
/** /**
* Return a collection of the WhitelistedSites created by a given user * Return a collection of the WhitelistedSites created by a given user
* *
@ -58,7 +58,7 @@ public interface WhitelistedSiteService {
* @return the collection of corresponding WhitelistedSites, if any, or null * @return the collection of corresponding WhitelistedSites, if any, or null
*/ */
public Collection<WhitelistedSite> getByCreator(String creatorId); public Collection<WhitelistedSite> getByCreator(String creatorId);
/** /**
* Removes the given WhitelistedSite from the repository * Removes the given WhitelistedSite from the repository
* *
@ -75,10 +75,10 @@ public interface WhitelistedSiteService {
* @return * @return
*/ */
public WhitelistedSite saveNew(WhitelistedSite whitelistedSite); public WhitelistedSite saveNew(WhitelistedSite whitelistedSite);
/** /**
* Updates an existing whitelisted site * Updates an existing whitelisted site
*/ */
public WhitelistedSite update(WhitelistedSite oldWhitelistedSite, WhitelistedSite whitelistedSite); public WhitelistedSite update(WhitelistedSite oldWhitelistedSite, WhitelistedSite whitelistedSite);
} }

View File

@ -42,27 +42,27 @@ import com.nimbusds.jose.jwk.JWKSet;
public class JwkKeyListView extends AbstractView { public class JwkKeyListView extends AbstractView {
private static Logger logger = LoggerFactory.getLogger(JwkKeyListView.class); private static Logger logger = LoggerFactory.getLogger(JwkKeyListView.class);
@Override @Override
protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) { protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) {
response.setContentType("application/json"); response.setContentType("application/json");
//BiMap<String, PublicKey> keyMap = (BiMap<String, PublicKey>) model.get("keys"); //BiMap<String, PublicKey> keyMap = (BiMap<String, PublicKey>) model.get("keys");
Map<String, JWK> keys = (Map<String, JWK>) model.get("keys"); Map<String, JWK> keys = (Map<String, JWK>) model.get("keys");
JWKSet jwkSet = new JWKSet(new ArrayList<JWK>(keys.values())); JWKSet jwkSet = new JWKSet(new ArrayList<JWK>(keys.values()));
try { try {
Writer out = response.getWriter(); Writer out = response.getWriter();
out.write(jwkSet.toString()); out.write(jwkSet.toString());
} catch (IOException e) { } catch (IOException e) {
logger.error("IOException in JwkKeyListView.java: ", e); logger.error("IOException in JwkKeyListView.java: ", e);
} }
} }

View File

@ -27,26 +27,26 @@ import org.springframework.dao.IncorrectResultSizeDataAccessException;
* Time: 2:13 PM * Time: 2:13 PM
*/ */
public class JpaUtil { public class JpaUtil {
public static <T> T getSingleResult(List<T> list) { public static <T> T getSingleResult(List<T> list) {
switch(list.size()) { switch(list.size()) {
case 0: case 0:
return null; return null;
case 1: case 1:
return list.get(0); return list.get(0);
default: default:
throw new IncorrectResultSizeDataAccessException(1); throw new IncorrectResultSizeDataAccessException(1);
} }
} }
public static <T, I> T saveOrUpdate(I id, EntityManager entityManager, T entity) { public static <T, I> T saveOrUpdate(I id, EntityManager entityManager, T entity) {
if (id == null) { if (id == null) {
entityManager.persist(entity); entityManager.persist(entity);
entityManager.flush(); entityManager.flush();
return entity; return entity;
} else { } else {
T tmp = entityManager.merge(entity); T tmp = entityManager.merge(entity);
entityManager.flush(); entityManager.flush();
return tmp; return tmp;
} }
} }
} }

View File

@ -18,13 +18,13 @@ package org.mitre.oauth2.exception;
public class DuplicateClientIdException extends RuntimeException { public class DuplicateClientIdException extends RuntimeException {
public DuplicateClientIdException(String clientId) { public DuplicateClientIdException(String clientId) {
super("Duplicate client id: " + clientId); super("Duplicate client id: " + clientId);
} }
/** /**
* *
*/ */
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
} }

View File

@ -17,7 +17,7 @@ public class JpaAuthenticationHolderRepository implements AuthenticationHolderRe
@PersistenceContext @PersistenceContext
private EntityManager manager; private EntityManager manager;
@Override @Override
public AuthenticationHolderEntity getById(Long id) { public AuthenticationHolderEntity getById(Long id) {
return manager.find(AuthenticationHolderEntity.class, id); return manager.find(AuthenticationHolderEntity.class, id);

View File

@ -27,16 +27,16 @@ public class JpaAuthorizationCodeRepository implements AuthorizationCodeReposito
@PersistenceContext @PersistenceContext
EntityManager manager; EntityManager manager;
/* (non-Javadoc) /* (non-Javadoc)
* @see org.mitre.oauth2.repository.AuthorizationCodeRepository#save(org.mitre.oauth2.model.AuthorizationCodeEntity) * @see org.mitre.oauth2.repository.AuthorizationCodeRepository#save(org.mitre.oauth2.model.AuthorizationCodeEntity)
*/ */
@Override @Override
@Transactional @Transactional
public AuthorizationCodeEntity save(AuthorizationCodeEntity authorizationCode) { public AuthorizationCodeEntity save(AuthorizationCodeEntity authorizationCode) {
return JpaUtil.saveOrUpdate(authorizationCode.getId(), manager, authorizationCode); return JpaUtil.saveOrUpdate(authorizationCode.getId(), manager, authorizationCode);
} }
/* (non-Javadoc) /* (non-Javadoc)
@ -45,20 +45,20 @@ public class JpaAuthorizationCodeRepository implements AuthorizationCodeReposito
@Override @Override
@Transactional @Transactional
public OAuth2Authentication consume(String code) throws InvalidGrantException { public OAuth2Authentication consume(String code) throws InvalidGrantException {
TypedQuery<AuthorizationCodeEntity> query = manager.createNamedQuery("AuthorizationCodeEntity.getByValue", AuthorizationCodeEntity.class); TypedQuery<AuthorizationCodeEntity> query = manager.createNamedQuery("AuthorizationCodeEntity.getByValue", AuthorizationCodeEntity.class);
query.setParameter("code", code); query.setParameter("code", code);
AuthorizationCodeEntity result = JpaUtil.getSingleResult(query.getResultList()); AuthorizationCodeEntity result = JpaUtil.getSingleResult(query.getResultList());
if (result == null) { if (result == null) {
throw new InvalidGrantException("JpaAuthorizationCodeRepository: no authorization code found for value " + code); throw new InvalidGrantException("JpaAuthorizationCodeRepository: no authorization code found for value " + code);
} }
OAuth2Authentication authRequest = result.getAuthentication(); OAuth2Authentication authRequest = result.getAuthentication();
manager.remove(result); manager.remove(result);
return authRequest; return authRequest;
} }

View File

@ -37,15 +37,16 @@ public class JpaOAuth2ClientRepository implements OAuth2ClientRepository {
@PersistenceContext @PersistenceContext
private EntityManager manager; private EntityManager manager;
public JpaOAuth2ClientRepository() { public JpaOAuth2ClientRepository() {
} }
public JpaOAuth2ClientRepository(EntityManager manager) { public JpaOAuth2ClientRepository(EntityManager manager) {
this.manager = manager; this.manager = manager;
} }
@Override
public ClientDetailsEntity getById(Long id) { public ClientDetailsEntity getById(Long id) {
return manager.find(ClientDetailsEntity.class, id); return manager.find(ClientDetailsEntity.class, id);
} }
@ -82,17 +83,17 @@ public class JpaOAuth2ClientRepository implements OAuth2ClientRepository {
} }
@Override @Override
public ClientDetailsEntity updateClient(Long id, ClientDetailsEntity client) { public ClientDetailsEntity updateClient(Long id, ClientDetailsEntity client) {
// sanity check // sanity check
client.setId(id); client.setId(id);
return JpaUtil.saveOrUpdate(id, manager, client); return JpaUtil.saveOrUpdate(id, manager, client);
} }
@Override @Override
public Collection<ClientDetailsEntity> getAllClients() { public Collection<ClientDetailsEntity> getAllClients() {
TypedQuery<ClientDetailsEntity> query = manager.createNamedQuery("ClientDetailsEntity.findAll", ClientDetailsEntity.class); TypedQuery<ClientDetailsEntity> query = manager.createNamedQuery("ClientDetailsEntity.findAll", ClientDetailsEntity.class);
return query.getResultList(); return query.getResultList();
} }
} }

View File

@ -42,18 +42,18 @@ public class JpaOAuth2TokenRepository implements OAuth2TokenRepository {
query.setParameter("tokenValue", accessTokenValue); query.setParameter("tokenValue", accessTokenValue);
return JpaUtil.getSingleResult(query.getResultList()); return JpaUtil.getSingleResult(query.getResultList());
} }
@Override @Override
public OAuth2AccessTokenEntity getAccessTokenById(Long id) { public OAuth2AccessTokenEntity getAccessTokenById(Long id) {
return manager.find(OAuth2AccessTokenEntity.class, id); return manager.find(OAuth2AccessTokenEntity.class, id);
} }
@Override @Override
@Transactional @Transactional
public OAuth2AccessTokenEntity saveAccessToken(OAuth2AccessTokenEntity token) { public OAuth2AccessTokenEntity saveAccessToken(OAuth2AccessTokenEntity token) {
return JpaUtil.saveOrUpdate(token.getId(), manager, token); return JpaUtil.saveOrUpdate(token.getId(), manager, token);
} }
@Override @Override
@Transactional @Transactional
public void removeAccessToken(OAuth2AccessTokenEntity accessToken) { public void removeAccessToken(OAuth2AccessTokenEntity accessToken) {
@ -64,17 +64,17 @@ public class JpaOAuth2TokenRepository implements OAuth2TokenRepository {
throw new IllegalArgumentException("Access token not found: " + accessToken); throw new IllegalArgumentException("Access token not found: " + accessToken);
} }
} }
@Override @Override
@Transactional @Transactional
public void clearAccessTokensForRefreshToken(OAuth2RefreshTokenEntity refreshToken) { public void clearAccessTokensForRefreshToken(OAuth2RefreshTokenEntity refreshToken) {
TypedQuery<OAuth2AccessTokenEntity> query = manager.createNamedQuery("OAuth2AccessTokenEntity.getByRefreshToken", OAuth2AccessTokenEntity.class); TypedQuery<OAuth2AccessTokenEntity> query = manager.createNamedQuery("OAuth2AccessTokenEntity.getByRefreshToken", OAuth2AccessTokenEntity.class);
query.setParameter("refreshToken", refreshToken); query.setParameter("refreshToken", refreshToken);
List<OAuth2AccessTokenEntity> accessTokens = query.getResultList(); List<OAuth2AccessTokenEntity> accessTokens = query.getResultList();
for (OAuth2AccessTokenEntity accessToken : accessTokens) { for (OAuth2AccessTokenEntity accessToken : accessTokens) {
removeAccessToken(accessToken); removeAccessToken(accessToken);
} }
} }
@Override @Override
public OAuth2RefreshTokenEntity getRefreshTokenByValue(String refreshTokenValue) { public OAuth2RefreshTokenEntity getRefreshTokenByValue(String refreshTokenValue) {
@ -82,105 +82,105 @@ public class JpaOAuth2TokenRepository implements OAuth2TokenRepository {
query.setParameter("tokenValue", refreshTokenValue); query.setParameter("tokenValue", refreshTokenValue);
return JpaUtil.getSingleResult(query.getResultList()); return JpaUtil.getSingleResult(query.getResultList());
} }
@Override @Override
public OAuth2RefreshTokenEntity getRefreshTokenById(Long id) { public OAuth2RefreshTokenEntity getRefreshTokenById(Long id) {
return manager.find(OAuth2RefreshTokenEntity.class, id); return manager.find(OAuth2RefreshTokenEntity.class, id);
} }
@Override @Override
@Transactional @Transactional
public OAuth2RefreshTokenEntity saveRefreshToken(OAuth2RefreshTokenEntity refreshToken) { public OAuth2RefreshTokenEntity saveRefreshToken(OAuth2RefreshTokenEntity refreshToken) {
return JpaUtil.saveOrUpdate(refreshToken.getId(), manager, refreshToken); return JpaUtil.saveOrUpdate(refreshToken.getId(), manager, refreshToken);
} }
@Override @Override
@Transactional @Transactional
public void removeRefreshToken(OAuth2RefreshTokenEntity refreshToken) { public void removeRefreshToken(OAuth2RefreshTokenEntity refreshToken) {
OAuth2RefreshTokenEntity found = getRefreshTokenByValue(refreshToken.getValue()); OAuth2RefreshTokenEntity found = getRefreshTokenByValue(refreshToken.getValue());
if (found != null) { if (found != null) {
manager.remove(found); manager.remove(found);
} else { } else {
throw new IllegalArgumentException("Refresh token not found: " + refreshToken); throw new IllegalArgumentException("Refresh token not found: " + refreshToken);
} }
} }
@Override @Override
@Transactional @Transactional
public void clearTokensForClient(ClientDetailsEntity client) { public void clearTokensForClient(ClientDetailsEntity client) {
TypedQuery<OAuth2AccessTokenEntity> queryA = manager.createNamedQuery("OAuth2AccessTokenEntity.getByClient", OAuth2AccessTokenEntity.class); TypedQuery<OAuth2AccessTokenEntity> queryA = manager.createNamedQuery("OAuth2AccessTokenEntity.getByClient", OAuth2AccessTokenEntity.class);
queryA.setParameter("client", client); queryA.setParameter("client", client);
List<OAuth2AccessTokenEntity> accessTokens = queryA.getResultList(); List<OAuth2AccessTokenEntity> accessTokens = queryA.getResultList();
for (OAuth2AccessTokenEntity accessToken : accessTokens) { for (OAuth2AccessTokenEntity accessToken : accessTokens) {
removeAccessToken(accessToken); removeAccessToken(accessToken);
} }
TypedQuery<OAuth2RefreshTokenEntity> queryR = manager.createNamedQuery("OAuth2RefreshTokenEntity.getByClient", OAuth2RefreshTokenEntity.class); TypedQuery<OAuth2RefreshTokenEntity> queryR = manager.createNamedQuery("OAuth2RefreshTokenEntity.getByClient", OAuth2RefreshTokenEntity.class);
queryR.setParameter("client", client); queryR.setParameter("client", client);
List<OAuth2RefreshTokenEntity> refreshTokens = queryR.getResultList(); List<OAuth2RefreshTokenEntity> refreshTokens = queryR.getResultList();
for (OAuth2RefreshTokenEntity refreshToken : refreshTokens) { for (OAuth2RefreshTokenEntity refreshToken : refreshTokens) {
removeRefreshToken(refreshToken); removeRefreshToken(refreshToken);
} }
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.mitre.oauth2.repository.OAuth2TokenRepository#getAccessTokensForClient(org.mitre.oauth2.model.ClientDetailsEntity) * @see org.mitre.oauth2.repository.OAuth2TokenRepository#getAccessTokensForClient(org.mitre.oauth2.model.ClientDetailsEntity)
*/ */
@Override @Override
public List<OAuth2AccessTokenEntity> getAccessTokensForClient(ClientDetailsEntity client) { public List<OAuth2AccessTokenEntity> getAccessTokensForClient(ClientDetailsEntity client) {
TypedQuery<OAuth2AccessTokenEntity> queryA = manager.createNamedQuery("OAuth2AccessTokenEntity.getByClient", OAuth2AccessTokenEntity.class); TypedQuery<OAuth2AccessTokenEntity> queryA = manager.createNamedQuery("OAuth2AccessTokenEntity.getByClient", OAuth2AccessTokenEntity.class);
queryA.setParameter("client", client); queryA.setParameter("client", client);
List<OAuth2AccessTokenEntity> accessTokens = queryA.getResultList(); List<OAuth2AccessTokenEntity> accessTokens = queryA.getResultList();
return accessTokens; return accessTokens;
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.mitre.oauth2.repository.OAuth2TokenRepository#getRefreshTokensForClient(org.mitre.oauth2.model.ClientDetailsEntity) * @see org.mitre.oauth2.repository.OAuth2TokenRepository#getRefreshTokensForClient(org.mitre.oauth2.model.ClientDetailsEntity)
*/ */
@Override @Override
public List<OAuth2RefreshTokenEntity> getRefreshTokensForClient(ClientDetailsEntity client) { public List<OAuth2RefreshTokenEntity> getRefreshTokensForClient(ClientDetailsEntity client) {
TypedQuery<OAuth2RefreshTokenEntity> queryR = manager.createNamedQuery("OAuth2RefreshTokenEntity.getByClient", OAuth2RefreshTokenEntity.class); TypedQuery<OAuth2RefreshTokenEntity> queryR = manager.createNamedQuery("OAuth2RefreshTokenEntity.getByClient", OAuth2RefreshTokenEntity.class);
queryR.setParameter("client", client); queryR.setParameter("client", client);
List<OAuth2RefreshTokenEntity> refreshTokens = queryR.getResultList(); List<OAuth2RefreshTokenEntity> refreshTokens = queryR.getResultList();
return refreshTokens; return refreshTokens;
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.mitre.oauth2.repository.OAuth2TokenRepository#getExpiredAccessTokens() * @see org.mitre.oauth2.repository.OAuth2TokenRepository#getExpiredAccessTokens()
*/ */
@Override @Override
public List<OAuth2AccessTokenEntity> getExpiredAccessTokens() { public List<OAuth2AccessTokenEntity> getExpiredAccessTokens() {
TypedQuery<OAuth2AccessTokenEntity> queryA = manager.createNamedQuery("OAuth2AccessTokenEntity.getExpired", OAuth2AccessTokenEntity.class); TypedQuery<OAuth2AccessTokenEntity> queryA = manager.createNamedQuery("OAuth2AccessTokenEntity.getExpired", OAuth2AccessTokenEntity.class);
List<OAuth2AccessTokenEntity> accessTokens = queryA.getResultList(); List<OAuth2AccessTokenEntity> accessTokens = queryA.getResultList();
return accessTokens; return accessTokens;
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.mitre.oauth2.repository.OAuth2TokenRepository#getExpiredRefreshTokens() * @see org.mitre.oauth2.repository.OAuth2TokenRepository#getExpiredRefreshTokens()
*/ */
@Override @Override
public List<OAuth2RefreshTokenEntity> getExpiredRefreshTokens() { public List<OAuth2RefreshTokenEntity> getExpiredRefreshTokens() {
TypedQuery<OAuth2RefreshTokenEntity> queryR = manager.createNamedQuery("OAuth2RefreshTokenEntity.getExpired", OAuth2RefreshTokenEntity.class); TypedQuery<OAuth2RefreshTokenEntity> queryR = manager.createNamedQuery("OAuth2RefreshTokenEntity.getExpired", OAuth2RefreshTokenEntity.class);
List<OAuth2RefreshTokenEntity> refreshTokens = queryR.getResultList(); List<OAuth2RefreshTokenEntity> refreshTokens = queryR.getResultList();
return refreshTokens; return refreshTokens;
} }
@Override @Override
public OAuth2AccessTokenEntity getByAuthentication(OAuth2Authentication auth) { public OAuth2AccessTokenEntity getByAuthentication(OAuth2Authentication auth) {
TypedQuery<OAuth2AccessTokenEntity> queryA = manager.createNamedQuery("OAuth2AccessTokenEntity.getByAuthentication", OAuth2AccessTokenEntity.class); TypedQuery<OAuth2AccessTokenEntity> queryA = manager.createNamedQuery("OAuth2AccessTokenEntity.getByAuthentication", OAuth2AccessTokenEntity.class);
queryA.setParameter("authentication", auth); queryA.setParameter("authentication", auth);
List<OAuth2AccessTokenEntity> accessTokens = queryA.getResultList(); List<OAuth2AccessTokenEntity> accessTokens = queryA.getResultList();
return JpaUtil.getSingleResult(accessTokens); return JpaUtil.getSingleResult(accessTokens);
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.mitre.oauth2.repository.OAuth2TokenRepository#getAccessTokenForIdToken(org.mitre.oauth2.model.OAuth2AccessTokenEntity) * @see org.mitre.oauth2.repository.OAuth2TokenRepository#getAccessTokenForIdToken(org.mitre.oauth2.model.OAuth2AccessTokenEntity)
*/ */
@Override @Override
public OAuth2AccessTokenEntity getAccessTokenForIdToken(OAuth2AccessTokenEntity idToken) { public OAuth2AccessTokenEntity getAccessTokenForIdToken(OAuth2AccessTokenEntity idToken) {
TypedQuery<OAuth2AccessTokenEntity> queryA = manager.createNamedQuery("OAuth2AccessTokenEntity.getByIdToken", OAuth2AccessTokenEntity.class); TypedQuery<OAuth2AccessTokenEntity> queryA = manager.createNamedQuery("OAuth2AccessTokenEntity.getByIdToken", OAuth2AccessTokenEntity.class);
queryA.setParameter("idToken", idToken); queryA.setParameter("idToken", idToken);
List<OAuth2AccessTokenEntity> accessTokens = queryA.getResultList(); List<OAuth2AccessTokenEntity> accessTokens = queryA.getResultList();
return JpaUtil.getSingleResult(accessTokens); return JpaUtil.getSingleResult(accessTokens);
} }
} }

View File

@ -3,6 +3,9 @@
*/ */
package org.mitre.oauth2.repository.impl; package org.mitre.oauth2.repository.impl;
import static org.mitre.util.jpa.JpaUtil.getSingleResult;
import static org.mitre.util.jpa.JpaUtil.saveOrUpdate;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.Set; import java.util.Set;
@ -15,9 +18,6 @@ import org.mitre.oauth2.repository.SystemScopeRepository;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import static org.mitre.util.jpa.JpaUtil.getSingleResult;
import static org.mitre.util.jpa.JpaUtil.saveOrUpdate;
/** /**
* @author jricher * @author jricher
* *
@ -27,7 +27,7 @@ public class JpaSystemScopeRepository implements SystemScopeRepository {
@PersistenceContext @PersistenceContext
private EntityManager em; private EntityManager em;
/* (non-Javadoc) /* (non-Javadoc)
* @see org.mitre.oauth2.repository.SystemScopeRepository#getAll() * @see org.mitre.oauth2.repository.SystemScopeRepository#getAll()
*/ */
@ -35,7 +35,7 @@ public class JpaSystemScopeRepository implements SystemScopeRepository {
@Transactional @Transactional
public Set<SystemScope> getAll() { public Set<SystemScope> getAll() {
TypedQuery<SystemScope> query = em.createNamedQuery("SystemScope.findAll", SystemScope.class); TypedQuery<SystemScope> query = em.createNamedQuery("SystemScope.findAll", SystemScope.class);
return new LinkedHashSet<SystemScope>(query.getResultList()); return new LinkedHashSet<SystemScope>(query.getResultList());
} }
@ -66,7 +66,7 @@ public class JpaSystemScopeRepository implements SystemScopeRepository {
@Transactional @Transactional
public void remove(SystemScope scope) { public void remove(SystemScope scope) {
SystemScope found = getById(scope.getId()); SystemScope found = getById(scope.getId());
if (found != null) { if (found != null) {
em.remove(found); em.remove(found);
} }

View File

@ -23,9 +23,9 @@ public class DefaultOAuth2AuthorizationCodeService implements AuthorizationCodeS
@Autowired @Autowired
private AuthorizationCodeRepository repository; private AuthorizationCodeRepository repository;
private RandomValueStringGenerator generator = new RandomValueStringGenerator(); private RandomValueStringGenerator generator = new RandomValueStringGenerator();
/** /**
* Generate a random authorization code and create an AuthorizationCodeEntity, * Generate a random authorization code and create an AuthorizationCodeEntity,
* which will be stored in the repository. * which will be stored in the repository.
@ -37,16 +37,16 @@ public class DefaultOAuth2AuthorizationCodeService implements AuthorizationCodeS
@Override @Override
public String createAuthorizationCode(OAuth2Authentication authentication) { public String createAuthorizationCode(OAuth2Authentication authentication) {
String code = generator.generate(); String code = generator.generate();
AuthorizationCodeEntity entity = new AuthorizationCodeEntity(code, authentication); AuthorizationCodeEntity entity = new AuthorizationCodeEntity(code, authentication);
repository.save(entity); repository.save(entity);
return code; return code;
} }
/** /**
* Consume a given authorization code. * Consume a given authorization code.
* Match the provided string to an AuthorizationCodeEntity. If one is found, return * Match the provided string to an AuthorizationCodeEntity. If one is found, return
* the authentication associated with the code. If one is not found, throw an * the authentication associated with the code. If one is not found, throw an
* InvalidGrantException. * InvalidGrantException.
* *
@ -56,7 +56,7 @@ public class DefaultOAuth2AuthorizationCodeService implements AuthorizationCodeS
*/ */
@Override @Override
public OAuth2Authentication consumeAuthorizationCode(String code) throws InvalidGrantException { public OAuth2Authentication consumeAuthorizationCode(String code) throws InvalidGrantException {
OAuth2Authentication auth = repository.consume(code); OAuth2Authentication auth = repository.consume(code);
return auth; return auth;
} }

View File

@ -39,32 +39,32 @@ import com.google.common.base.Strings;
@Service @Service
public class DefaultOAuth2ClientDetailsEntityService implements ClientDetailsEntityService { public class DefaultOAuth2ClientDetailsEntityService implements ClientDetailsEntityService {
@Autowired @Autowired
private OAuth2ClientRepository clientRepository; private OAuth2ClientRepository clientRepository;
@Autowired @Autowired
private OAuth2TokenRepository tokenRepository; private OAuth2TokenRepository tokenRepository;
@Autowired @Autowired
private ApprovedSiteService approvedSiteService; private ApprovedSiteService approvedSiteService;
@Autowired @Autowired
private WhitelistedSiteService whitelistedSiteService; private WhitelistedSiteService whitelistedSiteService;
@Autowired @Autowired
private BlacklistedSiteService blacklistedSiteService; private BlacklistedSiteService blacklistedSiteService;
public DefaultOAuth2ClientDetailsEntityService() { public DefaultOAuth2ClientDetailsEntityService() {
} }
public DefaultOAuth2ClientDetailsEntityService(OAuth2ClientRepository clientRepository, public DefaultOAuth2ClientDetailsEntityService(OAuth2ClientRepository clientRepository,
OAuth2TokenRepository tokenRepository) { OAuth2TokenRepository tokenRepository) {
this.clientRepository = clientRepository; this.clientRepository = clientRepository;
this.tokenRepository = tokenRepository; this.tokenRepository = tokenRepository;
} }
@Override @Override
public ClientDetailsEntity saveNewClient(ClientDetailsEntity client) { public ClientDetailsEntity saveNewClient(ClientDetailsEntity client) {
if (client.getId() != null) { // if it's not null, it's already been saved, this is an error if (client.getId() != null) { // if it's not null, it's already been saved, this is an error
@ -76,37 +76,38 @@ public class DefaultOAuth2ClientDetailsEntityService implements ClientDetailsEnt
if (blacklistedSiteService.isBlacklisted(uri)) { if (blacklistedSiteService.isBlacklisted(uri)) {
throw new IllegalArgumentException("Client URI is blacklisted: " + uri); throw new IllegalArgumentException("Client URI is blacklisted: " + uri);
} }
} }
} }
// assign a random clientid if it's empty // assign a random clientid if it's empty
// NOTE: don't assign a random client secret without asking, since public clients have no secret // NOTE: don't assign a random client secret without asking, since public clients have no secret
if (Strings.isNullOrEmpty(client.getClientId())) { if (Strings.isNullOrEmpty(client.getClientId())) {
client = generateClientId(client); client = generateClientId(client);
} }
// if the client is flagged to allow for refresh tokens, make sure it's got the right granted scopes // if the client is flagged to allow for refresh tokens, make sure it's got the right granted scopes
if (client.isAllowRefresh()) { if (client.isAllowRefresh()) {
client.getScope().add("offline_access"); client.getScope().add("offline_access");
} else { } else {
client.getScope().remove("offline_access"); client.getScope().remove("offline_access");
} }
// timestamp this to right now // timestamp this to right now
client.setCreatedAt(new Date()); client.setCreatedAt(new Date());
return clientRepository.saveClient(client); return clientRepository.saveClient(client);
} }
/** /**
* Get the client by its internal ID * Get the client by its internal ID
*/ */
@Override
public ClientDetailsEntity getClientById(Long id) { public ClientDetailsEntity getClientById(Long id) {
ClientDetailsEntity client = clientRepository.getById(id); ClientDetailsEntity client = clientRepository.getById(id);
return client; return client;
} }
/** /**
* Get the client for the given ClientID * Get the client for the given ClientID
*/ */
@ -121,87 +122,87 @@ public class DefaultOAuth2ClientDetailsEntityService implements ClientDetailsEnt
return client; return client;
} }
} }
throw new IllegalArgumentException("Client id must not be empty!"); throw new IllegalArgumentException("Client id must not be empty!");
} }
/** /**
* Delete a client and all its associated tokens * Delete a client and all its associated tokens
*/ */
@Override @Override
public void deleteClient(ClientDetailsEntity client) throws InvalidClientException { public void deleteClient(ClientDetailsEntity client) throws InvalidClientException {
if (clientRepository.getById(client.getId()) == null) { if (clientRepository.getById(client.getId()) == null) {
throw new InvalidClientException("Client with id " + client.getClientId() + " was not found"); throw new InvalidClientException("Client with id " + client.getClientId() + " was not found");
} }
// clean out any tokens that this client had issued // clean out any tokens that this client had issued
tokenRepository.clearTokensForClient(client); tokenRepository.clearTokensForClient(client);
// clean out any approved sites for this client // clean out any approved sites for this client
approvedSiteService.clearApprovedSitesForClient(client); approvedSiteService.clearApprovedSitesForClient(client);
// clear out any whitelisted sites for this client // clear out any whitelisted sites for this client
WhitelistedSite whitelistedSite = whitelistedSiteService.getByClientId(client.getClientId()); WhitelistedSite whitelistedSite = whitelistedSiteService.getByClientId(client.getClientId());
if (whitelistedSite != null) { if (whitelistedSite != null) {
whitelistedSiteService.remove(whitelistedSite); whitelistedSiteService.remove(whitelistedSite);
} }
// take care of the client itself // take care of the client itself
clientRepository.deleteClient(client); clientRepository.deleteClient(client);
} }
/** /**
* Update the oldClient with information from the newClient. The * Update the oldClient with information from the newClient. The
* id from oldClient is retained. * id from oldClient is retained.
*/ */
@Override @Override
public ClientDetailsEntity updateClient(ClientDetailsEntity oldClient, ClientDetailsEntity newClient) throws IllegalArgumentException { public ClientDetailsEntity updateClient(ClientDetailsEntity oldClient, ClientDetailsEntity newClient) throws IllegalArgumentException {
if (oldClient != null && newClient != null) { if (oldClient != null && newClient != null) {
for (String uri : newClient.getRegisteredRedirectUri()) { for (String uri : newClient.getRegisteredRedirectUri()) {
if (blacklistedSiteService.isBlacklisted(uri)) { if (blacklistedSiteService.isBlacklisted(uri)) {
throw new IllegalArgumentException("Client URI is blacklisted: " + uri); throw new IllegalArgumentException("Client URI is blacklisted: " + uri);
} }
} }
// if the client is flagged to allow for refresh tokens, make sure it's got the right scope
if (newClient.isAllowRefresh()) {
newClient.getScope().add("offline_access");
} else {
newClient.getScope().remove("offline_access");
}
return clientRepository.updateClient(oldClient.getId(), newClient); // if the client is flagged to allow for refresh tokens, make sure it's got the right scope
if (newClient.isAllowRefresh()) {
newClient.getScope().add("offline_access");
} else {
newClient.getScope().remove("offline_access");
}
return clientRepository.updateClient(oldClient.getId(), newClient);
} }
throw new IllegalArgumentException("Neither old client or new client can be null!"); throw new IllegalArgumentException("Neither old client or new client can be null!");
} }
/** /**
* Get all clients in the system * Get all clients in the system
*/ */
@Override @Override
public Collection<ClientDetailsEntity> getAllClients() { public Collection<ClientDetailsEntity> getAllClients() {
return clientRepository.getAllClients(); return clientRepository.getAllClients();
} }
/** /**
* Generates a clientId for the given client and sets it to the client's clientId field. Returns the client that was passed in, now with id set. * Generates a clientId for the given client and sets it to the client's clientId field. Returns the client that was passed in, now with id set.
*/ */
@Override @Override
public ClientDetailsEntity generateClientId(ClientDetailsEntity client) { public ClientDetailsEntity generateClientId(ClientDetailsEntity client) {
client.setClientId(UUID.randomUUID().toString()); client.setClientId(UUID.randomUUID().toString());
return client; return client;
} }
/** /**
* Generates a new clientSecret for the given client and sets it to the client's clientSecret field. Returns the client that was passed in, now with secret set. * Generates a new clientSecret for the given client and sets it to the client's clientSecret field. Returns the client that was passed in, now with secret set.
*/ */
@Override @Override
public ClientDetailsEntity generateClientSecret(ClientDetailsEntity client) { public ClientDetailsEntity generateClientSecret(ClientDetailsEntity client) {
client.setClientSecret(Base64.encodeBase64URLSafeString(new BigInteger(512, new SecureRandom()).toByteArray()).replace("=", "")); client.setClientSecret(Base64.encodeBase64URLSafeString(new BigInteger(512, new SecureRandom()).toByteArray()).replace("=", ""));
return client; return client;
} }
} }

View File

@ -59,159 +59,159 @@ import com.nimbusds.jwt.PlainJWT;
*/ */
@Service @Service
public class DefaultOAuth2ProviderTokenService implements OAuth2TokenEntityService { public class DefaultOAuth2ProviderTokenService implements OAuth2TokenEntityService {
private static Logger logger = LoggerFactory.getLogger(DefaultOAuth2ProviderTokenService.class); private static Logger logger = LoggerFactory.getLogger(DefaultOAuth2ProviderTokenService.class);
@Autowired @Autowired
private OAuth2TokenRepository tokenRepository; private OAuth2TokenRepository tokenRepository;
@Autowired @Autowired
private AuthenticationHolderRepository authenticationHolderRepository; private AuthenticationHolderRepository authenticationHolderRepository;
@Autowired @Autowired
private ClientDetailsEntityService clientDetailsService; private ClientDetailsEntityService clientDetailsService;
@Autowired @Autowired
private TokenEnhancer tokenEnhancer; private TokenEnhancer tokenEnhancer;
@Autowired @Autowired
private ApprovedSiteService approvedSiteService; private ApprovedSiteService approvedSiteService;
@Override @Override
public OAuth2AccessTokenEntity createAccessToken(OAuth2Authentication authentication) throws AuthenticationException, InvalidClientException { public OAuth2AccessTokenEntity createAccessToken(OAuth2Authentication authentication) throws AuthenticationException, InvalidClientException {
if (authentication != null && authentication.getOAuth2Request() != null) { if (authentication != null && authentication.getOAuth2Request() != null) {
// look up our client // look up our client
OAuth2Request clientAuth = authentication.getOAuth2Request(); OAuth2Request clientAuth = authentication.getOAuth2Request();
ClientDetailsEntity client = clientDetailsService.loadClientByClientId(clientAuth.getClientId()); ClientDetailsEntity client = clientDetailsService.loadClientByClientId(clientAuth.getClientId());
if (client == null) { if (client == null) {
throw new InvalidClientException("Client not found: " + clientAuth.getClientId()); throw new InvalidClientException("Client not found: " + clientAuth.getClientId());
} }
OAuth2AccessTokenEntity token = new OAuth2AccessTokenEntity();//accessTokenFactory.createNewAccessToken(); OAuth2AccessTokenEntity token = new OAuth2AccessTokenEntity();//accessTokenFactory.createNewAccessToken();
// attach the client
token.setClient(client);
// inherit the scope from the auth, but make a new set so it is
//not unmodifiable. Unmodifiables don't play nicely with Eclipselink, which
//wants to use the clone operation.
Set<String> scopes = Sets.newHashSet(clientAuth.getScope());
token.setScope(scopes);
// make it expire if necessary // attach the client
if (client.getAccessTokenValiditySeconds() != null && client.getAccessTokenValiditySeconds() > 0) { token.setClient(client);
Date expiration = new Date(System.currentTimeMillis() + (client.getAccessTokenValiditySeconds() * 1000L));
token.setExpiration(expiration);
}
// attach the authorization so that we can look it up later
AuthenticationHolderEntity authHolder = new AuthenticationHolderEntity();
authHolder.setAuthentication(authentication);
authHolder = authenticationHolderRepository.save(authHolder);
token.setAuthenticationHolder(authHolder);
// attach a refresh token, if this client is allowed to request them and the user gets the offline scope
// TODO: tie this to some kind of scope service
if (client.isAllowRefresh() && scopes.contains("offline_access")) {
OAuth2RefreshTokenEntity refreshToken = new OAuth2RefreshTokenEntity(); //refreshTokenFactory.createNewRefreshToken();
JWTClaimsSet refreshClaims = new JWTClaimsSet();
// inherit the scope from the auth, but make a new set so it is
// make it expire if necessary //not unmodifiable. Unmodifiables don't play nicely with Eclipselink, which
if (client.getRefreshTokenValiditySeconds() != null) { //wants to use the clone operation.
Date expiration = new Date(System.currentTimeMillis() + (client.getRefreshTokenValiditySeconds() * 1000L)); Set<String> scopes = Sets.newHashSet(clientAuth.getScope());
refreshToken.setExpiration(expiration); token.setScope(scopes);
refreshClaims.setExpirationTime(expiration);
} // make it expire if necessary
if (client.getAccessTokenValiditySeconds() != null && client.getAccessTokenValiditySeconds() > 0) {
// set a random identifier Date expiration = new Date(System.currentTimeMillis() + (client.getAccessTokenValiditySeconds() * 1000L));
refreshClaims.setJWTID(UUID.randomUUID().toString()); token.setExpiration(expiration);
}
// attach the authorization so that we can look it up later
AuthenticationHolderEntity authHolder = new AuthenticationHolderEntity();
authHolder.setAuthentication(authentication);
authHolder = authenticationHolderRepository.save(authHolder);
token.setAuthenticationHolder(authHolder);
// attach a refresh token, if this client is allowed to request them and the user gets the offline scope
// TODO: tie this to some kind of scope service
if (client.isAllowRefresh() && scopes.contains("offline_access")) {
OAuth2RefreshTokenEntity refreshToken = new OAuth2RefreshTokenEntity(); //refreshTokenFactory.createNewRefreshToken();
JWTClaimsSet refreshClaims = new JWTClaimsSet();
// make it expire if necessary
if (client.getRefreshTokenValiditySeconds() != null) {
Date expiration = new Date(System.currentTimeMillis() + (client.getRefreshTokenValiditySeconds() * 1000L));
refreshToken.setExpiration(expiration);
refreshClaims.setExpirationTime(expiration);
}
// set a random identifier
refreshClaims.setJWTID(UUID.randomUUID().toString());
// TODO: add issuer fields, signature to JWT
PlainJWT refreshJwt = new PlainJWT(refreshClaims);
refreshToken.setJwt(refreshJwt);
//Add the authentication
refreshToken.setAuthenticationHolder(authHolder);
refreshToken.setClient(client);
// save the token first so that we can set it to a member of the access token (NOTE: is this step necessary?)
tokenRepository.saveRefreshToken(refreshToken);
token.setRefreshToken(refreshToken);
}
tokenEnhancer.enhance(token, authentication);
tokenRepository.saveAccessToken(token);
//Add approved site reference, if any
OAuth2Request originalAuthRequest = authHolder.getAuthentication().getOAuth2Request();
if (originalAuthRequest.getExtensions() != null && originalAuthRequest.getExtensions().containsKey("approved_site")) {
// TODO: add issuer fields, signature to JWT
PlainJWT refreshJwt = new PlainJWT(refreshClaims);
refreshToken.setJwt(refreshJwt);
//Add the authentication
refreshToken.setAuthenticationHolder(authHolder);
refreshToken.setClient(client);
// save the token first so that we can set it to a member of the access token (NOTE: is this step necessary?)
tokenRepository.saveRefreshToken(refreshToken);
token.setRefreshToken(refreshToken);
}
tokenEnhancer.enhance(token, authentication);
tokenRepository.saveAccessToken(token);
//Add approved site reference, if any
OAuth2Request originalAuthRequest = authHolder.getAuthentication().getOAuth2Request();
if (originalAuthRequest.getExtensions() != null && originalAuthRequest.getExtensions().containsKey("approved_site")) {
Long apId = (Long) originalAuthRequest.getExtensions().get("approved_site"); Long apId = (Long) originalAuthRequest.getExtensions().get("approved_site");
ApprovedSite ap = approvedSiteService.getById(apId); ApprovedSite ap = approvedSiteService.getById(apId);
Set<OAuth2AccessTokenEntity> apTokens = ap.getApprovedAccessTokens(); Set<OAuth2AccessTokenEntity> apTokens = ap.getApprovedAccessTokens();
apTokens.add(token); apTokens.add(token);
ap.setApprovedAccessTokens(apTokens); ap.setApprovedAccessTokens(apTokens);
approvedSiteService.save(ap); approvedSiteService.save(ap);
} }
if (token.getRefreshToken() != null) { if (token.getRefreshToken() != null) {
tokenRepository.saveRefreshToken(token.getRefreshToken()); // make sure we save any changes that might have been enhanced tokenRepository.saveRefreshToken(token.getRefreshToken()); // make sure we save any changes that might have been enhanced
} }
return token; return token;
} }
throw new AuthenticationCredentialsNotFoundException("No authentication credentials found"); throw new AuthenticationCredentialsNotFoundException("No authentication credentials found");
} }
@Override @Override
public OAuth2AccessTokenEntity refreshAccessToken(String refreshTokenValue, TokenRequest authRequest) throws AuthenticationException { public OAuth2AccessTokenEntity refreshAccessToken(String refreshTokenValue, TokenRequest authRequest) throws AuthenticationException {
OAuth2RefreshTokenEntity refreshToken = tokenRepository.getRefreshTokenByValue(refreshTokenValue); OAuth2RefreshTokenEntity refreshToken = tokenRepository.getRefreshTokenByValue(refreshTokenValue);
if (refreshToken == null) { if (refreshToken == null) {
throw new InvalidTokenException("Invalid refresh token: " + refreshTokenValue); throw new InvalidTokenException("Invalid refresh token: " + refreshTokenValue);
} }
ClientDetailsEntity client = refreshToken.getClient(); ClientDetailsEntity client = refreshToken.getClient();
AuthenticationHolderEntity authHolder = refreshToken.getAuthenticationHolder(); AuthenticationHolderEntity authHolder = refreshToken.getAuthenticationHolder();
//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!");
} }
// clear out any access tokens // clear out any access tokens
// TODO: make this a configurable option // TODO: make this a configurable option
tokenRepository.clearAccessTokensForRefreshToken(refreshToken); tokenRepository.clearAccessTokensForRefreshToken(refreshToken);
if (refreshToken.isExpired()) { if (refreshToken.isExpired()) {
tokenRepository.removeRefreshToken(refreshToken); tokenRepository.removeRefreshToken(refreshToken);
throw new InvalidTokenException("Expired refresh token: " + refreshTokenValue); throw new InvalidTokenException("Expired refresh token: " + refreshTokenValue);
} }
// TODO: have the option to recycle the refresh token here, too // TODO: have the option to recycle the refresh token here, too
// for now, we just reuse it as long as it's valid, which is the original intent // for now, we just reuse it as long as it's valid, which is the original intent
OAuth2AccessTokenEntity token = new OAuth2AccessTokenEntity(); OAuth2AccessTokenEntity token = new OAuth2AccessTokenEntity();
// get the stored scopes from the authentication holder's authorization request; these are the scopes associated with the refresh token // get the stored scopes from the authentication holder's authorization request; these are the scopes associated with the refresh token
Set<String> refreshScopes = new HashSet<String>(refreshToken.getAuthenticationHolder().getAuthentication().getOAuth2Request().getScope()); Set<String> refreshScopes = new HashSet<String>(refreshToken.getAuthenticationHolder().getAuthentication().getOAuth2Request().getScope());
Set<String> scope = new HashSet<String>(authRequest.getScope()); Set<String> scope = new HashSet<String>(authRequest.getScope());
if (scope != null && !scope.isEmpty()) { if (scope != null && !scope.isEmpty()) {
// ensure a proper subset of scopes // ensure a proper subset of scopes
if (refreshScopes != null && refreshScopes.containsAll(scope)) { if (refreshScopes != null && refreshScopes.containsAll(scope)) {
// set the scope of the new access token if requested // set the scope of the new access token if requested
@ -225,189 +225,189 @@ public class DefaultOAuth2ProviderTokenService implements OAuth2TokenEntityServi
// otherwise inherit the scope of the refresh token (if it's there -- this can return a null scope set) // otherwise inherit the scope of the refresh token (if it's there -- this can return a null scope set)
token.setScope(refreshScopes); token.setScope(refreshScopes);
} }
token.setClient(client);
if (client.getAccessTokenValiditySeconds() != null) {
Date expiration = new Date(System.currentTimeMillis() + (client.getAccessTokenValiditySeconds() * 1000L));
token.setExpiration(expiration);
}
token.setRefreshToken(refreshToken);
token.setAuthenticationHolder(authHolder);
tokenEnhancer.enhance(token, authHolder.getAuthentication()); token.setClient(client);
tokenRepository.saveAccessToken(token); if (client.getAccessTokenValiditySeconds() != null) {
Date expiration = new Date(System.currentTimeMillis() + (client.getAccessTokenValiditySeconds() * 1000L));
return token; token.setExpiration(expiration);
}
}
token.setRefreshToken(refreshToken);
token.setAuthenticationHolder(authHolder);
tokenEnhancer.enhance(token, authHolder.getAuthentication());
tokenRepository.saveAccessToken(token);
return token;
}
@Override @Override
public OAuth2Authentication loadAuthentication(String accessTokenValue) throws AuthenticationException { public OAuth2Authentication loadAuthentication(String accessTokenValue) throws AuthenticationException {
OAuth2AccessTokenEntity accessToken = tokenRepository.getAccessTokenByValue(accessTokenValue); OAuth2AccessTokenEntity accessToken = tokenRepository.getAccessTokenByValue(accessTokenValue);
if (accessToken == null) { if (accessToken == null) {
throw new InvalidTokenException("Invalid access token: " + accessTokenValue); throw new InvalidTokenException("Invalid access token: " + accessTokenValue);
} }
if (accessToken.isExpired()) { if (accessToken.isExpired()) {
//tokenRepository.removeAccessToken(accessToken); //tokenRepository.removeAccessToken(accessToken);
revokeAccessToken(accessToken); revokeAccessToken(accessToken);
throw new InvalidTokenException("Expired access token: " + accessTokenValue); throw new InvalidTokenException("Expired access token: " + accessTokenValue);
} }
return accessToken.getAuthenticationHolder().getAuthentication(); return accessToken.getAuthenticationHolder().getAuthentication();
} }
/** /**
* Get an access token from its token value. * Get an access token from its token value.
*/ */
@Override @Override
public OAuth2AccessTokenEntity readAccessToken(String accessTokenValue) throws AuthenticationException { public OAuth2AccessTokenEntity readAccessToken(String accessTokenValue) throws AuthenticationException {
OAuth2AccessTokenEntity accessToken = tokenRepository.getAccessTokenByValue(accessTokenValue); OAuth2AccessTokenEntity accessToken = tokenRepository.getAccessTokenByValue(accessTokenValue);
if (accessToken == null) { if (accessToken == null) {
throw new InvalidTokenException("Access token for value " + accessTokenValue + " was not found"); throw new InvalidTokenException("Access token for value " + accessTokenValue + " was not found");
} }
else { else {
return accessToken; return accessToken;
} }
} }
/** /**
* Get an access token by its authentication object. * Get an access token by its authentication object.
*/ */
@Override @Override
public OAuth2AccessTokenEntity getAccessToken(OAuth2Authentication authentication) { public OAuth2AccessTokenEntity getAccessToken(OAuth2Authentication authentication) {
OAuth2AccessTokenEntity accessToken = tokenRepository.getByAuthentication(authentication); OAuth2AccessTokenEntity accessToken = tokenRepository.getByAuthentication(authentication);
return accessToken; return accessToken;
} }
/** /**
* Get a refresh token by its token value. * Get a refresh token by its token value.
*/ */
@Override @Override
public OAuth2RefreshTokenEntity getRefreshToken(String refreshTokenValue) throws AuthenticationException { public OAuth2RefreshTokenEntity getRefreshToken(String refreshTokenValue) throws AuthenticationException {
OAuth2RefreshTokenEntity refreshToken = tokenRepository.getRefreshTokenByValue(refreshTokenValue); OAuth2RefreshTokenEntity refreshToken = tokenRepository.getRefreshTokenByValue(refreshTokenValue);
if (refreshToken == null) { if (refreshToken == null) {
throw new InvalidTokenException("Refresh token for value " + refreshTokenValue + " was not found"); throw new InvalidTokenException("Refresh token for value " + refreshTokenValue + " was not found");
} }
else { else {
return refreshToken; return refreshToken;
} }
} }
/** /**
* Revoke a refresh token and all access tokens issued to it. * Revoke a refresh token and all access tokens issued to it.
*/ */
@Override @Override
public void revokeRefreshToken(OAuth2RefreshTokenEntity refreshToken) { public void revokeRefreshToken(OAuth2RefreshTokenEntity refreshToken) {
tokenRepository.clearAccessTokensForRefreshToken(refreshToken); tokenRepository.clearAccessTokensForRefreshToken(refreshToken);
tokenRepository.removeRefreshToken(refreshToken); tokenRepository.removeRefreshToken(refreshToken);
} }
/** /**
* Revoke an access token. * Revoke an access token.
*/ */
@Override @Override
public void revokeAccessToken(OAuth2AccessTokenEntity accessToken) { public void revokeAccessToken(OAuth2AccessTokenEntity accessToken) {
tokenRepository.removeAccessToken(accessToken); tokenRepository.removeAccessToken(accessToken);
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.mitre.oauth2.service.OAuth2TokenEntityService#getAccessTokensForClient(org.mitre.oauth2.model.ClientDetailsEntity) * @see org.mitre.oauth2.service.OAuth2TokenEntityService#getAccessTokensForClient(org.mitre.oauth2.model.ClientDetailsEntity)
*/ */
@Override @Override
public List<OAuth2AccessTokenEntity> getAccessTokensForClient(ClientDetailsEntity client) { public List<OAuth2AccessTokenEntity> getAccessTokensForClient(ClientDetailsEntity client) {
return tokenRepository.getAccessTokensForClient(client); return tokenRepository.getAccessTokensForClient(client);
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.mitre.oauth2.service.OAuth2TokenEntityService#getRefreshTokensForClient(org.mitre.oauth2.model.ClientDetailsEntity) * @see org.mitre.oauth2.service.OAuth2TokenEntityService#getRefreshTokensForClient(org.mitre.oauth2.model.ClientDetailsEntity)
*/ */
@Override @Override
public List<OAuth2RefreshTokenEntity> getRefreshTokensForClient(ClientDetailsEntity client) { public List<OAuth2RefreshTokenEntity> getRefreshTokensForClient(ClientDetailsEntity client) {
return tokenRepository.getRefreshTokensForClient(client); return tokenRepository.getRefreshTokensForClient(client);
} }
@Override @Override
@Scheduled(fixedRate = 5 * 60 * 1000) // schedule this task every five minutes @Scheduled(fixedRate = 5 * 60 * 1000) // schedule this task every five minutes
public void clearExpiredTokens() { public void clearExpiredTokens() {
logger.info("Cleaning out all expired tokens"); logger.info("Cleaning out all expired tokens");
List<OAuth2AccessTokenEntity> accessTokens = tokenRepository.getExpiredAccessTokens(); List<OAuth2AccessTokenEntity> accessTokens = tokenRepository.getExpiredAccessTokens();
logger.info("Found " + accessTokens.size() + " expired access tokens"); logger.info("Found " + accessTokens.size() + " expired access tokens");
for (OAuth2AccessTokenEntity oAuth2AccessTokenEntity : accessTokens) { for (OAuth2AccessTokenEntity oAuth2AccessTokenEntity : accessTokens) {
revokeAccessToken(oAuth2AccessTokenEntity); revokeAccessToken(oAuth2AccessTokenEntity);
} }
List<OAuth2RefreshTokenEntity> refreshTokens = tokenRepository.getExpiredRefreshTokens(); List<OAuth2RefreshTokenEntity> refreshTokens = tokenRepository.getExpiredRefreshTokens();
logger.info("Found " + refreshTokens.size() + " expired refresh tokens"); logger.info("Found " + refreshTokens.size() + " expired refresh tokens");
for (OAuth2RefreshTokenEntity oAuth2RefreshTokenEntity : refreshTokens) { for (OAuth2RefreshTokenEntity oAuth2RefreshTokenEntity : refreshTokens) {
revokeRefreshToken(oAuth2RefreshTokenEntity); revokeRefreshToken(oAuth2RefreshTokenEntity);
} }
} }
/** /**
* Get a builder object for this class (for tests) * Get a builder object for this class (for tests)
* @return * @return
*/ */
public static DefaultOAuth2ProviderTokenServicesBuilder makeBuilder() { public static DefaultOAuth2ProviderTokenServicesBuilder makeBuilder() {
return new DefaultOAuth2ProviderTokenServicesBuilder(); return new DefaultOAuth2ProviderTokenServicesBuilder();
} }
/** /**
* Builder class for test harnesses. * Builder class for test harnesses.
*/ */
public static class DefaultOAuth2ProviderTokenServicesBuilder { public static class DefaultOAuth2ProviderTokenServicesBuilder {
private DefaultOAuth2ProviderTokenService instance; private DefaultOAuth2ProviderTokenService instance;
private DefaultOAuth2ProviderTokenServicesBuilder() { private DefaultOAuth2ProviderTokenServicesBuilder() {
instance = new DefaultOAuth2ProviderTokenService(); instance = new DefaultOAuth2ProviderTokenService();
} }
public DefaultOAuth2ProviderTokenServicesBuilder setTokenRepository(OAuth2TokenRepository tokenRepository) { public DefaultOAuth2ProviderTokenServicesBuilder setTokenRepository(OAuth2TokenRepository tokenRepository) {
instance.tokenRepository = tokenRepository; instance.tokenRepository = tokenRepository;
return this; return this;
} }
public DefaultOAuth2ProviderTokenServicesBuilder setClientDetailsService(ClientDetailsEntityService clientDetailsService) { public DefaultOAuth2ProviderTokenServicesBuilder setClientDetailsService(ClientDetailsEntityService clientDetailsService) {
instance.clientDetailsService = clientDetailsService; instance.clientDetailsService = clientDetailsService;
return this; return this;
} }
public DefaultOAuth2ProviderTokenServicesBuilder setTokenEnhancer(TokenEnhancer tokenEnhancer) { public DefaultOAuth2ProviderTokenServicesBuilder setTokenEnhancer(TokenEnhancer tokenEnhancer) {
instance.tokenEnhancer = tokenEnhancer; instance.tokenEnhancer = tokenEnhancer;
return this; return this;
} }
public OAuth2TokenEntityService finish() { public OAuth2TokenEntityService finish() {
return instance; return instance;
} }
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.mitre.oauth2.service.OAuth2TokenEntityService#saveAccessToken(org.mitre.oauth2.model.OAuth2AccessTokenEntity) * @see org.mitre.oauth2.service.OAuth2TokenEntityService#saveAccessToken(org.mitre.oauth2.model.OAuth2AccessTokenEntity)
*/ */
@Override @Override
public OAuth2AccessTokenEntity saveAccessToken(OAuth2AccessTokenEntity accessToken) { public OAuth2AccessTokenEntity saveAccessToken(OAuth2AccessTokenEntity accessToken) {
return tokenRepository.saveAccessToken(accessToken); return tokenRepository.saveAccessToken(accessToken);
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.mitre.oauth2.service.OAuth2TokenEntityService#saveRefreshToken(org.mitre.oauth2.model.OAuth2RefreshTokenEntity) * @see org.mitre.oauth2.service.OAuth2TokenEntityService#saveRefreshToken(org.mitre.oauth2.model.OAuth2RefreshTokenEntity)
*/ */
@Override @Override
public OAuth2RefreshTokenEntity saveRefreshToken(OAuth2RefreshTokenEntity refreshToken) { public OAuth2RefreshTokenEntity saveRefreshToken(OAuth2RefreshTokenEntity refreshToken) {
return tokenRepository.saveRefreshToken(refreshToken); return tokenRepository.saveRefreshToken(refreshToken);
} }
/** /**
* @return the tokenEnhancer * @return the tokenEnhancer
@ -424,16 +424,16 @@ public class DefaultOAuth2ProviderTokenService implements OAuth2TokenEntityServi
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.mitre.oauth2.service.OAuth2TokenEntityService#getAccessTokenForIdToken(org.mitre.oauth2.model.OAuth2AccessTokenEntity) * @see org.mitre.oauth2.service.OAuth2TokenEntityService#getAccessTokenForIdToken(org.mitre.oauth2.model.OAuth2AccessTokenEntity)
*/ */
@Override @Override
public OAuth2AccessTokenEntity getAccessTokenForIdToken(OAuth2AccessTokenEntity idToken) { public OAuth2AccessTokenEntity getAccessTokenForIdToken(OAuth2AccessTokenEntity idToken) {
return tokenRepository.getAccessTokenForIdToken(idToken); return tokenRepository.getAccessTokenForIdToken(idToken);
} }
@Override @Override
public OAuth2AccessTokenEntity getAccessTokenById(Long id) { public OAuth2AccessTokenEntity getAccessTokenById(Long id) {
return tokenRepository.getAccessTokenById(id); return tokenRepository.getAccessTokenById(id);
} }
} }

View File

@ -29,132 +29,132 @@ public class DefaultSystemScopeService implements SystemScopeService {
@Autowired @Autowired
private SystemScopeRepository repository; private SystemScopeRepository repository;
private Predicate<SystemScope> isDefault = new Predicate<SystemScope>() { private Predicate<SystemScope> isDefault = new Predicate<SystemScope>() {
@Override @Override
public boolean apply(@Nullable SystemScope input) { public boolean apply(@Nullable SystemScope input) {
return (input != null && input.isDefaultScope()); return (input != null && input.isDefaultScope());
} }
}; };
private Predicate<SystemScope> isDynReg = new Predicate<SystemScope>() { private Predicate<SystemScope> isDynReg = new Predicate<SystemScope>() {
@Override @Override
public boolean apply(@Nullable SystemScope input) { public boolean apply(@Nullable SystemScope input) {
return (input != null && input.isAllowDynReg()); return (input != null && input.isAllowDynReg());
} }
}; };
private Function<String, SystemScope> stringToSystemScope = new Function<String, SystemScope>() { private Function<String, SystemScope> stringToSystemScope = new Function<String, SystemScope>() {
@Override @Override
public SystemScope apply(@Nullable String input) { public SystemScope apply(@Nullable String input) {
if (input == null) { if (input == null) {
return null; return null;
} else { } else {
SystemScope s = getByValue(input); SystemScope s = getByValue(input);
if (s != null) { if (s != null) {
// get the real scope if it's available // get the real scope if it's available
return s; return s;
} else { } else {
// make a fake one otherwise // make a fake one otherwise
return new SystemScope(input); return new SystemScope(input);
} }
} }
} }
}; };
private Function<SystemScope, String> systemScopeToString = new Function<SystemScope, String>() { private Function<SystemScope, String> systemScopeToString = new Function<SystemScope, String>() {
@Override @Override
public String apply(@Nullable SystemScope input) { public String apply(@Nullable SystemScope input) {
if (input == null) { if (input == null) {
return null; return null;
} else { } else {
return input.getValue(); return input.getValue();
} }
} }
}; };
/* (non-Javadoc) /* (non-Javadoc)
* @see org.mitre.oauth2.service.SystemScopeService#getAll() * @see org.mitre.oauth2.service.SystemScopeService#getAll()
*/ */
@Override @Override
public Set<SystemScope> getAll() { public Set<SystemScope> getAll() {
return repository.getAll(); return repository.getAll();
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.mitre.oauth2.service.SystemScopeService#getDefaults() * @see org.mitre.oauth2.service.SystemScopeService#getDefaults()
*/ */
@Override @Override
public Set<SystemScope> getDefaults() { public Set<SystemScope> getDefaults() {
return Sets.filter(getAll(), isDefault); return Sets.filter(getAll(), isDefault);
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.mitre.oauth2.service.SystemScopeService#getDynReg() * @see org.mitre.oauth2.service.SystemScopeService#getDynReg()
*/ */
@Override @Override
public Set<SystemScope> getDynReg() { public Set<SystemScope> getDynReg() {
return Sets.filter(getAll(), isDynReg); return Sets.filter(getAll(), isDynReg);
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.mitre.oauth2.service.SystemScopeService#getById(java.lang.Long) * @see org.mitre.oauth2.service.SystemScopeService#getById(java.lang.Long)
*/ */
@Override @Override
public SystemScope getById(Long id) { public SystemScope getById(Long id) {
return repository.getById(id); return repository.getById(id);
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.mitre.oauth2.service.SystemScopeService#getByValue(java.lang.String) * @see org.mitre.oauth2.service.SystemScopeService#getByValue(java.lang.String)
*/ */
@Override @Override
public SystemScope getByValue(String value) { public SystemScope getByValue(String value) {
return repository.getByValue(value); return repository.getByValue(value);
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.mitre.oauth2.service.SystemScopeService#remove(org.mitre.oauth2.model.SystemScope) * @see org.mitre.oauth2.service.SystemScopeService#remove(org.mitre.oauth2.model.SystemScope)
*/ */
@Override @Override
public void remove(SystemScope scope) { public void remove(SystemScope scope) {
repository.remove(scope); repository.remove(scope);
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.mitre.oauth2.service.SystemScopeService#save(org.mitre.oauth2.model.SystemScope) * @see org.mitre.oauth2.service.SystemScopeService#save(org.mitre.oauth2.model.SystemScope)
*/ */
@Override @Override
public SystemScope save(SystemScope scope) { public SystemScope save(SystemScope scope) {
return repository.save(scope); return repository.save(scope);
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.mitre.oauth2.service.SystemScopeService#fromStrings(java.util.Set) * @see org.mitre.oauth2.service.SystemScopeService#fromStrings(java.util.Set)
*/ */
@Override @Override
public Set<SystemScope> fromStrings(Set<String> scope) { public Set<SystemScope> fromStrings(Set<String> scope) {
if (scope == null) { if (scope == null) {
return null; return null;
} else { } else {
return new LinkedHashSet<SystemScope>(Collections2.filter(Collections2.transform(scope, stringToSystemScope), Predicates.notNull())); return new LinkedHashSet<SystemScope>(Collections2.filter(Collections2.transform(scope, stringToSystemScope), Predicates.notNull()));
} }
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.mitre.oauth2.service.SystemScopeService#toStrings(java.util.Set) * @see org.mitre.oauth2.service.SystemScopeService#toStrings(java.util.Set)
*/ */
@Override @Override
public Set<String> toStrings(Set<SystemScope> scope) { public Set<String> toStrings(Set<SystemScope> scope) {
if (scope == null) { if (scope == null) {
return null; return null;
} else { } else {
return new LinkedHashSet<String>(Collections2.filter(Collections2.transform(scope, systemScopeToString), Predicates.notNull())); return new LinkedHashSet<String>(Collections2.filter(Collections2.transform(scope, systemScopeToString), Predicates.notNull()));
} }
} }
} }

View File

@ -30,12 +30,12 @@ import com.google.common.collect.Sets;
public class ChainedTokenGranter extends AbstractTokenGranter { public class ChainedTokenGranter extends AbstractTokenGranter {
private static final String grantType = "urn:ietf:params:oauth:grant_type:redelegate"; private static final String grantType = "urn:ietf:params:oauth:grant_type:redelegate";
// keep down-cast versions so we can get to the right queries // keep down-cast versions so we can get to the right queries
private OAuth2TokenEntityService tokenServices; private OAuth2TokenEntityService tokenServices;
/** /**
* @param tokenServices * @param tokenServices
* @param clientDetailsService * @param clientDetailsService
@ -46,52 +46,52 @@ public class ChainedTokenGranter extends AbstractTokenGranter {
super(tokenServices, clientDetailsService, requestFactory, grantType); super(tokenServices, clientDetailsService, requestFactory, grantType);
this.tokenServices = tokenServices; this.tokenServices = tokenServices;
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.springframework.security.oauth2.provider.token.AbstractTokenGranter#getOAuth2Authentication(org.springframework.security.oauth2.provider.AuthorizationRequest) * @see org.springframework.security.oauth2.provider.token.AbstractTokenGranter#getOAuth2Authentication(org.springframework.security.oauth2.provider.AuthorizationRequest)
*/ */
@Override @Override
protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) throws AuthenticationException, InvalidTokenException { protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) throws AuthenticationException, InvalidTokenException {
// read and load up the existing token // read and load up the existing token
String incomingTokenValue = tokenRequest.getRequestParameters().get("token"); String incomingTokenValue = tokenRequest.getRequestParameters().get("token");
OAuth2AccessTokenEntity incomingToken = tokenServices.readAccessToken(incomingTokenValue); OAuth2AccessTokenEntity incomingToken = tokenServices.readAccessToken(incomingTokenValue);
// check for scoping in the request, can't up-scope with a chained request
Set<String> approvedScopes = incomingToken.getScope();
Set<String> requestedScopes = tokenRequest.getScope();
if (requestedScopes == null) {
requestedScopes = new HashSet<String>();
}
// do a check on the requested scopes -- if they exactly match the client scopes, they were probably shadowed by the token granter
if (client.getScope().equals(requestedScopes)) {
requestedScopes = new HashSet<String>();
}
// if our scopes are a valid subset of what's allowed, we can continue
if (approvedScopes.containsAll(requestedScopes)) {
if (requestedScopes.isEmpty()) { // check for scoping in the request, can't up-scope with a chained request
// if there are no scopes, inherit the original scopes from the token Set<String> approvedScopes = incomingToken.getScope();
tokenRequest.setScope(approvedScopes); Set<String> requestedScopes = tokenRequest.getScope();
} else {
// if scopes were asked for, give only the subset of scopes requested if (requestedScopes == null) {
// this allows safe downscoping requestedScopes = new HashSet<String>();
tokenRequest.setScope(Sets.intersection(requestedScopes, approvedScopes)); }
}
// do a check on the requested scopes -- if they exactly match the client scopes, they were probably shadowed by the token granter
// NOTE: don't revoke the existing access token if (client.getScope().equals(requestedScopes)) {
requestedScopes = new HashSet<String>();
}
// if our scopes are a valid subset of what's allowed, we can continue
if (approvedScopes.containsAll(requestedScopes)) {
if (requestedScopes.isEmpty()) {
// if there are no scopes, inherit the original scopes from the token
tokenRequest.setScope(approvedScopes);
} else {
// if scopes were asked for, give only the subset of scopes requested
// this allows safe downscoping
tokenRequest.setScope(Sets.intersection(requestedScopes, approvedScopes));
}
// NOTE: don't revoke the existing access token
// create a new access token
OAuth2Authentication authentication = new OAuth2Authentication(getRequestFactory().createOAuth2Request(client, tokenRequest), incomingToken.getAuthenticationHolder().getAuthentication().getUserAuthentication());
return authentication;
} else {
throw new InvalidScopeException("Invalid scope requested in chained request", approvedScopes);
}
}
// create a new access token
OAuth2Authentication authentication = new OAuth2Authentication(getRequestFactory().createOAuth2Request(client, tokenRequest), incomingToken.getAuthenticationHolder().getAuthentication().getUserAuthentication());
return authentication;
} else {
throw new InvalidScopeException("Invalid scope requested in chained request", approvedScopes);
}
}
} }

View File

@ -40,124 +40,124 @@ public class JwtAssertionTokenGranter extends AbstractTokenGranter {
// keep down-cast versions so we can get to the right queries // keep down-cast versions so we can get to the right queries
private OAuth2TokenEntityService tokenServices; private OAuth2TokenEntityService tokenServices;
@Autowired @Autowired
private JwtSigningAndValidationService jwtService; private JwtSigningAndValidationService jwtService;
@Autowired @Autowired
private ConfigurationPropertiesBean config; private ConfigurationPropertiesBean config;
@Autowired @Autowired
public JwtAssertionTokenGranter(OAuth2TokenEntityService tokenServices, ClientDetailsEntityService clientDetailsService, OAuth2RequestFactory requestFactory) { public JwtAssertionTokenGranter(OAuth2TokenEntityService tokenServices, ClientDetailsEntityService clientDetailsService, OAuth2RequestFactory requestFactory) {
super(tokenServices, clientDetailsService, requestFactory, grantType); super(tokenServices, clientDetailsService, requestFactory, grantType);
this.tokenServices = tokenServices; this.tokenServices = tokenServices;
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.springframework.security.oauth2.provider.token.AbstractTokenGranter#getOAuth2Authentication(org.springframework.security.oauth2.provider.AuthorizationRequest) * @see org.springframework.security.oauth2.provider.token.AbstractTokenGranter#getOAuth2Authentication(org.springframework.security.oauth2.provider.AuthorizationRequest)
*/ */
@Override @Override
protected OAuth2AccessToken getAccessToken(ClientDetails client, TokenRequest tokenRequest) throws AuthenticationException, InvalidTokenException { protected OAuth2AccessToken getAccessToken(ClientDetails client, TokenRequest tokenRequest) throws AuthenticationException, InvalidTokenException {
// read and load up the existing token // read and load up the existing token
String incomingTokenValue = tokenRequest.getRequestParameters().get("assertion"); String incomingTokenValue = tokenRequest.getRequestParameters().get("assertion");
OAuth2AccessTokenEntity incomingToken = tokenServices.readAccessToken(incomingTokenValue); OAuth2AccessTokenEntity incomingToken = tokenServices.readAccessToken(incomingTokenValue);
if (incomingToken.getScope().contains(OAuth2AccessTokenEntity.ID_TOKEN_SCOPE)) {
if (!client.getClientId().equals(tokenRequest.getClientId())) {
throw new InvalidClientException("Not the right client for this token");
}
// it's an ID token, process it accordingly if (incomingToken.getScope().contains(OAuth2AccessTokenEntity.ID_TOKEN_SCOPE)) {
try { if (!client.getClientId().equals(tokenRequest.getClientId())) {
throw new InvalidClientException("Not the right client for this token");
// TODO: make this use a more specific idtoken class }
JWT idToken = JWTParser.parse(incomingTokenValue);
// it's an ID token, process it accordingly
OAuth2AccessTokenEntity accessToken = tokenServices.getAccessTokenForIdToken(incomingToken);
try {
if (accessToken != null) {
// TODO: make this use a more specific idtoken class
//OAuth2AccessTokenEntity newIdToken = tokenServices.get JWT idToken = JWTParser.parse(incomingTokenValue);
OAuth2AccessTokenEntity newIdTokenEntity = new OAuth2AccessTokenEntity(); OAuth2AccessTokenEntity accessToken = tokenServices.getAccessTokenForIdToken(incomingToken);
// copy over all existing claims if (accessToken != null) {
JWTClaimsSet claims = new JWTClaimsSet(idToken.getJWTClaimsSet());
//OAuth2AccessTokenEntity newIdToken = tokenServices.get
if (client instanceof ClientDetailsEntity) {
OAuth2AccessTokenEntity newIdTokenEntity = new OAuth2AccessTokenEntity();
ClientDetailsEntity clientEntity = (ClientDetailsEntity) client;
// copy over all existing claims
// update expiration and issued-at claims JWTClaimsSet claims = new JWTClaimsSet(idToken.getJWTClaimsSet());
if (client instanceof ClientDetailsEntity) {
ClientDetailsEntity clientEntity = (ClientDetailsEntity) client;
// update expiration and issued-at claims
if (clientEntity.getIdTokenValiditySeconds() != null) { if (clientEntity.getIdTokenValiditySeconds() != null) {
Date expiration = new Date(System.currentTimeMillis() + (clientEntity.getIdTokenValiditySeconds() * 1000L)); Date expiration = new Date(System.currentTimeMillis() + (clientEntity.getIdTokenValiditySeconds() * 1000L));
claims.setExpirationTime(expiration); claims.setExpirationTime(expiration);
newIdTokenEntity.setExpiration(expiration); newIdTokenEntity.setExpiration(expiration);
} }
} else { } else {
//TODO: What should happen in this case? Is this possible? //TODO: What should happen in this case? Is this possible?
} }
claims.setIssueTime(new Date()); claims.setIssueTime(new Date());
SignedJWT newIdToken = new SignedJWT((JWSHeader) idToken.getHeader(), claims); SignedJWT newIdToken = new SignedJWT((JWSHeader) idToken.getHeader(), claims);
jwtService.signJwt(newIdToken); jwtService.signJwt(newIdToken);
newIdTokenEntity.setJwt(newIdToken); newIdTokenEntity.setJwt(newIdToken);
newIdTokenEntity.setAuthenticationHolder(incomingToken.getAuthenticationHolder()); newIdTokenEntity.setAuthenticationHolder(incomingToken.getAuthenticationHolder());
newIdTokenEntity.setScope(incomingToken.getScope()); newIdTokenEntity.setScope(incomingToken.getScope());
newIdTokenEntity.setClient(incomingToken.getClient()); newIdTokenEntity.setClient(incomingToken.getClient());
newIdTokenEntity = tokenServices.saveAccessToken(newIdTokenEntity); newIdTokenEntity = tokenServices.saveAccessToken(newIdTokenEntity);
// attach the ID token to the access token entity // attach the ID token to the access token entity
accessToken.setIdToken(newIdTokenEntity); accessToken.setIdToken(newIdTokenEntity);
accessToken = tokenServices.saveAccessToken(accessToken); accessToken = tokenServices.saveAccessToken(accessToken);
// delete the old ID token // delete the old ID token
tokenServices.revokeAccessToken(incomingToken); tokenServices.revokeAccessToken(incomingToken);
return newIdTokenEntity;
}
} catch (ParseException e) {
logger.warn("Couldn't parse id token", e);
}
}
// if we got down here, we didn't actually create any tokens, so return null
return null;
/* return newIdTokenEntity;
* Otherwise, process it like an access token assertion ... which we don't support yet so this is all commented out
* / }
} catch (ParseException e) {
logger.warn("Couldn't parse id token", e);
}
}
// if we got down here, we didn't actually create any tokens, so return null
return null;
/*
* Otherwise, process it like an access token assertion ... which we don't support yet so this is all commented out
* /
if (jwtService.validateSignature(incomingTokenValue)) { if (jwtService.validateSignature(incomingTokenValue)) {
Jwt jwt = Jwt.parse(incomingTokenValue); Jwt jwt = Jwt.parse(incomingTokenValue);
if (oldToken.getScope().contains("id-token")) { if (oldToken.getScope().contains("id-token")) {
// TODO: things // TODO: things
} }
// TODO: should any of these throw an exception instead of returning null? // TODO: should any of these throw an exception instead of returning null?
JwtClaims claims = jwt.getClaims(); JwtClaims claims = jwt.getClaims();
if (!config.getIssuer().equals(claims.getIssuer())) { if (!config.getIssuer().equals(claims.getIssuer())) {
// issuer isn't us // issuer isn't us
return null; return null;
} }
if (!authorizationRequest.getClientId().equals(claims.getAudience())) { if (!authorizationRequest.getClientId().equals(claims.getAudience())) {
// audience isn't the client // audience isn't the client
return null; return null;
} }
Date now = new Date(); Date now = new Date();
if (!now.after(claims.getExpiration())) { if (!now.after(claims.getExpiration())) {
// token is expired // token is expired
@ -171,14 +171,14 @@ public class JwtAssertionTokenGranter extends AbstractTokenGranter {
// we might need new calls on the token services layer to handle this, and we might // we might need new calls on the token services layer to handle this, and we might
// need to handle id tokens separately. // need to handle id tokens separately.
return new OAuth2Authentication(authorizationRequest, null); return new OAuth2Authentication(authorizationRequest, null);
} else { } else {
return null; // throw error?? return null; // throw error??
} }
*/ */
} }
} }

View File

@ -43,11 +43,11 @@ import com.google.gson.JsonSerializer;
@Component("tokenIntrospection") @Component("tokenIntrospection")
public class TokenIntrospectionView extends AbstractView { public class TokenIntrospectionView extends AbstractView {
private static Logger logger = LoggerFactory.getLogger(TokenIntrospectionView.class); private static Logger logger = LoggerFactory.getLogger(TokenIntrospectionView.class);
@Override @Override
protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) { protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) {
Gson gson = new GsonBuilder().setExclusionStrategies(new ExclusionStrategy() { Gson gson = new GsonBuilder().setExclusionStrategies(new ExclusionStrategy() {
@ -68,7 +68,7 @@ public class TokenIntrospectionView extends AbstractView {
// serialize other classes without filter (lists and sets and things) // serialize other classes without filter (lists and sets and things)
return false; return false;
} }
*/ */
return false; return false;
} }
@ -84,28 +84,29 @@ public class TokenIntrospectionView extends AbstractView {
}) })
.registerTypeAdapter(OAuth2AccessTokenEntity.class, new JsonSerializer<OAuth2AccessTokenEntity>() { .registerTypeAdapter(OAuth2AccessTokenEntity.class, new JsonSerializer<OAuth2AccessTokenEntity>() {
public JsonElement serialize(OAuth2AccessTokenEntity src, Type typeOfSrc, JsonSerializationContext context) { @Override
JsonObject token = new JsonObject(); public JsonElement serialize(OAuth2AccessTokenEntity src, Type typeOfSrc, JsonSerializationContext context) {
JsonObject token = new JsonObject();
token.addProperty("valid", true);
token.addProperty("valid", true);
JsonArray scopes = new JsonArray();
for (String scope : src.getScope()) { JsonArray scopes = new JsonArray();
scopes.add(new JsonPrimitive(scope)); for (String scope : src.getScope()) {
} scopes.add(new JsonPrimitive(scope));
token.add("scope", scopes); }
token.add("scope", scopes);
token.add("expires_at", context.serialize(src.getExpiration()));
token.add("expires_at", context.serialize(src.getExpiration()));
//token.addProperty("audience", src.getAuthenticationHolder().getAuthentication().getAuthorizationRequest().getClientId());
//token.addProperty("audience", src.getAuthenticationHolder().getAuthentication().getAuthorizationRequest().getClientId());
token.addProperty("subject", src.getAuthenticationHolder().getAuthentication().getName());
token.addProperty("subject", src.getAuthenticationHolder().getAuthentication().getName());
token.addProperty("client_id", src.getAuthenticationHolder().getAuthentication().getOAuth2Request().getClientId());
token.addProperty("client_id", src.getAuthenticationHolder().getAuthentication().getOAuth2Request().getClientId());
return token;
} return token;
}
}) })
.setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ") .setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")
.create(); .create();
@ -113,9 +114,9 @@ public class TokenIntrospectionView extends AbstractView {
response.setContentType("application/json"); response.setContentType("application/json");
Writer out; Writer out;
try { try {
out = response.getWriter(); out = response.getWriter();
Object obj = model.get("entity"); Object obj = model.get("entity");
if (obj == null) { if (obj == null) {
@ -123,13 +124,13 @@ public class TokenIntrospectionView extends AbstractView {
} }
gson.toJson(obj, out); gson.toJson(obj, out);
} catch (IOException e) { } catch (IOException e) {
logger.error("IOException occurred in TokenIntrospectionView.java: ", e); logger.error("IOException occurred in TokenIntrospectionView.java: ", e);
} }
} }
} }

View File

@ -44,48 +44,48 @@ public class IntrospectionEndpoint {
@Autowired @Autowired
private OAuth2TokenEntityService tokenServices; private OAuth2TokenEntityService tokenServices;
@Autowired @Autowired
private ClientDetailsEntityService clientService; private ClientDetailsEntityService clientService;
private static Logger logger = LoggerFactory.getLogger(IntrospectionEndpoint.class); private static Logger logger = LoggerFactory.getLogger(IntrospectionEndpoint.class);
public IntrospectionEndpoint() { public IntrospectionEndpoint() {
} }
public IntrospectionEndpoint(OAuth2TokenEntityService tokenServices) { public IntrospectionEndpoint(OAuth2TokenEntityService tokenServices) {
this.tokenServices = tokenServices; this.tokenServices = tokenServices;
} }
@ExceptionHandler(InvalidTokenException.class) @ExceptionHandler(InvalidTokenException.class)
public ModelAndView tokenNotFound(InvalidTokenException ex) { public ModelAndView tokenNotFound(InvalidTokenException ex) {
Map<String,Boolean> e = ImmutableMap.of("valid", Boolean.FALSE); Map<String,Boolean> e = ImmutableMap.of("valid", Boolean.FALSE);
Map<String, Object> model = new HashMap<String, Object>(); Map<String, Object> model = new HashMap<String, Object>();
model.put("entity", e); model.put("entity", e);
logger.error("InvalidTokenException: ", ex); logger.error("InvalidTokenException: ", ex);
model.put("code", HttpStatus.BAD_REQUEST); model.put("code", HttpStatus.BAD_REQUEST);
return new ModelAndView("jsonEntityView", model); return new ModelAndView("jsonEntityView", model);
} }
@PreAuthorize("hasRole('ROLE_CLIENT')") @PreAuthorize("hasRole('ROLE_CLIENT')")
@RequestMapping("/introspect") @RequestMapping("/introspect")
public ModelAndView verify(@RequestParam("token") String tokenValue, Principal p, ModelAndView modelAndView) { public ModelAndView verify(@RequestParam("token") String tokenValue, Principal p, ModelAndView modelAndView) {
/* /*
if (p != null && p instanceof OAuth2Authentication) { if (p != null && p instanceof OAuth2Authentication) {
OAuth2Authentication auth = (OAuth2Authentication)p; OAuth2Authentication auth = (OAuth2Authentication)p;
if (auth.getDetails() != null && auth.getDetails() instanceof OAuth2AuthenticationDetails) { if (auth.getDetails() != null && auth.getDetails() instanceof OAuth2AuthenticationDetails) {
OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails)auth.getDetails(); OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails)auth.getDetails();
String tokenValue = details.getTokenValue(); String tokenValue = details.getTokenValue();
OAuth2AccessTokenEntity token = tokenServices.readAccessToken(tokenValue); OAuth2AccessTokenEntity token = tokenServices.readAccessToken(tokenValue);
if (token != null) { if (token != null) {
// if it's a valid token, we'll print out the scope and expiration // if it's a valid token, we'll print out the scope and expiration
modelAndView.setViewName("tokenIntrospection"); modelAndView.setViewName("tokenIntrospection");
@ -93,36 +93,36 @@ public class IntrospectionEndpoint {
} }
} }
}*/ }*/
if (Strings.isNullOrEmpty(tokenValue)) { if (Strings.isNullOrEmpty(tokenValue)) {
logger.error("Verify failed; token value is null"); logger.error("Verify failed; token value is null");
modelAndView.addObject("code", HttpStatus.BAD_REQUEST); modelAndView.addObject("code", HttpStatus.BAD_REQUEST);
modelAndView.setViewName("httpCodeView"); modelAndView.setViewName("httpCodeView");
return modelAndView; return modelAndView;
} }
OAuth2AccessTokenEntity token = null; OAuth2AccessTokenEntity token = null;
try { try {
token = tokenServices.readAccessToken(tokenValue); token = tokenServices.readAccessToken(tokenValue);
} catch (AuthenticationException e) { } catch (AuthenticationException e) {
logger.error("Verify failed; AuthenticationException: ", e); logger.error("Verify failed; AuthenticationException: ", e);
modelAndView.addObject("code", HttpStatus.FORBIDDEN); modelAndView.addObject("code", HttpStatus.FORBIDDEN);
modelAndView.setViewName("httpCodeView"); modelAndView.setViewName("httpCodeView");
return modelAndView; return modelAndView;
} }
ClientDetailsEntity tokenClient = token.getClient(); ClientDetailsEntity tokenClient = token.getClient();
// 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 (tokenClient != null && authClient != null) { if (tokenClient != null && authClient != null) {
if (authClient.isAllowIntrospection()) { if (authClient.isAllowIntrospection()) {
// 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 // 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
if (authClient.equals(tokenClient) || authClient.getScope().containsAll(token.getScope())) { if (authClient.equals(tokenClient) || authClient.getScope().containsAll(token.getScope())) {
// 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
modelAndView.setViewName("tokenIntrospection"); modelAndView.setViewName("tokenIntrospection");
modelAndView.addObject("entity", token); modelAndView.addObject("entity", token);
@ -146,7 +146,7 @@ public class IntrospectionEndpoint {
modelAndView.setViewName("httpCodeView"); modelAndView.setViewName("httpCodeView");
return modelAndView; return modelAndView;
} }
} }
} }

View File

@ -51,20 +51,20 @@ public class OAuthConfirmationController {
@Autowired @Autowired
private ClientDetailsEntityService clientService; private ClientDetailsEntityService clientService;
@Autowired @Autowired
private SystemScopeService scopeService; private SystemScopeService scopeService;
private static Logger logger = LoggerFactory.getLogger(OAuthConfirmationController.class); private static Logger logger = LoggerFactory.getLogger(OAuthConfirmationController.class);
public OAuthConfirmationController() { public OAuthConfirmationController() {
} }
public OAuthConfirmationController(ClientDetailsEntityService clientService) { public OAuthConfirmationController(ClientDetailsEntityService clientService) {
this.clientService = clientService; this.clientService = clientService;
} }
@PreAuthorize("hasRole('ROLE_USER')") @PreAuthorize("hasRole('ROLE_USER')")
@RequestMapping("/oauth/confirm_access") @RequestMapping("/oauth/confirm_access")
public ModelAndView confimAccess(Map<String, Object> model, @ModelAttribute("authorizationRequest") AuthorizationRequest clientAuth) { public ModelAndView confimAccess(Map<String, Object> model, @ModelAttribute("authorizationRequest") AuthorizationRequest clientAuth) {
@ -72,10 +72,10 @@ public class OAuthConfirmationController {
//AuthorizationRequest clientAuth = (AuthorizationRequest) model.remove("authorizationRequest"); //AuthorizationRequest clientAuth = (AuthorizationRequest) model.remove("authorizationRequest");
ClientDetails client = null; ClientDetails client = null;
try { try {
client = clientService.loadClientByClientId(clientAuth.getClientId()); client = clientService.loadClientByClientId(clientAuth.getClientId());
} catch (OAuth2Exception e) { } catch (OAuth2Exception e) {
logger.error("confirmAccess: OAuth2Exception was thrown when attempting to load client: " logger.error("confirmAccess: OAuth2Exception was thrown when attempting to load client: "
, e); , e);
model.put("code", HttpStatus.BAD_REQUEST); model.put("code", HttpStatus.BAD_REQUEST);
@ -86,7 +86,7 @@ public class OAuthConfirmationController {
model.put("code", HttpStatus.BAD_REQUEST); model.put("code", HttpStatus.BAD_REQUEST);
return new ModelAndView("httpCodeView"); return new ModelAndView("httpCodeView");
} }
if (client == null) { if (client == null) {
logger.error("confirmAccess: could not find client " + clientAuth.getClientId()); logger.error("confirmAccess: could not find client " + clientAuth.getClientId());
model.put("code", HttpStatus.NOT_FOUND); model.put("code", HttpStatus.NOT_FOUND);
@ -96,49 +96,49 @@ public class OAuthConfirmationController {
model.put("client", client); model.put("client", client);
String redirect_uri = clientAuth.getRequestParameters().get("redirect_uri"); String redirect_uri = clientAuth.getRequestParameters().get("redirect_uri");
model.put("redirect_uri", redirect_uri);
model.put("redirect_uri", redirect_uri);
/*
/*
Map<String, Boolean> scopes = new HashMap<String, Boolean>(); Map<String, Boolean> scopes = new HashMap<String, Boolean>();
for (String scope : clientAuth.getScope()) { for (String scope : clientAuth.getScope()) {
scopes.put(scope, Boolean.TRUE); scopes.put(scope, Boolean.TRUE);
} }
*/ */
Set<SystemScope> scopes = scopeService.fromStrings(clientAuth.getScope()); Set<SystemScope> scopes = scopeService.fromStrings(clientAuth.getScope());
Set<SystemScope> sortedScopes = new LinkedHashSet<SystemScope>(scopes.size()); Set<SystemScope> sortedScopes = new LinkedHashSet<SystemScope>(scopes.size());
Set<SystemScope> systemScopes = scopeService.getAll(); Set<SystemScope> systemScopes = scopeService.getAll();
// sort scopes for display // sort scopes for display
for (SystemScope s : systemScopes) { for (SystemScope s : systemScopes) {
if (scopes.contains(s)) { if (scopes.contains(s)) {
sortedScopes.add(s); sortedScopes.add(s);
} }
} }
sortedScopes.addAll(Sets.difference(scopes, systemScopes)); sortedScopes.addAll(Sets.difference(scopes, systemScopes));
model.put("scopes", sortedScopes); model.put("scopes", sortedScopes);
return new ModelAndView("oauth/approve", model); return new ModelAndView("oauth/approve", model);
} }
/** /**
* @return the clientService * @return the clientService
*/ */
public ClientDetailsEntityService getClientService() { public ClientDetailsEntityService getClientService() {
return clientService; return clientService;
} }
/** /**
* @param clientService the clientService to set * @param clientService the clientService to set
*/ */
public void setClientService(ClientDetailsEntityService clientService) { public void setClientService(ClientDetailsEntityService clientService) {
this.clientService = clientService; this.clientService = clientService;
} }
} }

View File

@ -38,52 +38,52 @@ import org.springframework.web.servlet.ModelAndView;
public class RevocationEndpoint { public class RevocationEndpoint {
@Autowired @Autowired
OAuth2TokenEntityService tokenServices; OAuth2TokenEntityService tokenServices;
private static Logger logger = LoggerFactory.getLogger(RevocationEndpoint.class); private static Logger logger = LoggerFactory.getLogger(RevocationEndpoint.class);
public RevocationEndpoint() { public RevocationEndpoint() {
} }
public RevocationEndpoint(OAuth2TokenEntityService tokenServices) { public RevocationEndpoint(OAuth2TokenEntityService tokenServices) {
this.tokenServices = tokenServices; this.tokenServices = tokenServices;
} }
// TODO // TODO
@PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_CLIENT')") @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_CLIENT')")
@RequestMapping("/revoke") @RequestMapping("/revoke")
public ModelAndView revoke(@RequestParam("token") String tokenValue, Principal principal, public ModelAndView revoke(@RequestParam("token") String tokenValue, Principal principal,
ModelAndView modelAndView) { ModelAndView modelAndView) {
OAuth2RefreshTokenEntity refreshToken = null; OAuth2RefreshTokenEntity refreshToken = null;
OAuth2AccessTokenEntity accessToken = null; OAuth2AccessTokenEntity accessToken = null;
try { try {
refreshToken = tokenServices.getRefreshToken(tokenValue); refreshToken = tokenServices.getRefreshToken(tokenValue);
} catch (InvalidTokenException e) { } catch (InvalidTokenException e) {
// it's OK if either of these tokens are bad // it's OK if either of these tokens are bad
//TODO: Error Handling //TODO: Error Handling
} }
try { try {
accessToken = tokenServices.readAccessToken(tokenValue); accessToken = tokenServices.readAccessToken(tokenValue);
} catch (InvalidTokenException e) { } catch (InvalidTokenException e) {
// it's OK if either of these tokens are bad // it's OK if either of these tokens are bad
//TODO: Error Handling //TODO: Error Handling
} catch (AuthenticationException e) { } catch (AuthenticationException e) {
//TODO: Error Handling //TODO: Error Handling
} }
if (refreshToken == null && accessToken == null) { if (refreshToken == null && accessToken == null) {
//TODO: Error Handling //TODO: Error Handling
// TODO: this should throw a 400 with a JSON error code // TODO: this should throw a 400 with a JSON error code
throw new InvalidTokenException("Invalid OAuth token: " + tokenValue); throw new InvalidTokenException("Invalid OAuth token: " + tokenValue);
} }
if (principal instanceof OAuth2Authentication) { if (principal instanceof OAuth2Authentication) {
//TODO what is this variable for? It is unused. is it just a validation check? //TODO what is this variable for? It is unused. is it just a validation check?
OAuth2AccessTokenEntity tok = tokenServices.getAccessToken((OAuth2Authentication) principal); OAuth2AccessTokenEntity tok = tokenServices.getAccessToken((OAuth2Authentication) principal);
// we've got a client acting on its own behalf, not an admin // we've got a client acting on its own behalf, not an admin
//ClientAuthentication clientAuth = (ClientAuthenticationToken) ((OAuth2Authentication) auth).getClientAuthentication(); //ClientAuthentication clientAuth = (ClientAuthenticationToken) ((OAuth2Authentication) auth).getClientAuthentication();
OAuth2Request clientAuth = ((OAuth2Authentication) principal).getOAuth2Request(); OAuth2Request clientAuth = ((OAuth2Authentication) principal).getOAuth2Request();
@ -91,27 +91,27 @@ public class RevocationEndpoint {
if (refreshToken != null) { if (refreshToken != null) {
if (!refreshToken.getClient().getClientId().equals(clientAuth.getClientId())) { if (!refreshToken.getClient().getClientId().equals(clientAuth.getClientId())) {
// trying to revoke a token we don't own, fail // trying to revoke a token we don't own, fail
// TODO: this should throw a 403 // TODO: this should throw a 403
//TODO: Error Handling //TODO: Error Handling
throw new PermissionDeniedException("Client tried to revoke a token it doesn't own"); throw new PermissionDeniedException("Client tried to revoke a token it doesn't own");
} }
} else { } else {
if (!accessToken.getClient().getClientId().equals(clientAuth.getClientId())) { if (!accessToken.getClient().getClientId().equals(clientAuth.getClientId())) {
// trying to revoke a token we don't own, fail // trying to revoke a token we don't own, fail
// TODO: this should throw a 403 // TODO: this should throw a 403
//TODO: Error Handling //TODO: Error Handling
throw new PermissionDeniedException("Client tried to revoke a token it doesn't own"); throw new PermissionDeniedException("Client tried to revoke a token it doesn't own");
} }
} }
} }
// if we got this far, we're allowed to do this // if we got this far, we're allowed to do this
if (refreshToken != null) { if (refreshToken != null) {
tokenServices.revokeRefreshToken(refreshToken); tokenServices.revokeRefreshToken(refreshToken);
} else { } else {
tokenServices.revokeAccessToken(accessToken); tokenServices.revokeAccessToken(accessToken);
} }
// TODO: throw a 200 back (no content?) // TODO: throw a 200 back (no content?)
return modelAndView; return modelAndView;
} }

View File

@ -5,9 +5,6 @@ package org.mitre.oauth2.web;
import java.util.Set; import java.util.Set;
import javax.persistence.EntityExistsException;
import javax.persistence.TransactionRequiredException;
import org.mitre.oauth2.model.SystemScope; import org.mitre.oauth2.model.SystemScope;
import org.mitre.oauth2.service.SystemScopeService; import org.mitre.oauth2.service.SystemScopeService;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -35,35 +32,35 @@ public class ScopeAPI {
@Autowired @Autowired
private SystemScopeService scopeService; private SystemScopeService scopeService;
private static Logger logger = LoggerFactory.getLogger(ScopeAPI.class); private static Logger logger = LoggerFactory.getLogger(ScopeAPI.class);
private Gson gson = new Gson(); private Gson gson = new Gson();
@RequestMapping(value = "", method = RequestMethod.GET, produces = "application/json") @RequestMapping(value = "", method = RequestMethod.GET, produces = "application/json")
public String getAll(ModelMap m) { public String getAll(ModelMap m) {
Set<SystemScope> allScopes = scopeService.getAll(); Set<SystemScope> allScopes = scopeService.getAll();
m.put("entity", allScopes); m.put("entity", allScopes);
return "jsonEntityView"; return "jsonEntityView";
} }
@RequestMapping(value = "/{id}", method = RequestMethod.GET, produces = "application/json") @RequestMapping(value = "/{id}", method = RequestMethod.GET, produces = "application/json")
public String getScope(@PathVariable("id") Long id, ModelMap m) { public String getScope(@PathVariable("id") Long id, ModelMap m) {
SystemScope scope = scopeService.getById(id); SystemScope scope = scopeService.getById(id);
if (scope != null) { if (scope != null) {
m.put("entity", scope); m.put("entity", scope);
return "jsonEntityView"; return "jsonEntityView";
} else { } else {
logger.error("getScope failed; scope not found: " + id); logger.error("getScope failed; scope not found: " + id);
m.put("code", HttpStatus.NOT_FOUND); m.put("code", HttpStatus.NOT_FOUND);
m.put("errorMessage", "The requested scope with id " + id + " could not be found."); m.put("errorMessage", "The requested scope with id " + id + " could not be found.");
return "jsonErrorView"; return "jsonErrorView";
@ -73,46 +70,46 @@ public class ScopeAPI {
@PreAuthorize("hasRole('ROLE_ADMIN')") @PreAuthorize("hasRole('ROLE_ADMIN')")
@RequestMapping(value = "/{id}", method = RequestMethod.PUT, produces = "application/json", consumes = "application/json") @RequestMapping(value = "/{id}", method = RequestMethod.PUT, produces = "application/json", consumes = "application/json")
public String updateScope(@PathVariable("id") Long id, @RequestBody String json, ModelMap m) { public String updateScope(@PathVariable("id") Long id, @RequestBody String json, ModelMap m) {
SystemScope existing = scopeService.getById(id); SystemScope existing = scopeService.getById(id);
SystemScope scope = gson.fromJson(json, SystemScope.class); SystemScope scope = gson.fromJson(json, SystemScope.class);
if (existing != null && scope != null) { if (existing != null && scope != null) {
if (existing.getId().equals(scope.getId())) { if (existing.getId().equals(scope.getId())) {
// sanity check // sanity check
scope = scopeService.save(scope); scope = scopeService.save(scope);
m.put("entity", scope); m.put("entity", scope);
return "jsonEntityView"; return "jsonEntityView";
} else { } else {
logger.error("updateScope failed; scope ids to not match: got " logger.error("updateScope failed; scope ids to not match: got "
+ existing.getId() + " and " + scope.getId()); + existing.getId() + " and " + scope.getId());
m.put("code", HttpStatus.BAD_REQUEST); m.put("code", HttpStatus.BAD_REQUEST);
m.put("errorMessage", "Could not update scope. Scope ids to not match: got " m.put("errorMessage", "Could not update scope. Scope ids to not match: got "
+ existing.getId() + " and " + scope.getId()); + existing.getId() + " and " + scope.getId());
return "jsonErrorView"; return "jsonErrorView";
} }
} else { } else {
logger.error("updateScope failed; scope with id " + id + " not found."); logger.error("updateScope failed; scope with id " + id + " not found.");
m.put("code", HttpStatus.NOT_FOUND); m.put("code", HttpStatus.NOT_FOUND);
m.put("errorMessage", "Could not update scope. The scope with id " + id + " could not be found."); m.put("errorMessage", "Could not update scope. The scope with id " + id + " could not be found.");
return "jsonErrorView"; return "jsonErrorView";
} }
} }
@PreAuthorize("hasRole('ROLE_ADMIN')") @PreAuthorize("hasRole('ROLE_ADMIN')")
@RequestMapping(value = "", method = RequestMethod.POST, produces = "application/json", consumes = "application/json") @RequestMapping(value = "", method = RequestMethod.POST, produces = "application/json", consumes = "application/json")
public String createScope(@RequestBody String json, ModelMap m) { public String createScope(@RequestBody String json, ModelMap m) {
SystemScope scope = gson.fromJson(json, SystemScope.class); SystemScope scope = gson.fromJson(json, SystemScope.class);
SystemScope alreadyExists = scopeService.getByValue(scope.getValue()); SystemScope alreadyExists = scopeService.getByValue(scope.getValue());
if (alreadyExists != null) { if (alreadyExists != null) {
//Error, cannot save a scope with the same value as an existing one //Error, cannot save a scope with the same value as an existing one
@ -121,41 +118,41 @@ public class ScopeAPI {
m.put("errorMessage", "A scope with value " + scope.getValue() + " already exists, please choose a different value."); m.put("errorMessage", "A scope with value " + scope.getValue() + " already exists, please choose a different value.");
return "jsonErrorView"; return "jsonErrorView";
} }
scope = scopeService.save(scope); scope = scopeService.save(scope);
if (scope != null && scope.getId() != null) { if (scope != null && scope.getId() != null) {
m.put("entity", scope); m.put("entity", scope);
return "jsonEntityView"; return "jsonEntityView";
} else { } else {
logger.error("createScope failed; JSON was invalid: " + json); logger.error("createScope failed; JSON was invalid: " + json);
m.put("code", HttpStatus.BAD_REQUEST); m.put("code", HttpStatus.BAD_REQUEST);
m.put("errorMessage", "Could not save new scope " + scope.getValue() + ". The scope service failed to return a saved entity."); m.put("errorMessage", "Could not save new scope " + scope.getValue() + ". The scope service failed to return a saved entity.");
return "jsonErrorView"; return "jsonErrorView";
} }
} }
@PreAuthorize("hasRole('ROLE_ADMIN')") @PreAuthorize("hasRole('ROLE_ADMIN')")
@RequestMapping(value = "/{id}", method = RequestMethod.DELETE) @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
public String deleteScope(@PathVariable("id") Long id, ModelMap m) { public String deleteScope(@PathVariable("id") Long id, ModelMap m) {
SystemScope existing = scopeService.getById(id); SystemScope existing = scopeService.getById(id);
if (existing != null) { if (existing != null) {
scopeService.remove(existing); scopeService.remove(existing);
return "httpCodeView"; return "httpCodeView";
} else { } else {
logger.error("deleteScope failed; scope with id " + id + " not found."); logger.error("deleteScope failed; scope with id " + id + " not found.");
m.put("code", HttpStatus.NOT_FOUND); m.put("code", HttpStatus.NOT_FOUND);
m.put("errorMessage", "Could not delete scope. The requested scope with id " + id + " could not be found."); m.put("errorMessage", "Could not delete scope. The requested scope with id " + id + " could not be found.");
return "jsonErrorView"; return "jsonErrorView";
} }
} }
} }

View File

@ -36,10 +36,10 @@ import com.nimbusds.jwt.SignedJWT;
public class ConnectOAuth2RequestFactory extends DefaultOAuth2RequestFactory { public class ConnectOAuth2RequestFactory extends DefaultOAuth2RequestFactory {
private static Logger logger = LoggerFactory.getLogger(ConnectOAuth2RequestFactory.class); private static Logger logger = LoggerFactory.getLogger(ConnectOAuth2RequestFactory.class);
//@Autowired //@Autowired
private NonceService nonceService; private NonceService nonceService;
//@Autowired //@Autowired
private ClientDetailsEntityService clientDetailsService; private ClientDetailsEntityService clientDetailsService;
@ -58,7 +58,7 @@ public class ConnectOAuth2RequestFactory extends DefaultOAuth2RequestFactory {
this.clientDetailsService = clientDetailsService; this.clientDetailsService = clientDetailsService;
this.nonceService = nonceService; this.nonceService = nonceService;
} }
/** /**
* Default empty constructor * Default empty constructor
*/ */
@ -70,28 +70,28 @@ public class ConnectOAuth2RequestFactory extends DefaultOAuth2RequestFactory {
public AuthorizationRequest createAuthorizationRequest(Map<String, String> inputParams) { public AuthorizationRequest createAuthorizationRequest(Map<String, String> inputParams) {
Map<String, String> parameters = processRequestObject(inputParams); Map<String, String> parameters = processRequestObject(inputParams);
String clientId = parameters.get("client_id"); String clientId = parameters.get("client_id");
ClientDetails client = null; ClientDetails client = null;
if (clientId != null) { if (clientId != null) {
client = clientDetailsService.loadClientByClientId(clientId); client = clientDetailsService.loadClientByClientId(clientId);
} }
String requestNonce = parameters.get("nonce"); String requestNonce = parameters.get("nonce");
AuthorizationRequest request = new AuthorizationRequest(parameters, Collections.<String, String> emptyMap(), AuthorizationRequest request = new AuthorizationRequest(parameters, Collections.<String, String> emptyMap(),
parameters.get(OAuth2Utils.CLIENT_ID), parameters.get(OAuth2Utils.CLIENT_ID),
OAuth2Utils.parseParameterList(parameters.get(OAuth2Utils.SCOPE)), null, OAuth2Utils.parseParameterList(parameters.get(OAuth2Utils.SCOPE)), null,
null, false, parameters.get(OAuth2Utils.STATE), null, false, parameters.get(OAuth2Utils.STATE),
parameters.get(OAuth2Utils.REDIRECT_URI), parameters.get(OAuth2Utils.REDIRECT_URI),
OAuth2Utils.parseParameterList(parameters.get(OAuth2Utils.RESPONSE_TYPE))); OAuth2Utils.parseParameterList(parameters.get(OAuth2Utils.RESPONSE_TYPE)));
//Only process if the user is authenticated. If the user is not authenticated yet, this //Only process if the user is authenticated. If the user is not authenticated yet, this
//code will be called a second time once the user is redirected from the login page back //code will be called a second time once the user is redirected from the login page back
//to the auth endpoint. //to the auth endpoint.
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if (requestNonce != null && principal != null && principal instanceof User) { if (requestNonce != null && principal != null && principal instanceof User) {
if (!nonceService.alreadyUsed(clientId, requestNonce)) { if (!nonceService.alreadyUsed(clientId, requestNonce)) {
@ -101,18 +101,18 @@ public class ConnectOAuth2RequestFactory extends DefaultOAuth2RequestFactory {
else { else {
throw new NonceReuseException(client == null ? "unidentified client" : client.getClientId(), requestNonce); throw new NonceReuseException(client == null ? "unidentified client" : client.getClientId(), requestNonce);
} }
} }
Set<String> scopes = OAuth2Utils.parseParameterList(parameters.get("scope")); Set<String> scopes = OAuth2Utils.parseParameterList(parameters.get("scope"));
if ((scopes == null || scopes.isEmpty()) && client != null) { if ((scopes == null || scopes.isEmpty()) && client != null) {
//TODO: do we want to allow default scoping at all? //TODO: do we want to allow default scoping at all?
Set<String> clientScopes = client.getScope(); Set<String> clientScopes = client.getScope();
scopes = clientScopes; scopes = clientScopes;
} }
request.setScope(scopes); request.setScope(scopes);
return request; return request;
} }
@ -120,46 +120,46 @@ public class ConnectOAuth2RequestFactory extends DefaultOAuth2RequestFactory {
* @param inputParams * @param inputParams
* @return * @return
*/ */
private Map<String, String> processRequestObject(Map<String, String> inputParams) { private Map<String, String> processRequestObject(Map<String, String> inputParams) {
String jwtString = inputParams.get("request");
// if there's no request object, bail early
if (Strings.isNullOrEmpty(jwtString)) {
return inputParams;
}
// start by copying over what's already in there String jwtString = inputParams.get("request");
Map<String, String> parameters = new HashMap<String, String>(inputParams);
// if there's no request object, bail early
if (Strings.isNullOrEmpty(jwtString)) {
return inputParams;
}
// start by copying over what's already in there
Map<String, String> parameters = new HashMap<String, String>(inputParams);
// parse the request object
try {
SignedJWT jwsObject = SignedJWT.parse(jwtString);
JSONObject claims = jwsObject.getPayload().toJSONObject();
// parse the request object
try {
SignedJWT jwsObject = SignedJWT.parse(jwtString);
JSONObject claims = jwsObject.getPayload().toJSONObject();
// TODO: check parameter consistency, move keys to constants // TODO: check parameter consistency, move keys to constants
String clientId = JSONObjectUtils.getString(claims, "client_id"); String clientId = JSONObjectUtils.getString(claims, "client_id");
if (clientId != null) { if (clientId != null) {
parameters.put("client_id", clientId); parameters.put("client_id", clientId);
} }
ClientDetailsEntity client = clientDetailsService.loadClientByClientId(clientId); ClientDetailsEntity client = clientDetailsService.loadClientByClientId(clientId);
if (client.getJwksUri() == null) { if (client.getJwksUri() == null) {
throw new InvalidClientException("Client must have a JWK URI registered to use request objects."); throw new InvalidClientException("Client must have a JWK URI registered to use request objects.");
} }
// check JWT signature // check JWT signature
JwtSigningAndValidationService validator = validators.get(client.getJwksUri()); JwtSigningAndValidationService validator = validators.get(client.getJwksUri());
if (validator == null) { if (validator == null) {
throw new InvalidClientException("Client must have a JWK URI registered to use request objects."); throw new InvalidClientException("Client must have a JWK URI registered to use request objects.");
} }
if (!validator.validateSignature(jwsObject)) { if (!validator.validateSignature(jwsObject)) {
throw new AuthenticationServiceException("Signature did not validate for presented JWT request object."); throw new AuthenticationServiceException("Signature did not validate for presented JWT request object.");
} }
/* /*
* if (in Claims): * if (in Claims):
* if (in params): * if (in params):
@ -172,57 +172,57 @@ public class ConnectOAuth2RequestFactory extends DefaultOAuth2RequestFactory {
* else (not in claims): * else (not in claims):
* we don't care * we don't care
*/ */
String responseTypes = JSONObjectUtils.getString(claims, "response_type"); String responseTypes = JSONObjectUtils.getString(claims, "response_type");
if (responseTypes != null) { if (responseTypes != null) {
parameters.put("response_type", responseTypes); parameters.put("response_type", responseTypes);
} }
if (claims.get("redirect_uri") != null) { if (claims.get("redirect_uri") != null) {
if (inputParams.containsKey("redirect_uri") == false) { if (inputParams.containsKey("redirect_uri") == false) {
parameters.put("redirect_uri", JSONObjectUtils.getString(claims, "redirect_uri")); parameters.put("redirect_uri", JSONObjectUtils.getString(claims, "redirect_uri"));
} }
} }
String state = JSONObjectUtils.getString(claims, "state"); String state = JSONObjectUtils.getString(claims, "state");
if(state != null) { if(state != null) {
if (inputParams.containsKey("state") == false) { if (inputParams.containsKey("state") == false) {
parameters.put("state", state); parameters.put("state", state);
} }
} }
String nonce = JSONObjectUtils.getString(claims, "nonce"); String nonce = JSONObjectUtils.getString(claims, "nonce");
if(nonce != null) { if(nonce != null) {
if (inputParams.containsKey("nonce") == false) { if (inputParams.containsKey("nonce") == false) {
parameters.put("nonce", nonce); parameters.put("nonce", nonce);
} }
} }
String display = JSONObjectUtils.getString(claims, "display"); String display = JSONObjectUtils.getString(claims, "display");
if (display != null) { if (display != null) {
if (inputParams.containsKey("display") == false) { if (inputParams.containsKey("display") == false) {
parameters.put("display", display); parameters.put("display", display);
} }
} }
String prompt = JSONObjectUtils.getString(claims, "prompt"); String prompt = JSONObjectUtils.getString(claims, "prompt");
if (prompt != null) { if (prompt != null) {
if (inputParams.containsKey("prompt") == false) { if (inputParams.containsKey("prompt") == false) {
parameters.put("prompt", prompt); parameters.put("prompt", prompt);
} }
} }
String scope = JSONObjectUtils.getString(claims, "scope"); String scope = JSONObjectUtils.getString(claims, "scope");
if (scope != null) { if (scope != null) {
if (inputParams.containsKey("scope") == false) { if (inputParams.containsKey("scope") == false) {
parameters.put("scope", scope); parameters.put("scope", scope);
} }
} }
} catch (ParseException e) { } catch (ParseException e) {
logger.error("ParseException while parsing RequestObject:", e); logger.error("ParseException while parsing RequestObject:", e);
} }
return parameters; return parameters;
} }
} }

View File

@ -18,19 +18,19 @@ public class JwtBearerAssertionAuthenticationToken extends AbstractAuthenticatio
private String clientId; private String clientId;
private JWT jwt; private JWT jwt;
/** /**
* Create an unauthenticated token with the given client ID and jwt * Create an unauthenticated token with the given client ID and jwt
* @param clientId * @param clientId
* @param jwt * @param jwt
*/ */
public JwtBearerAssertionAuthenticationToken(String clientId, JWT jwt) { public JwtBearerAssertionAuthenticationToken(String clientId, JWT jwt) {
super(null); super(null);
this.clientId = clientId; this.clientId = clientId;
this.jwt = jwt; this.jwt = jwt;
setAuthenticated(false); setAuthenticated(false);
} }
/** /**
* Create an authenticated token with the given clientID, jwt, and authorities set * Create an authenticated token with the given clientID, jwt, and authorities set
* @param clientId * @param clientId
@ -38,11 +38,11 @@ public class JwtBearerAssertionAuthenticationToken extends AbstractAuthenticatio
* @param authorities * @param authorities
*/ */
public JwtBearerAssertionAuthenticationToken(String clientId, JWT jwt, Collection<? extends GrantedAuthority> authorities) { public JwtBearerAssertionAuthenticationToken(String clientId, JWT jwt, Collection<? extends GrantedAuthority> authorities) {
super(authorities); super(authorities);
this.clientId = clientId; this.clientId = clientId;
this.jwt = jwt; this.jwt = jwt;
setAuthenticated(true); setAuthenticated(true);
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.springframework.security.core.Authentication#getCredentials() * @see org.springframework.security.core.Authentication#getCredentials()
@ -61,42 +61,42 @@ public class JwtBearerAssertionAuthenticationToken extends AbstractAuthenticatio
} }
/** /**
* @return the clientId * @return the clientId
*/ */
public String getClientId() { public String getClientId() {
return clientId; return clientId;
} }
/** /**
* @param clientId the clientId to set * @param clientId the clientId to set
*/ */
public void setClientId(String clientId) { public void setClientId(String clientId) {
this.clientId = clientId; this.clientId = clientId;
} }
/** /**
* @return the jwt * @return the jwt
*/ */
public JWT getJwt() { public JWT getJwt() {
return jwt; return jwt;
} }
/** /**
* @param jwt the jwt to set * @param jwt the jwt to set
*/ */
public void setJwt(JWT jwt) { public void setJwt(JWT jwt) {
this.jwt = jwt; this.jwt = jwt;
} }
/** /**
* Clear out the JWT that this token holds. * Clear out the JWT that this token holds.
*/ */
@Override @Override
public void eraseCredentials() { public void eraseCredentials() {
super.eraseCredentials(); super.eraseCredentials();
setJwt(null); setJwt(null);
} }
} }

View File

@ -36,49 +36,49 @@ public class JwtBearerAuthenticationProvider implements AuthenticationProvider {
// map of verifiers, load keys for clients // map of verifiers, load keys for clients
@Autowired @Autowired
private JWKSetSigningAndValidationServiceCacheService validators; private JWKSetSigningAndValidationServiceCacheService validators;
// Allow for time sync issues by having a window of X seconds. // Allow for time sync issues by having a window of X seconds.
private int timeSkewAllowance = 300; private int timeSkewAllowance = 300;
// to load clients // to load clients
@Autowired @Autowired
private ClientDetailsEntityService clientService; private ClientDetailsEntityService clientService;
// to get our server's issuer url // to get our server's issuer url
@Autowired @Autowired
private ConfigurationPropertiesBean config; private ConfigurationPropertiesBean config;
/** /**
* Try to validate the client credentials by parsing and validating the JWT. * Try to validate the client credentials by parsing and validating the JWT.
*/ */
@Override @Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException { public Authentication authenticate(Authentication authentication) throws AuthenticationException {
JwtBearerAssertionAuthenticationToken jwtAuth = (JwtBearerAssertionAuthenticationToken)authentication;
try {
ClientDetailsEntity client = clientService.loadClientByClientId(jwtAuth.getClientId());
JWT jwt = jwtAuth.getJwt(); JwtBearerAssertionAuthenticationToken jwtAuth = (JwtBearerAssertionAuthenticationToken)authentication;
ReadOnlyJWTClaimsSet jwtClaims = jwt.getJWTClaimsSet();
try {
ClientDetailsEntity client = clientService.loadClientByClientId(jwtAuth.getClientId());
JWT jwt = jwtAuth.getJwt();
ReadOnlyJWTClaimsSet jwtClaims = jwt.getJWTClaimsSet();
// check the signature with nimbus
if (jwt instanceof SignedJWT) {
SignedJWT jws = (SignedJWT)jwt;
JwtSigningAndValidationService validator = validators.get(client.getJwksUri());
if (validator == null || !validator.validateSignature(jws)) {
throw new AuthenticationServiceException("Invalid signature");
}
}
// check the signature with nimbus
if (jwt instanceof SignedJWT) {
SignedJWT jws = (SignedJWT)jwt;
JwtSigningAndValidationService validator = validators.get(client.getJwksUri());
if (validator == null || !validator.validateSignature(jws)) {
throw new AuthenticationServiceException("Invalid signature");
}
}
// check the issuer // check the issuer
if (jwtClaims.getIssuer() == null) { if (jwtClaims.getIssuer() == null) {
throw new AuthenticationServiceException("Assertion Token Issuer is null"); throw new AuthenticationServiceException("Assertion Token Issuer is null");
} else if (!jwtClaims.getIssuer().equals(client.getClientId())){ } else if (!jwtClaims.getIssuer().equals(client.getClientId())){
throw new AuthenticationServiceException("Issuers do not match, expected " + client.getClientId() + " got " + jwtClaims.getIssuer()); throw new AuthenticationServiceException("Issuers do not match, expected " + client.getClientId() + " got " + jwtClaims.getIssuer());
} }
// check expiration // check expiration
if (jwtClaims.getExpirationTime() == null) { if (jwtClaims.getExpirationTime() == null) {
throw new AuthenticationServiceException("Assertion Token does not have required expiration claim"); throw new AuthenticationServiceException("Assertion Token does not have required expiration claim");
@ -89,7 +89,7 @@ public class JwtBearerAuthenticationProvider implements AuthenticationProvider {
throw new AuthenticationServiceException("Assertion Token is expired: " + jwtClaims.getExpirationTime()); throw new AuthenticationServiceException("Assertion Token is expired: " + jwtClaims.getExpirationTime());
} }
} }
// check not before // check not before
if (jwtClaims.getNotBeforeTime() != null) { if (jwtClaims.getNotBeforeTime() != null) {
Date now = new Date(System.currentTimeMillis() + (timeSkewAllowance * 1000)); Date now = new Date(System.currentTimeMillis() + (timeSkewAllowance * 1000));
@ -97,7 +97,7 @@ public class JwtBearerAuthenticationProvider implements AuthenticationProvider {
throw new AuthenticationServiceException("Assertion Token not valid untill: " + jwtClaims.getNotBeforeTime()); throw new AuthenticationServiceException("Assertion Token not valid untill: " + jwtClaims.getNotBeforeTime());
} }
} }
// check issued at // check issued at
if (jwtClaims.getIssueTime() != null) { if (jwtClaims.getIssueTime() != null) {
// since it's not null, see if it was issued in the future // since it's not null, see if it was issued in the future
@ -106,32 +106,32 @@ public class JwtBearerAuthenticationProvider implements AuthenticationProvider {
throw new AuthenticationServiceException("Assertion Token was issued in the future: " + jwtClaims.getIssueTime()); throw new AuthenticationServiceException("Assertion Token was issued in the future: " + jwtClaims.getIssueTime());
} }
} }
// check audience // check audience
if (jwtClaims.getAudience() == null) { if (jwtClaims.getAudience() == null) {
throw new AuthenticationServiceException("Assertion token audience is null"); throw new AuthenticationServiceException("Assertion token audience is null");
} else if (!jwtClaims.getAudience().contains(config.getIssuer())) { } else if (!jwtClaims.getAudience().contains(config.getIssuer())) {
throw new AuthenticationServiceException("Audience does not match, expected " + config.getIssuer() + " got " + jwtClaims.getAudience()); throw new AuthenticationServiceException("Audience does not match, expected " + config.getIssuer() + " got " + jwtClaims.getAudience());
} }
// 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
return new JwtBearerAssertionAuthenticationToken(client.getClientId(), jwt, client.getAuthorities()); return new JwtBearerAssertionAuthenticationToken(client.getClientId(), jwt, client.getAuthorities());
} catch (ClientNotFoundException e) { } catch (ClientNotFoundException e) {
throw new UsernameNotFoundException("Could not find client: " + jwtAuth.getClientId()); throw new UsernameNotFoundException("Could not find client: " + jwtAuth.getClientId());
} catch (ParseException e) { } catch (ParseException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
throw new AuthenticationServiceException("Invalid JWT format"); throw new AuthenticationServiceException("Invalid JWT format");
} }
} }
/** /**
* We support {@link JwtBearerAssertionAuthenticationToken}s only. * We support {@link JwtBearerAssertionAuthenticationToken}s only.
*/ */
@Override @Override
public boolean supports(Class<?> authentication) { public boolean supports(Class<?> authentication) {
return (JwtBearerAssertionAuthenticationToken.class.isAssignableFrom(authentication)); return (JwtBearerAssertionAuthenticationToken.class.isAssignableFrom(authentication));
} }
} }

View File

@ -28,74 +28,74 @@ import com.nimbusds.jwt.JWTParser;
public class JwtBearerClientAssertionTokenEndpointFilter extends ClientCredentialsTokenEndpointFilter { public class JwtBearerClientAssertionTokenEndpointFilter extends ClientCredentialsTokenEndpointFilter {
public JwtBearerClientAssertionTokenEndpointFilter() { public JwtBearerClientAssertionTokenEndpointFilter() {
super(); super();
// TODO Auto-generated constructor stub // TODO Auto-generated constructor stub
} }
public JwtBearerClientAssertionTokenEndpointFilter(String path) { public JwtBearerClientAssertionTokenEndpointFilter(String path) {
super(path); super(path);
// TODO Auto-generated constructor stub // TODO Auto-generated constructor stub
} }
/** /**
* Pull the assertion out of the request and send it up to the auth manager for processing. * Pull the assertion out of the request and send it up to the auth manager for processing.
*/ */
@Override @Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException { public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
// check for appropriate parameters // check for appropriate parameters
String assertionType = request.getParameter("client_assertion_type"); String assertionType = request.getParameter("client_assertion_type");
String assertion = request.getParameter("client_assertion"); String assertion = request.getParameter("client_assertion");
try { try {
JWT jwt = JWTParser.parse(assertion); JWT jwt = JWTParser.parse(assertion);
String clientId = jwt.getJWTClaimsSet().getSubject(); String clientId = jwt.getJWTClaimsSet().getSubject();
Authentication authRequest = new JwtBearerAssertionAuthenticationToken(clientId, jwt); Authentication authRequest = new JwtBearerAssertionAuthenticationToken(clientId, jwt);
return this.getAuthenticationManager().authenticate(authRequest); return this.getAuthenticationManager().authenticate(authRequest);
} catch (ParseException e) { } catch (ParseException e) {
throw new BadCredentialsException("Invalid JWT credential: " + assertion); throw new BadCredentialsException("Invalid JWT credential: " + assertion);
} }
} }
/** /**
* Check to see if the "client_assertion_type" and "client_assertion" parameters are present and contain the right values. * Check to see if the "client_assertion_type" and "client_assertion" parameters are present and contain the right values.
*/ */
@Override @Override
protected boolean requiresAuthentication(HttpServletRequest request, HttpServletResponse response) { protected boolean requiresAuthentication(HttpServletRequest request, HttpServletResponse response) {
// check for appropriate parameters // check for appropriate parameters
String assertionType = request.getParameter("client_assertion_type"); String assertionType = request.getParameter("client_assertion_type");
String assertion = request.getParameter("client_assertion"); String assertion = request.getParameter("client_assertion");
if (Strings.isNullOrEmpty(assertionType) || Strings.isNullOrEmpty(assertion)) {
return false;
} else if (!assertionType.equals("urn:ietf:params:oauth:client-assertion-type:jwt-bearer")) {
return false;
}
// Can't call to superclass here b/c client creds would break for lack of client_id
// return super.requiresAuthentication(request, response);
String uri = request.getRequestURI();
int pathParamIndex = uri.indexOf(';');
if (pathParamIndex > 0) {
// strip everything after the first semi-colon
uri = uri.substring(0, pathParamIndex);
}
if ("".equals(request.getContextPath())) {
return uri.endsWith(getFilterProcessesUrl());
}
return uri.endsWith(request.getContextPath() + getFilterProcessesUrl());
}
if (Strings.isNullOrEmpty(assertionType) || Strings.isNullOrEmpty(assertion)) {
return false;
} else if (!assertionType.equals("urn:ietf:params:oauth:client-assertion-type:jwt-bearer")) {
return false;
}
// Can't call to superclass here b/c client creds would break for lack of client_id
// return super.requiresAuthentication(request, response);
String uri = request.getRequestURI();
int pathParamIndex = uri.indexOf(';');
if (pathParamIndex > 0) {
// strip everything after the first semi-colon
uri = uri.substring(0, pathParamIndex);
}
if ("".equals(request.getContextPath())) {
return uri.endsWith(getFilterProcessesUrl());
}
return uri.endsWith(request.getContextPath() + getFilterProcessesUrl());
}
} }

View File

@ -30,5 +30,5 @@ public class ExpiredTokenException extends RuntimeException {
public ExpiredTokenException(String message) { public ExpiredTokenException(String message) {
super(message); super(message);
} }
} }

View File

@ -30,5 +30,5 @@ public class InvalidJwtIssuerException extends RuntimeException {
public InvalidJwtIssuerException(String message) { public InvalidJwtIssuerException(String message) {
super(message); super(message);
} }
} }

View File

@ -22,7 +22,7 @@ package org.mitre.openid.connect.exception;
public class InvalidJwtSignatureException extends RuntimeException { public class InvalidJwtSignatureException extends RuntimeException {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public InvalidJwtSignatureException() { public InvalidJwtSignatureException() {
super(); super();
} }
@ -30,5 +30,5 @@ public class InvalidJwtSignatureException extends RuntimeException {
public InvalidJwtSignatureException(String message) { public InvalidJwtSignatureException(String message) {
super(message); super(message);
} }
} }

View File

@ -20,9 +20,9 @@ package org.mitre.openid.connect.exception;
* *
*/ */
public class UnknownUserInfoSchemaException extends RuntimeException { public class UnknownUserInfoSchemaException extends RuntimeException {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public UnknownUserInfoSchemaException() { public UnknownUserInfoSchemaException() {
super(); super();
} }
@ -30,5 +30,5 @@ public class UnknownUserInfoSchemaException extends RuntimeException {
public UnknownUserInfoSchemaException(String message) { public UnknownUserInfoSchemaException(String message) {
super(message); super(message);
} }
} }

View File

@ -5,23 +5,23 @@ public class UserNotFoundException extends RuntimeException {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public UserNotFoundException() { public UserNotFoundException() {
super(); super();
// TODO Auto-generated constructor stub // TODO Auto-generated constructor stub
} }
public UserNotFoundException(String message, Throwable cause) { public UserNotFoundException(String message, Throwable cause) {
super(message, cause); super(message, cause);
// TODO Auto-generated constructor stub // TODO Auto-generated constructor stub
} }
public UserNotFoundException(String message) { public UserNotFoundException(String message) {
super(message); super(message);
// TODO Auto-generated constructor stub // TODO Auto-generated constructor stub
} }
public UserNotFoundException(Throwable cause) { public UserNotFoundException(Throwable cause) {
super(cause); super(cause);
// TODO Auto-generated constructor stub // TODO Auto-generated constructor stub
} }
} }

View File

@ -25,7 +25,6 @@ import javax.persistence.TypedQuery;
import org.mitre.openid.connect.model.ApprovedSite; import org.mitre.openid.connect.model.ApprovedSite;
import org.mitre.openid.connect.repository.ApprovedSiteRepository; import org.mitre.openid.connect.repository.ApprovedSiteRepository;
import org.mitre.util.jpa.JpaUtil;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -48,7 +47,7 @@ public class JpaApprovedSiteRepository implements ApprovedSiteRepository {
"ApprovedSite.getAll", ApprovedSite.class); "ApprovedSite.getAll", ApprovedSite.class);
return query.getResultList(); return query.getResultList();
} }
@Override @Override
@Transactional @Transactional
public ApprovedSite getById(Long id) { public ApprovedSite getById(Long id) {
@ -59,7 +58,7 @@ public class JpaApprovedSiteRepository implements ApprovedSiteRepository {
@Transactional @Transactional
public void remove(ApprovedSite approvedSite) { public void remove(ApprovedSite approvedSite) {
ApprovedSite found = manager.find(ApprovedSite.class, approvedSite.getId()); ApprovedSite found = manager.find(ApprovedSite.class, approvedSite.getId());
if (found != null) { if (found != null) {
manager.remove(found); manager.remove(found);
} else { } else {
@ -75,30 +74,30 @@ public class JpaApprovedSiteRepository implements ApprovedSiteRepository {
@Override @Override
public Collection<ApprovedSite> getByClientIdAndUserId(String clientId, String userId) { public Collection<ApprovedSite> getByClientIdAndUserId(String clientId, String userId) {
TypedQuery<ApprovedSite> query = manager.createNamedQuery("ApprovedSite.getByClientIdAndUserId", ApprovedSite.class); TypedQuery<ApprovedSite> query = manager.createNamedQuery("ApprovedSite.getByClientIdAndUserId", ApprovedSite.class);
query.setParameter("userId", userId); query.setParameter("userId", userId);
query.setParameter("clientId", clientId); query.setParameter("clientId", clientId);
return query.getResultList(); return query.getResultList();
} }
@Override @Override
@Transactional @Transactional
public Collection<ApprovedSite> getByUserId(String userId) { public Collection<ApprovedSite> getByUserId(String userId) {
TypedQuery<ApprovedSite> query = manager.createNamedQuery("ApprovedSite.getByUserId", ApprovedSite.class); TypedQuery<ApprovedSite> query = manager.createNamedQuery("ApprovedSite.getByUserId", ApprovedSite.class);
query.setParameter("userId", userId); query.setParameter("userId", userId);
return query.getResultList(); return query.getResultList();
}
@Override }
@Transactional
public Collection<ApprovedSite> getByClientId(String clientId) { @Override
@Transactional
public Collection<ApprovedSite> getByClientId(String clientId) {
TypedQuery<ApprovedSite> query = manager.createNamedQuery("ApprovedSite.getByClientId", ApprovedSite.class); TypedQuery<ApprovedSite> query = manager.createNamedQuery("ApprovedSite.getByClientId", ApprovedSite.class);
query.setParameter("clientId", clientId); query.setParameter("clientId", clientId);
return query.getResultList(); return query.getResultList();
} }
} }

View File

@ -25,7 +25,7 @@ public class JpaBlacklistedSiteRepository implements BlacklistedSiteRepository {
@PersistenceContext @PersistenceContext
private EntityManager manager; private EntityManager manager;
/* (non-Javadoc) /* (non-Javadoc)
* @see org.mitre.openid.connect.repository.BlacklistedSiteRepository#getAll() * @see org.mitre.openid.connect.repository.BlacklistedSiteRepository#getAll()
*/ */
@ -52,7 +52,7 @@ public class JpaBlacklistedSiteRepository implements BlacklistedSiteRepository {
@Transactional @Transactional
public void remove(BlacklistedSite blacklistedSite) { public void remove(BlacklistedSite blacklistedSite) {
BlacklistedSite found = manager.find(BlacklistedSite.class, blacklistedSite.getId()); BlacklistedSite found = manager.find(BlacklistedSite.class, blacklistedSite.getId());
if (found != null) { if (found != null) {
manager.remove(found); manager.remove(found);
} else { } else {
@ -79,7 +79,7 @@ public class JpaBlacklistedSiteRepository implements BlacklistedSiteRepository {
blacklistedSite.setId(oldBlacklistedSite.getId()); blacklistedSite.setId(oldBlacklistedSite.getId());
return saveOrUpdate(oldBlacklistedSite.getId(), manager, blacklistedSite); return saveOrUpdate(oldBlacklistedSite.getId(), manager, blacklistedSite);
} }
} }

View File

@ -38,7 +38,7 @@ import org.springframework.transaction.annotation.Transactional;
*/ */
@Repository @Repository
public class JpaEventRepository implements EventRepository { public class JpaEventRepository implements EventRepository {
@PersistenceContext @PersistenceContext
private EntityManager manager; private EntityManager manager;
@ -52,17 +52,17 @@ public class JpaEventRepository implements EventRepository {
@Override @Override
@Transactional @Transactional
public Collection<Event> getEventsDuringPeriod(Date start, Date end, int startChunk, int chunkSize) { public Collection<Event> getEventsDuringPeriod(Date start, Date end, int startChunk, int chunkSize) {
Query query = manager.createQuery("SELECT e FROM Event e WHERE e.timestamp BETWEEN :start AND :end"); Query query = manager.createQuery("SELECT e FROM Event e WHERE e.timestamp BETWEEN :start AND :end");
query = query.setParameter("start", start, TemporalType.DATE); query = query.setParameter("start", start, TemporalType.DATE);
query = query.setParameter("end", end, TemporalType.DATE); query = query.setParameter("end", end, TemporalType.DATE);
query = query.setFirstResult(startChunk); query = query.setFirstResult(startChunk);
query = query.setMaxResults(chunkSize); query = query.setMaxResults(chunkSize);
return query.getResultList(); return query.getResultList();
} }
@Override @Override
@Transactional @Transactional
public void remove(Event event) { public void remove(Event event) {

View File

@ -8,7 +8,6 @@ import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext; import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery; import javax.persistence.TypedQuery;
import org.mitre.openid.connect.model.ApprovedSite;
import org.mitre.openid.connect.model.Nonce; import org.mitre.openid.connect.model.Nonce;
import org.mitre.openid.connect.repository.NonceRepository; import org.mitre.openid.connect.repository.NonceRepository;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
@ -20,7 +19,7 @@ public class JpaNonceRepository implements NonceRepository {
@PersistenceContext @PersistenceContext
private EntityManager manager; private EntityManager manager;
@Override @Override
@Transactional @Transactional
public Nonce getById(Long id) { public Nonce getById(Long id) {
@ -31,7 +30,7 @@ public class JpaNonceRepository implements NonceRepository {
@Transactional @Transactional
public void remove(Nonce nonce) { public void remove(Nonce nonce) {
Nonce found = manager.find(Nonce.class, nonce.getId()); Nonce found = manager.find(Nonce.class, nonce.getId());
if (found != null) { if (found != null) {
manager.remove(found); manager.remove(found);
} else { } else {
@ -65,7 +64,7 @@ public class JpaNonceRepository implements NonceRepository {
public Collection<Nonce> getByClientId(String clientId) { public Collection<Nonce> getByClientId(String clientId) {
TypedQuery<Nonce> query = manager.createNamedQuery("Nonce.getByClientId", Nonce.class); TypedQuery<Nonce> query = manager.createNamedQuery("Nonce.getByClientId", Nonce.class);
query.setParameter("clientId", clientId); query.setParameter("clientId", clientId);
return query.getResultList(); return query.getResultList();
} }

View File

@ -15,8 +15,8 @@
******************************************************************************/ ******************************************************************************/
package org.mitre.openid.connect.repository.impl; package org.mitre.openid.connect.repository.impl;
import static org.mitre.util.jpa.JpaUtil.saveOrUpdate;
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 java.util.Collection; import java.util.Collection;
@ -40,43 +40,43 @@ import org.springframework.transaction.annotation.Transactional;
public class JpaUserInfoRepository implements UserInfoRepository { public class JpaUserInfoRepository implements UserInfoRepository {
@PersistenceContext @PersistenceContext
private EntityManager manager; private EntityManager manager;
@Override @Override
@Transactional @Transactional
public UserInfo getBySubject(String sub) { public UserInfo getBySubject(String sub) {
TypedQuery<DefaultUserInfo> query = manager.createNamedQuery("DefaultUserInfo.getBySubject", DefaultUserInfo.class); TypedQuery<DefaultUserInfo> query = manager.createNamedQuery("DefaultUserInfo.getBySubject", DefaultUserInfo.class);
query.setParameter("sub", sub); query.setParameter("sub", sub);
return getSingleResult(query.getResultList()); return getSingleResult(query.getResultList());
} }
@Override @Override
@Transactional @Transactional
public UserInfo save(UserInfo userInfo) { public UserInfo save(UserInfo userInfo) {
DefaultUserInfo dui = (DefaultUserInfo)userInfo; DefaultUserInfo dui = (DefaultUserInfo)userInfo;
return saveOrUpdate(dui.getId(), manager, dui); return saveOrUpdate(dui.getId(), manager, dui);
} }
@Override @Override
@Transactional @Transactional
public void remove(UserInfo userInfo) { public void remove(UserInfo userInfo) {
DefaultUserInfo dui = (DefaultUserInfo)userInfo; DefaultUserInfo dui = (DefaultUserInfo)userInfo;
UserInfo found = manager.find(DefaultUserInfo.class, dui.getId()); UserInfo found = manager.find(DefaultUserInfo.class, dui.getId());
if (found != null) { if (found != null) {
manager.remove(userInfo); manager.remove(userInfo);
} else { } else {
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
} }
@Override @Override
@Transactional @Transactional
public Collection<DefaultUserInfo> getAll() { public Collection<DefaultUserInfo> getAll() {
TypedQuery<DefaultUserInfo> query = manager.createNamedQuery("DefaultUserInfo.getAll", DefaultUserInfo.class); TypedQuery<DefaultUserInfo> query = manager.createNamedQuery("DefaultUserInfo.getAll", DefaultUserInfo.class);
return query.getResultList(); return query.getResultList();
} }
@ -84,12 +84,12 @@ public class JpaUserInfoRepository implements UserInfoRepository {
* Get a single UserInfo object by its username * Get a single UserInfo object by its username
*/ */
@Override @Override
public UserInfo getByUsername(String username) { public UserInfo getByUsername(String username) {
TypedQuery<DefaultUserInfo> query = manager.createNamedQuery("DefaultUserInfo.getByUsername", DefaultUserInfo.class); TypedQuery<DefaultUserInfo> query = manager.createNamedQuery("DefaultUserInfo.getByUsername", DefaultUserInfo.class);
query.setParameter("username", username); query.setParameter("username", username);
return getSingleResult(query.getResultList()); return getSingleResult(query.getResultList());
} }
} }

View File

@ -77,10 +77,10 @@ public class JpaWhitelistedSiteRepository implements WhitelistedSiteRepository {
public WhitelistedSite update(WhitelistedSite oldWhitelistedSite, WhitelistedSite whitelistedSite) { public WhitelistedSite update(WhitelistedSite oldWhitelistedSite, WhitelistedSite whitelistedSite) {
// sanity check // sanity check
whitelistedSite.setId(oldWhitelistedSite.getId()); whitelistedSite.setId(oldWhitelistedSite.getId());
return saveOrUpdate(oldWhitelistedSite.getId(), manager, whitelistedSite); return saveOrUpdate(oldWhitelistedSite.getId(), manager, whitelistedSite);
} }
@Override @Override
@Transactional @Transactional
public WhitelistedSite getByClientId(String clientId) { public WhitelistedSite getByClientId(String clientId) {
@ -94,7 +94,7 @@ public class JpaWhitelistedSiteRepository implements WhitelistedSiteRepository {
public Collection<WhitelistedSite> getByCreator(String creatorId) { public Collection<WhitelistedSite> getByCreator(String creatorId) {
TypedQuery<WhitelistedSite> query = manager.createNamedQuery("WhitelistedSite.getByCreaterUserId", WhitelistedSite.class); TypedQuery<WhitelistedSite> query = manager.createNamedQuery("WhitelistedSite.getByCreaterUserId", WhitelistedSite.class);
query.setParameter("userId", creatorId); query.setParameter("userId", creatorId);
return query.getResultList(); return query.getResultList();
} }
} }

View File

@ -42,26 +42,26 @@ public class DefaultApprovedSiteService implements ApprovedSiteService {
@Autowired @Autowired
private ApprovedSiteRepository approvedSiteRepository; private ApprovedSiteRepository approvedSiteRepository;
@Autowired @Autowired
private OAuth2TokenRepository tokenRepository; private OAuth2TokenRepository tokenRepository;
/** /**
* Default constructor * Default constructor
*/ */
public DefaultApprovedSiteService() { public DefaultApprovedSiteService() {
} }
/** /**
* Constructor for use in test harnesses. * Constructor for use in test harnesses.
* *
* @param repository * @param repository
*/ */
public DefaultApprovedSiteService(ApprovedSiteRepository approvedSiteRepository) { public DefaultApprovedSiteService(ApprovedSiteRepository approvedSiteRepository) {
this.approvedSiteRepository = approvedSiteRepository; this.approvedSiteRepository = approvedSiteRepository;
} }
@Override @Override
public Collection<ApprovedSite> getAll() { public Collection<ApprovedSite> getAll() {
return approvedSiteRepository.getAll(); return approvedSiteRepository.getAll();
@ -81,7 +81,7 @@ public class DefaultApprovedSiteService implements ApprovedSiteService {
@Override @Override
@Transactional @Transactional
public void remove(ApprovedSite approvedSite) { public void remove(ApprovedSite approvedSite) {
//Remove any associated access and refresh tokens //Remove any associated access and refresh tokens
Set<OAuth2AccessTokenEntity> accessTokens = approvedSite.getApprovedAccessTokens(); Set<OAuth2AccessTokenEntity> accessTokens = approvedSite.getApprovedAccessTokens();
@ -91,17 +91,17 @@ public class DefaultApprovedSiteService implements ApprovedSiteService {
} }
tokenRepository.removeAccessToken(token); tokenRepository.removeAccessToken(token);
} }
approvedSiteRepository.remove(approvedSite); approvedSiteRepository.remove(approvedSite);
} }
@Override @Override
@Transactional @Transactional
public ApprovedSite createApprovedSite(String clientId, String userId, Date timeoutDate, Set<String> allowedScopes, public ApprovedSite createApprovedSite(String clientId, String userId, Date timeoutDate, Set<String> allowedScopes,
WhitelistedSite whitelistedSite) { WhitelistedSite whitelistedSite) {
ApprovedSite as = approvedSiteRepository.save(new ApprovedSite()); ApprovedSite as = approvedSiteRepository.save(new ApprovedSite());
Date now = new Date(); Date now = new Date();
as.setCreationDate(now); as.setCreationDate(now);
as.setAccessDate(now); as.setAccessDate(now);
@ -110,47 +110,47 @@ public class DefaultApprovedSiteService implements ApprovedSiteService {
as.setTimeoutDate(timeoutDate); as.setTimeoutDate(timeoutDate);
as.setAllowedScopes(allowedScopes); as.setAllowedScopes(allowedScopes);
as.setWhitelistedSite(whitelistedSite); as.setWhitelistedSite(whitelistedSite);
return save(as); return save(as);
} }
@Override @Override
public Collection<ApprovedSite> getByClientIdAndUserId(String clientId, String userId) { public Collection<ApprovedSite> getByClientIdAndUserId(String clientId, String userId) {
return approvedSiteRepository.getByClientIdAndUserId(clientId, userId); return approvedSiteRepository.getByClientIdAndUserId(clientId, userId);
} }
/** /**
* @param userId * @param userId
* @return * @return
* @see org.mitre.openid.connect.repository.ApprovedSiteRepository#getByUserId(java.lang.String) * @see org.mitre.openid.connect.repository.ApprovedSiteRepository#getByUserId(java.lang.String)
*/ */
@Override @Override
public Collection<ApprovedSite> getByUserId(String userId) { public Collection<ApprovedSite> getByUserId(String userId) {
return approvedSiteRepository.getByUserId(userId); return approvedSiteRepository.getByUserId(userId);
} }
/** /**
* @param clientId * @param clientId
* @return * @return
* @see org.mitre.openid.connect.repository.ApprovedSiteRepository#getByClientId(java.lang.String) * @see org.mitre.openid.connect.repository.ApprovedSiteRepository#getByClientId(java.lang.String)
*/ */
@Override @Override
public Collection<ApprovedSite> getByClientId(String clientId) { public Collection<ApprovedSite> getByClientId(String clientId) {
return approvedSiteRepository.getByClientId(clientId); return approvedSiteRepository.getByClientId(clientId);
} }
@Override @Override
public void clearApprovedSitesForClient(ClientDetails client) { public void clearApprovedSitesForClient(ClientDetails client) {
Collection<ApprovedSite> approvedSites = approvedSiteRepository.getByClientId(client.getClientId()); Collection<ApprovedSite> approvedSites = approvedSiteRepository.getByClientId(client.getClientId());
if (approvedSites != null) { if (approvedSites != null) {
for (ApprovedSite approvedSite : approvedSites) { for (ApprovedSite approvedSite : approvedSites) {
approvedSiteRepository.remove(approvedSite); approvedSiteRepository.remove(approvedSite);
} }
} }
} }
} }

Some files were not shown because too many files have changed in this diff Show More