Applied code cleanup
parent
3e23967b46
commit
15aea61fbe
|
@ -27,178 +27,178 @@ import com.google.gson.JsonParser;
|
|||
|
||||
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() {
|
||||
return introspectionUrl;
|
||||
}
|
||||
private String clientId;
|
||||
private String clientSecret;
|
||||
private String introspectionUrl;
|
||||
|
||||
public void setIntrospectionUrl(String introspectionUrl) {
|
||||
this.introspectionUrl = 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 getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
public String getIntrospectionUrl() {
|
||||
return introspectionUrl;
|
||||
}
|
||||
|
||||
public void setClientId(String clientId) {
|
||||
this.clientId = clientId;
|
||||
}
|
||||
public void setIntrospectionUrl(String introspectionUrl) {
|
||||
this.introspectionUrl = introspectionUrl;
|
||||
}
|
||||
|
||||
public String getClientSecret() {
|
||||
return clientSecret;
|
||||
}
|
||||
public String getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
|
||||
public void setClientSecret(String clientSecret) {
|
||||
this.clientSecret = clientSecret;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
public void setClientId(String clientId) {
|
||||
this.clientId = clientId;
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
||||
}
|
||||
public String getClientSecret() {
|
||||
return clientSecret;
|
||||
}
|
||||
|
||||
public void setClientSecret(String clientSecret) {
|
||||
this.clientSecret = clientSecret;
|
||||
}
|
||||
|
||||
// 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 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,73 +20,73 @@ import com.google.gson.JsonObject;
|
|||
|
||||
public class OAuth2AccessTokenImpl implements OAuth2AccessToken {
|
||||
|
||||
private JsonObject token;
|
||||
private String tokenString;
|
||||
private Set<String> scopes = null;
|
||||
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);
|
||||
}
|
||||
}
|
||||
private JsonObject token;
|
||||
private String tokenString;
|
||||
private Set<String> scopes = null;
|
||||
private Date expireDate;
|
||||
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getAdditionalInformation() {
|
||||
return null;
|
||||
}
|
||||
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());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getScope() {
|
||||
return scopes;
|
||||
}
|
||||
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 OAuth2RefreshToken getRefreshToken() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTokenType() {
|
||||
return BEARER_TYPE;
|
||||
}
|
||||
@Override
|
||||
public Map<String, Object> getAdditionalInformation() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isExpired() {
|
||||
if (expireDate != null && expireDate.before(new Date())) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public Set<String> getScope() {
|
||||
return scopes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getExpiration() {
|
||||
return expireDate;
|
||||
}
|
||||
@Override
|
||||
public OAuth2RefreshToken getRefreshToken() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getExpiresIn() {
|
||||
if (expireDate != null) {
|
||||
return (int)TimeUnit.MILLISECONDS.toSeconds(expireDate.getTime() - (new Date()).getTime());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@Override
|
||||
public String getTokenType() {
|
||||
return BEARER_TYPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValue() {
|
||||
return tokenString;
|
||||
}
|
||||
@Override
|
||||
public boolean isExpired() {
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,8 +20,6 @@ import java.math.BigInteger;
|
|||
import java.security.SecureRandom;
|
||||
import java.text.ParseException;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
@ -29,8 +27,6 @@ import javax.servlet.http.HttpServletResponse;
|
|||
import javax.servlet.http.HttpSession;
|
||||
|
||||
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.mitre.jwt.signer.service.JwtSigningAndValidationService;
|
||||
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 String FILTER_PROCESSES_URL = "/openid_connect_login";
|
||||
|
||||
|
||||
// Allow for time sync issues by having a window of X seconds.
|
||||
private int timeSkewAllowance = 300;
|
||||
|
||||
|
@ -86,7 +82,7 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi
|
|||
private ClientConfigurationService clients;
|
||||
private IssuerService issuerService;
|
||||
private AuthRequestUrlBuilder authRequestBuilder;
|
||||
|
||||
|
||||
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
|
||||
handleError(request, response);
|
||||
return null; // no auth, response is sent to display page or something
|
||||
|
||||
|
||||
} else if (!Strings.isNullOrEmpty(request.getParameter("code"))) {
|
||||
|
||||
// we got back the code, need to process this to get our tokens
|
||||
Authentication auth = handleAuthorizationCodeResponse(request, response);
|
||||
return auth;
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
// not an error, not a code, must be an initial login of some type
|
||||
handleAuthorizationRequest(request, response);
|
||||
|
||||
|
||||
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 {
|
||||
|
||||
HttpSession session = request.getSession();
|
||||
|
||||
|
||||
IssuerServiceResponse issResp = issuerService.getIssuer(request);
|
||||
|
||||
|
||||
if (issResp.shouldRedirect()) {
|
||||
response.sendRedirect(issResp.getRedirectUrl());
|
||||
} else {
|
||||
String issuer = issResp.getIssuer();
|
||||
|
||||
|
||||
session.setAttribute(ISSUER_SESSION_VARIABLE, issuer);
|
||||
|
||||
|
||||
ServerConfiguration serverConfig = servers.getServerConfiguration(issuer);
|
||||
ClientDetails clientConfig = clients.getClientConfiguration(issuer);
|
||||
|
||||
|
||||
// our redirect URI is this current URL, with no query parameters
|
||||
String redirectUri = request.getRequestURL().toString();
|
||||
session.setAttribute(REDIRECT_URI_SESION_VARIABLE, redirectUri);
|
||||
|
||||
|
||||
// this value comes back in the id token and is checked there
|
||||
String nonce = createNonce(session);
|
||||
|
||||
|
||||
// this value comes back in the auth code response
|
||||
String state = createState(session);
|
||||
|
||||
|
||||
String authRequest = authRequestBuilder.buildAuthRequestUrl(serverConfig, clientConfig, redirectUri, nonce, state);
|
||||
|
||||
|
||||
logger.debug("Auth Request: " + authRequest);
|
||||
|
||||
|
||||
response.sendRedirect(authRequest);
|
||||
}
|
||||
}
|
||||
|
@ -190,9 +186,9 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi
|
|||
protected Authentication handleAuthorizationCodeResponse(HttpServletRequest request, HttpServletResponse response) {
|
||||
|
||||
String authorizationCode = request.getParameter("code");
|
||||
|
||||
|
||||
HttpSession session = request.getSession();
|
||||
|
||||
|
||||
// check for state, if it doesn't match we bail early
|
||||
String storedState = getStoredState(session);
|
||||
if (!StringUtils.isBlank(storedState)) {
|
||||
|
@ -204,20 +200,20 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi
|
|||
|
||||
// look up the issuer that we set out to talk to
|
||||
String issuer = getStoredSessionString(session, ISSUER_SESSION_VARIABLE);
|
||||
|
||||
|
||||
// pull the configurations based on that issuer
|
||||
ServerConfiguration serverConfig = servers.getServerConfiguration(issuer);
|
||||
ClientDetails clientConfig = clients.getClientConfiguration(issuer);
|
||||
|
||||
|
||||
MultiValueMap<String, String> form = new LinkedMultiValueMap<String, String>();
|
||||
form.add("grant_type", "authorization_code");
|
||||
form.add("code", authorizationCode);
|
||||
|
||||
|
||||
String redirectUri = getStoredSessionString(session, REDIRECT_URI_SESION_VARIABLE);
|
||||
if (redirectUri != null) {
|
||||
form.add("redirect_uri", redirectUri);
|
||||
}
|
||||
|
||||
|
||||
// Handle Token Endpoint interaction
|
||||
DefaultHttpClient httpClient = new DefaultHttpClient();
|
||||
|
||||
|
@ -232,7 +228,7 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi
|
|||
*/
|
||||
form.add("client_id", clientConfig.getClientId());
|
||||
form.add("client_secret", clientConfig.getClientSecret());
|
||||
/**/
|
||||
/**/
|
||||
|
||||
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);
|
||||
|
||||
|
@ -257,14 +253,14 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi
|
|||
}
|
||||
|
||||
logger.debug("from TokenEndpoint jsonString = " + jsonString);
|
||||
|
||||
|
||||
JsonElement jsonRoot = new JsonParser().parse(jsonString);
|
||||
if (!jsonRoot.isJsonObject()) {
|
||||
throw new AuthenticationServiceException("Token Endpoint did not return a JSON object: " + jsonRoot);
|
||||
}
|
||||
|
||||
JsonObject tokenResponse = jsonRoot.getAsJsonObject();
|
||||
|
||||
|
||||
if (tokenResponse.get("error") != null) {
|
||||
|
||||
// Handle error
|
||||
|
@ -279,125 +275,125 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi
|
|||
|
||||
// Extract the id_token to insert into the
|
||||
// OIDCAuthenticationToken
|
||||
|
||||
|
||||
// get out all the token strings
|
||||
String accessTokenValue = null;
|
||||
String idTokenValue = null;
|
||||
String refreshTokenValue = null;
|
||||
|
||||
|
||||
if (tokenResponse.has("access_token")) {
|
||||
accessTokenValue = tokenResponse.get("access_token").getAsString();
|
||||
} else {
|
||||
throw new AuthenticationServiceException("Token Endpoint did not return an access_token: " + jsonString);
|
||||
}
|
||||
|
||||
|
||||
if (tokenResponse.has("id_token")) {
|
||||
idTokenValue = tokenResponse.get("id_token").getAsString();
|
||||
} else {
|
||||
logger.error("Token Endpoint did not return an id_token");
|
||||
throw new AuthenticationServiceException("Token Endpoint did not return an id_token");
|
||||
}
|
||||
|
||||
|
||||
if (tokenResponse.has("refresh_token")) {
|
||||
refreshTokenValue = tokenResponse.get("refresh_token").getAsString();
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
SignedJWT idToken = SignedJWT.parse(idTokenValue);
|
||||
SignedJWT idToken = SignedJWT.parse(idTokenValue);
|
||||
|
||||
// validate our ID Token over a number of tests
|
||||
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.");
|
||||
// validate our ID Token over a number of tests
|
||||
ReadOnlyJWTClaimsSet idClaims = idToken.getJWTClaimsSet();
|
||||
|
||||
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);
|
||||
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 + ".");
|
||||
// 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());
|
||||
}
|
||||
|
||||
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 + ".");
|
||||
}
|
||||
// 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());
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
// 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());
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a cryptographically random nonce and store it in the session
|
||||
* @param session
|
||||
|
@ -457,7 +453,7 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi
|
|||
protected static String getStoredNonce(HttpSession session) {
|
||||
return getStoredSessionString(session, NONCE_SESSION_VARIABLE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a cryptographically random state and store it in the session
|
||||
* @param session
|
||||
|
@ -466,10 +462,10 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi
|
|||
protected static String createState(HttpSession session) {
|
||||
String state = new BigInteger(50, new SecureRandom()).toString(16);
|
||||
session.setAttribute(STATE_SESSION_VARIABLE, state);
|
||||
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the state we stored in the session
|
||||
* @param session
|
||||
|
@ -478,14 +474,14 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi
|
|||
protected static String getStoredState(HttpSession session) {
|
||||
return getStoredSessionString(session, STATE_SESSION_VARIABLE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Getters and setters for configuration variables
|
||||
//
|
||||
|
||||
|
||||
|
||||
|
||||
public int getTimeSkewAllowance() {
|
||||
return timeSkewAllowance;
|
||||
}
|
||||
|
@ -562,6 +558,6 @@ public class OIDCAuthenticationFilter extends AbstractAuthenticationProcessingFi
|
|||
*/
|
||||
public void setAuthRequestUrlBuilder(AuthRequestUrlBuilder authRequestBuilder) {
|
||||
this.authRequestBuilder = authRequestBuilder;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -35,10 +35,10 @@ import com.google.common.collect.Sets;
|
|||
*
|
||||
*/
|
||||
public class OIDCAuthenticationProvider implements
|
||||
AuthenticationProvider, InitializingBean {
|
||||
AuthenticationProvider, InitializingBean {
|
||||
|
||||
private UserInfoFetcher userInfoFetcher = new UserInfoFetcher();
|
||||
|
||||
|
||||
private GrantedAuthoritiesMapper authoritiesMapper = new NullAuthoritiesMapper();
|
||||
|
||||
/*
|
||||
|
@ -70,22 +70,22 @@ public class OIDCAuthenticationProvider implements
|
|||
// Default authorities set
|
||||
// TODO: let this be configured
|
||||
Collection<SimpleGrantedAuthority> authorities = Sets.newHashSet(new SimpleGrantedAuthority("ROLE_USER"));
|
||||
|
||||
|
||||
OIDCAuthenticationToken token = (OIDCAuthenticationToken) authentication;
|
||||
|
||||
UserInfo userInfo = userInfoFetcher.loadUserInfo(token);
|
||||
|
||||
if (userInfo == null) {
|
||||
// TODO: user Info not found -- error?
|
||||
} else {
|
||||
} else {
|
||||
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
|
||||
throw new UsernameNotFoundException("user_id mismatch between id_token and user_info call: " + userInfo.getSub() + " / " + token.getUserId());
|
||||
}
|
||||
}
|
||||
|
||||
return new OIDCAuthenticationToken(token.getUserId(),
|
||||
token.getIssuer(),
|
||||
|
||||
return new OIDCAuthenticationToken(token.getUserId(),
|
||||
token.getIssuer(),
|
||||
userInfo, authoritiesMapper.mapAuthorities(authorities),
|
||||
token.getIdTokenValue(), token.getAccessTokenValue(), token.getRefreshTokenValue());
|
||||
}
|
||||
|
|
|
@ -32,8 +32,8 @@ import com.google.common.collect.ImmutableMap;
|
|||
*/
|
||||
public class OIDCAuthenticationToken extends AbstractAuthenticationToken {
|
||||
|
||||
private static final long serialVersionUID = 22100073066377804L;
|
||||
|
||||
private static final long serialVersionUID = 22100073066377804L;
|
||||
|
||||
private final Object principal;
|
||||
private final String idTokenValue; // string representation of the id 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 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.
|
||||
*
|
||||
|
@ -55,7 +55,7 @@ public class OIDCAuthenticationToken extends AbstractAuthenticationToken {
|
|||
* @param principal
|
||||
* @param idToken
|
||||
*/
|
||||
public OIDCAuthenticationToken(String userId, String issuer,
|
||||
public OIDCAuthenticationToken(String userId, String issuer,
|
||||
UserInfo userInfo, Collection<? extends GrantedAuthority> authorities,
|
||||
String idTokenValue, String accessTokenValue, String refreshTokenValue) {
|
||||
|
||||
|
@ -70,12 +70,12 @@ public class OIDCAuthenticationToken extends AbstractAuthenticationToken {
|
|||
this.refreshTokenValue = refreshTokenValue;
|
||||
|
||||
this.serverConfiguration = null; // we don't need a server config anymore
|
||||
|
||||
|
||||
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.
|
||||
*
|
||||
|
@ -83,8 +83,8 @@ public class OIDCAuthenticationToken extends AbstractAuthenticationToken {
|
|||
* @param userId
|
||||
* @param idToken
|
||||
*/
|
||||
public OIDCAuthenticationToken(String userId, String issuer,
|
||||
ServerConfiguration serverConfiguration,
|
||||
public OIDCAuthenticationToken(String userId, String issuer,
|
||||
ServerConfiguration serverConfiguration,
|
||||
String idTokenValue, String accessTokenValue, String refreshTokenValue) {
|
||||
|
||||
super(new ArrayList<GrantedAuthority>(0));
|
||||
|
@ -97,10 +97,10 @@ public class OIDCAuthenticationToken extends AbstractAuthenticationToken {
|
|||
this.refreshTokenValue = refreshTokenValue;
|
||||
|
||||
this.userInfo = null; // we don't have a UserInfo yet
|
||||
|
||||
|
||||
this.serverConfiguration = serverConfiguration;
|
||||
|
||||
|
||||
|
||||
|
||||
setAuthenticated(false);
|
||||
}
|
||||
|
||||
|
@ -130,46 +130,46 @@ public class OIDCAuthenticationToken extends AbstractAuthenticationToken {
|
|||
}
|
||||
|
||||
/**
|
||||
* @return the idTokenValue
|
||||
*/
|
||||
public String getIdTokenValue() {
|
||||
return idTokenValue;
|
||||
}
|
||||
* @return the idTokenValue
|
||||
*/
|
||||
public String getIdTokenValue() {
|
||||
return idTokenValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the accessTokenValue
|
||||
*/
|
||||
public String getAccessTokenValue() {
|
||||
return accessTokenValue;
|
||||
}
|
||||
* @return the accessTokenValue
|
||||
*/
|
||||
public String getAccessTokenValue() {
|
||||
return accessTokenValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the refreshTokenValue
|
||||
*/
|
||||
public String getRefreshTokenValue() {
|
||||
return refreshTokenValue;
|
||||
}
|
||||
* @return the refreshTokenValue
|
||||
*/
|
||||
public String getRefreshTokenValue() {
|
||||
return refreshTokenValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the serverConfiguration
|
||||
*/
|
||||
public ServerConfiguration getServerConfiguration() {
|
||||
return serverConfiguration;
|
||||
}
|
||||
* @return the serverConfiguration
|
||||
*/
|
||||
public ServerConfiguration getServerConfiguration() {
|
||||
return serverConfiguration;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the issuer
|
||||
*/
|
||||
public String getIssuer() {
|
||||
return issuer;
|
||||
}
|
||||
* @return the issuer
|
||||
*/
|
||||
public String getIssuer() {
|
||||
return issuer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the userInfo
|
||||
*/
|
||||
public UserInfo getUserInfo() {
|
||||
return userInfo;
|
||||
}
|
||||
|
||||
|
||||
* @return the userInfo
|
||||
*/
|
||||
public UserInfo getUserInfo() {
|
||||
return userInfo;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -15,7 +15,7 @@ import com.google.gson.JsonParser;
|
|||
public class UserInfoFetcher {
|
||||
|
||||
public UserInfo loadUserInfo(OIDCAuthenticationToken token) {
|
||||
|
||||
|
||||
HttpClient httpClient = new DefaultHttpClient();
|
||||
|
||||
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);
|
||||
|
@ -25,15 +25,15 @@ public class UserInfoFetcher {
|
|||
MultiValueMap<String, String> form = new LinkedMultiValueMap<String, String>();
|
||||
form.add("access_token", token.getAccessTokenValue());
|
||||
form.add("schema", "openid");
|
||||
|
||||
|
||||
String userInfoString = restTemplate.postForObject(token.getServerConfiguration().getUserInfoUri(), form, String.class);
|
||||
|
||||
|
||||
JsonObject userInfoJson = new JsonParser().parse(userInfoString).getAsJsonObject();
|
||||
|
||||
|
||||
UserInfo userInfo = DefaultUserInfo.fromJson(userInfoJson);
|
||||
|
||||
|
||||
return userInfo;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
@Override
|
||||
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
|
||||
*/
|
||||
@Override
|
||||
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
|
||||
if (!Strings.isNullOrEmpty(getJwkPublishUrl())) {
|
||||
|
||||
// add a mapping to this class
|
||||
BeanDefinitionBuilder clientKeyMapping = BeanDefinitionBuilder.rootBeanDefinition(ClientKeyPublisherMapping.class);
|
||||
// custom view resolver
|
||||
BeanDefinitionBuilder viewResolver = BeanDefinitionBuilder.rootBeanDefinition(JwkViewResolver.class);
|
||||
|
||||
|
||||
if (!Strings.isNullOrEmpty(getJwkPublishUrl())) {
|
||||
clientKeyMapping.addPropertyValue("jwkPublishUrl", getJwkPublishUrl());
|
||||
|
||||
|
@ -56,49 +56,49 @@ public class ClientKeyPublisher implements BeanDefinitionRegistryPostProcessor {
|
|||
registry.registerBeanDefinition("jwkKeyList", jwkView.getBeanDefinition());
|
||||
viewResolver.addPropertyReference("jwk", "jwkKeyList");
|
||||
}
|
||||
|
||||
|
||||
registry.registerBeanDefinition("clientKeyMapping", clientKeyMapping.getBeanDefinition());
|
||||
registry.registerBeanDefinition("jwkViewResolver", viewResolver.getBeanDefinition());
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry(org.springframework.beans.factory.support.BeanDefinitionRegistry)
|
||||
*/
|
||||
@Override
|
||||
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
|
||||
* @see org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry(org.springframework.beans.factory.support.BeanDefinitionRegistry)
|
||||
*/
|
||||
@Override
|
||||
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
|
||||
this.registry = registry;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a view to publish all keys in JWK format. Only used if jwkPublishUrl is set.
|
||||
* @return
|
||||
*/
|
||||
* Return a view to publish all keys in JWK format. Only used if jwkPublishUrl is set.
|
||||
* @return
|
||||
*/
|
||||
public ModelAndView publishClientJwk() {
|
||||
|
||||
|
||||
// map from key id to key
|
||||
Map<String, JWK> keys = signingAndValidationService.getAllPublicKeys();
|
||||
|
||||
// TODO: check if keys are empty, return a 404 here or just an empty list?
|
||||
|
||||
|
||||
return new ModelAndView(jwkViewName, "keys", keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the jwkPublishUrl
|
||||
*/
|
||||
public String getJwkPublishUrl() {
|
||||
return jwkPublishUrl;
|
||||
}
|
||||
* @return the jwkPublishUrl
|
||||
*/
|
||||
public String getJwkPublishUrl() {
|
||||
return jwkPublishUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param jwkPublishUrl the jwkPublishUrl to set
|
||||
*/
|
||||
public void setJwkPublishUrl(String jwkPublishUrl) {
|
||||
this.jwkPublishUrl = jwkPublishUrl;
|
||||
}
|
||||
* @param jwkPublishUrl the jwkPublishUrl to set
|
||||
*/
|
||||
public void setJwkPublishUrl(String jwkPublishUrl) {
|
||||
this.jwkPublishUrl = jwkPublishUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the signingAndValidationService
|
||||
|
|
|
@ -19,72 +19,72 @@ public class ClientKeyPublisherMapping extends RequestMappingInfoHandlerMapping
|
|||
|
||||
private String jwkPublishUrl;
|
||||
private String x509PublishUrl;
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.web.servlet.handler.AbstractHandlerMethodMapping#isHandler(java.lang.Class)
|
||||
*/
|
||||
@Override
|
||||
protected boolean isHandler(Class<?> beanType) {
|
||||
return beanType.equals(ClientKeyPublisher.class);
|
||||
}
|
||||
* @see org.springframework.web.servlet.handler.AbstractHandlerMethodMapping#isHandler(java.lang.Class)
|
||||
*/
|
||||
@Override
|
||||
protected boolean isHandler(Class<?> beanType) {
|
||||
return beanType.equals(ClientKeyPublisher.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Map the "jwkKeyPublish" method to our jwkPublishUrl.
|
||||
* Map the "x509KeyPublish" method to our x509PublishUrl.
|
||||
*/
|
||||
@Override
|
||||
protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {
|
||||
|
||||
if (method.getName().equals("publishClientJwk") && getJwkPublishUrl() != null) {
|
||||
return new RequestMappingInfo(
|
||||
new PatternsRequestCondition(new String[] {getJwkPublishUrl()}, getUrlPathHelper(), getPathMatcher(), false, false),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null);
|
||||
} else if (method.getName().equals("publishClientx509") && getX509PublishUrl() != null) {
|
||||
return new RequestMappingInfo(
|
||||
new PatternsRequestCondition(new String[] {getX509PublishUrl()}, getUrlPathHelper(), getPathMatcher(), false, false),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
@Override
|
||||
protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {
|
||||
|
||||
if (method.getName().equals("publishClientJwk") && getJwkPublishUrl() != null) {
|
||||
return new RequestMappingInfo(
|
||||
new PatternsRequestCondition(new String[] {getJwkPublishUrl()}, getUrlPathHelper(), getPathMatcher(), false, false),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null);
|
||||
} else if (method.getName().equals("publishClientx509") && getX509PublishUrl() != null) {
|
||||
return new RequestMappingInfo(
|
||||
new PatternsRequestCondition(new String[] {getX509PublishUrl()}, getUrlPathHelper(), getPathMatcher(), false, false),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the jwkPublishUrl
|
||||
*/
|
||||
public String getJwkPublishUrl() {
|
||||
return jwkPublishUrl;
|
||||
}
|
||||
* @return the jwkPublishUrl
|
||||
*/
|
||||
public String getJwkPublishUrl() {
|
||||
return jwkPublishUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param jwkPublishUrl the jwkPublishUrl to set
|
||||
*/
|
||||
public void setJwkPublishUrl(String jwkPublishUrl) {
|
||||
this.jwkPublishUrl = jwkPublishUrl;
|
||||
}
|
||||
* @param jwkPublishUrl the jwkPublishUrl to set
|
||||
*/
|
||||
public void setJwkPublishUrl(String jwkPublishUrl) {
|
||||
this.jwkPublishUrl = jwkPublishUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the x509PublishUrl
|
||||
*/
|
||||
public String getX509PublishUrl() {
|
||||
return x509PublishUrl;
|
||||
}
|
||||
* @return the x509PublishUrl
|
||||
*/
|
||||
public String getX509PublishUrl() {
|
||||
return x509PublishUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param x509PublishUrl the x509PublishUrl to set
|
||||
*/
|
||||
public void setX509PublishUrl(String x509PublishUrl) {
|
||||
this.x509PublishUrl = x509PublishUrl;
|
||||
}
|
||||
* @param x509PublishUrl the x509PublishUrl to set
|
||||
*/
|
||||
public void setX509PublishUrl(String x509PublishUrl) {
|
||||
this.x509PublishUrl = x509PublishUrl;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,12 +20,12 @@ public class JwkViewResolver implements ViewResolver, Ordered {
|
|||
|
||||
private String jwkViewName = "jwkKeyList";
|
||||
private View jwk;
|
||||
|
||||
|
||||
private String x509ViewName = "x509certs";
|
||||
private View x509;
|
||||
|
||||
|
||||
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.
|
||||
* Everything else returns null
|
||||
|
@ -46,74 +46,74 @@ public class JwkViewResolver implements ViewResolver, Ordered {
|
|||
}
|
||||
|
||||
/**
|
||||
* @return the x509
|
||||
*/
|
||||
public View getX509() {
|
||||
return x509;
|
||||
}
|
||||
* @return the x509
|
||||
*/
|
||||
public View getX509() {
|
||||
return x509;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param x509 the x509 to set
|
||||
*/
|
||||
public void setX509(View x509) {
|
||||
this.x509 = x509;
|
||||
}
|
||||
* @param x509 the x509 to set
|
||||
*/
|
||||
public void setX509(View x509) {
|
||||
this.x509 = x509;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the jwk
|
||||
*/
|
||||
public View getJwk() {
|
||||
return jwk;
|
||||
}
|
||||
* @return the jwk
|
||||
*/
|
||||
public View getJwk() {
|
||||
return jwk;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param jwk the jwk to set
|
||||
*/
|
||||
public void setJwk(View jwk) {
|
||||
this.jwk = jwk;
|
||||
}
|
||||
* @param jwk the jwk to set
|
||||
*/
|
||||
public void setJwk(View jwk) {
|
||||
this.jwk = jwk;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the order
|
||||
*/
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return order;
|
||||
}
|
||||
* @return the order
|
||||
*/
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return order;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param order the order to set
|
||||
*/
|
||||
public void setOrder(int order) {
|
||||
this.order = order;
|
||||
}
|
||||
* @param order the order to set
|
||||
*/
|
||||
public void setOrder(int order) {
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the jwkViewName
|
||||
*/
|
||||
public String getJwkViewName() {
|
||||
return jwkViewName;
|
||||
}
|
||||
* @return the jwkViewName
|
||||
*/
|
||||
public String getJwkViewName() {
|
||||
return jwkViewName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param jwkViewName the jwkViewName to set
|
||||
*/
|
||||
public void setJwkViewName(String jwkViewName) {
|
||||
this.jwkViewName = jwkViewName;
|
||||
}
|
||||
* @param jwkViewName the jwkViewName to set
|
||||
*/
|
||||
public void setJwkViewName(String jwkViewName) {
|
||||
this.jwkViewName = jwkViewName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the x509ViewName
|
||||
*/
|
||||
public String getX509ViewName() {
|
||||
return x509ViewName;
|
||||
}
|
||||
* @return the x509ViewName
|
||||
*/
|
||||
public String getX509ViewName() {
|
||||
return x509ViewName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param x509ViewName the x509ViewName to set
|
||||
*/
|
||||
public void setX509ViewName(String x509ViewName) {
|
||||
this.x509ViewName = x509ViewName;
|
||||
}
|
||||
* @param x509ViewName the x509ViewName to set
|
||||
*/
|
||||
public void setX509ViewName(String x509ViewName) {
|
||||
this.x509ViewName = x509ViewName;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,24 +16,24 @@ public class IssuerServiceResponse {
|
|||
private String loginHint;
|
||||
private String targetLinkUri;
|
||||
private String redirectUrl;
|
||||
|
||||
|
||||
/**
|
||||
* @param issuer
|
||||
* @param loginHint
|
||||
* @param targetLinkUri
|
||||
*/
|
||||
public IssuerServiceResponse(String issuer, String loginHint, String targetLinkUri) {
|
||||
this.issuer = issuer;
|
||||
this.loginHint = loginHint;
|
||||
this.targetLinkUri = targetLinkUri;
|
||||
}
|
||||
|
||||
public IssuerServiceResponse(String issuer, String loginHint, String targetLinkUri) {
|
||||
this.issuer = issuer;
|
||||
this.loginHint = loginHint;
|
||||
this.targetLinkUri = targetLinkUri;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param redirectUrl
|
||||
*/
|
||||
public IssuerServiceResponse(String redirectUrl) {
|
||||
this.redirectUrl = redirectUrl;
|
||||
}
|
||||
public IssuerServiceResponse(String redirectUrl) {
|
||||
this.redirectUrl = redirectUrl;
|
||||
}
|
||||
/**
|
||||
* @return the issuer
|
||||
*/
|
||||
|
@ -82,12 +82,12 @@ public class IssuerServiceResponse {
|
|||
public void setRedirectUrl(String redirectUrl) {
|
||||
this.redirectUrl = redirectUrl;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If the redirect url has been set, then we should send a redirect using it instead of processing things.
|
||||
*/
|
||||
public boolean shouldRedirect() {
|
||||
return this.redirectUrl != null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -20,6 +20,6 @@ public interface AuthRequestUrlBuilder {
|
|||
* @param state
|
||||
* @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);
|
||||
|
||||
}
|
||||
|
|
|
@ -12,5 +12,5 @@ import org.springframework.security.oauth2.provider.ClientDetails;
|
|||
public interface ClientConfigurationService {
|
||||
|
||||
public ClientDetails getClientConfiguration(String issuer);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -17,5 +17,5 @@ import org.mitre.openid.connect.client.model.IssuerServiceResponse;
|
|||
public interface IssuerService {
|
||||
|
||||
public IssuerServiceResponse getIssuer(HttpServletRequest request);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -12,5 +12,5 @@ import org.mitre.openid.connect.config.ServerConfiguration;
|
|||
public interface ServerConfigurationService {
|
||||
|
||||
public ServerConfiguration getServerConfiguration(String issuer);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ public class PlainAuthRequestUrlBuilder implements AuthRequestUrlBuilder {
|
|||
@Override
|
||||
public String buildAuthRequestUrl(ServerConfiguration serverConfig, ClientDetails clientConfig, String redirectUri, String nonce, String state) {
|
||||
try {
|
||||
|
||||
|
||||
URIBuilder uriBuilder = new URIBuilder(serverConfig.getAuthorizationEndpointUri());
|
||||
uriBuilder.addParameter("response_type", "code");
|
||||
uriBuilder.addParameter("client_id", clientConfig.getClientId());
|
||||
|
@ -39,20 +39,20 @@ public class PlainAuthRequestUrlBuilder implements AuthRequestUrlBuilder {
|
|||
uriBuilder.addParameter("nonce", nonce);
|
||||
|
||||
uriBuilder.addParameter("state", state);
|
||||
|
||||
|
||||
// Optional parameters:
|
||||
|
||||
// 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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,11 +4,6 @@
|
|||
package org.mitre.openid.connect.client.service.impl;
|
||||
|
||||
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.mitre.jwt.signer.service.JwtSigningAndValidationService;
|
||||
|
@ -38,34 +33,34 @@ public class SignedAuthRequestUrlBuilder implements AuthRequestUrlBuilder {
|
|||
|
||||
// create our signed JWT for the request object
|
||||
JWTClaimsSet claims = new JWTClaimsSet();
|
||||
|
||||
|
||||
//set parameters to JwtClaims
|
||||
claims.setCustomClaim("response_type", "code");
|
||||
claims.setCustomClaim("client_id", clientConfig.getClientId());
|
||||
claims.setCustomClaim("scope", Joiner.on(" ").join(clientConfig.getScope()));
|
||||
|
||||
|
||||
// build our redirect URI
|
||||
claims.setCustomClaim("redirect_uri", redirectUri);
|
||||
|
||||
|
||||
// this comes back in the id token
|
||||
claims.setCustomClaim("nonce", nonce);
|
||||
|
||||
|
||||
// this comes back in the auth request return
|
||||
claims.setCustomClaim("state", state);
|
||||
|
||||
|
||||
SignedJWT jwt = new SignedJWT(new JWSHeader(signingAndValidationService.getDefaultSigningAlgorithm()), claims);
|
||||
|
||||
|
||||
signingAndValidationService.signJwt(jwt);
|
||||
|
||||
|
||||
try {
|
||||
URIBuilder uriBuilder = new URIBuilder(serverConfig.getAuthorizationEndpointUri());
|
||||
uriBuilder.addParameter("request", jwt.serialize());
|
||||
|
||||
// build out the URI
|
||||
return uriBuilder.build().toString();
|
||||
} catch (URISyntaxException e) {
|
||||
throw new AuthenticationServiceException("Malformed Authorization Endpoint Uri", e);
|
||||
}
|
||||
URIBuilder uriBuilder = new URIBuilder(serverConfig.getAuthorizationEndpointUri());
|
||||
uriBuilder.addParameter("request", jwt.serialize());
|
||||
|
||||
// build out the URI
|
||||
return uriBuilder.build().toString();
|
||||
} catch (URISyntaxException e) {
|
||||
throw new AuthenticationServiceException("Malformed Authorization Endpoint Uri", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -21,7 +21,7 @@ public class StaticClientConfigurationService implements ClientConfigurationServ
|
|||
|
||||
// Map of issuer URL -> client configuration information
|
||||
private Map<String, ClientDetails> clients;
|
||||
|
||||
|
||||
/**
|
||||
* @return the clients
|
||||
*/
|
||||
|
@ -43,19 +43,19 @@ public class StaticClientConfigurationService implements ClientConfigurationServ
|
|||
*/
|
||||
@Override
|
||||
public ClientDetails getClientConfiguration(String issuer) {
|
||||
|
||||
|
||||
return clients.get(issuer);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
|
||||
*/
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
if (clients == null || clients.isEmpty()) {
|
||||
throw new IllegalArgumentException("Clients map cannot be null or empty");
|
||||
}
|
||||
|
||||
}
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
if (clients == null || clients.isEmpty()) {
|
||||
throw new IllegalArgumentException("Clients map cannot be null or empty");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -45,12 +45,12 @@ public class StaticServerConfigurationService implements ServerConfigurationServ
|
|||
/* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
|
||||
*/
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
if (servers == null || servers.isEmpty()) {
|
||||
throw new IllegalArgumentException("Servers map cannot be null or empty.");
|
||||
}
|
||||
|
||||
}
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
if (servers == null || servers.isEmpty()) {
|
||||
throw new IllegalArgumentException("Servers map cannot be null or empty.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ import com.google.common.base.Strings;
|
|||
*
|
||||
*/
|
||||
public class StaticSingleIssuerService implements IssuerService, InitializingBean {
|
||||
|
||||
|
||||
private String issuer;
|
||||
|
||||
/**
|
||||
|
@ -46,13 +46,13 @@ public class StaticSingleIssuerService implements IssuerService, InitializingBea
|
|||
/* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
|
||||
*/
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
|
||||
if (Strings.isNullOrEmpty(issuer)) {
|
||||
throw new IllegalArgumentException("Issuer must not be null or empty.");
|
||||
}
|
||||
|
||||
}
|
||||
if (Strings.isNullOrEmpty(issuer)) {
|
||||
throw new IllegalArgumentException("Issuer must not be null or empty.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -25,34 +25,34 @@ import com.google.common.base.Strings;
|
|||
public class ThirdPartyIssuerService implements IssuerService, InitializingBean {
|
||||
|
||||
private String accountChooserUrl;
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.mitre.openid.connect.client.service.IssuerService#getIssuer(javax.servlet.http.HttpServletRequest)
|
||||
*/
|
||||
@Override
|
||||
public IssuerServiceResponse getIssuer(HttpServletRequest request) {
|
||||
|
||||
|
||||
// if the issuer is passed in, return that
|
||||
if (!Strings.isNullOrEmpty(request.getParameter("iss"))) {
|
||||
return new IssuerServiceResponse(request.getParameter("iss"), request.getParameter("login_hint"), request.getParameter("target_link_uri"));
|
||||
} else {
|
||||
|
||||
|
||||
try {
|
||||
// otherwise, need to forward to the account chooser
|
||||
String redirectUri = request.getRequestURL().toString();
|
||||
URIBuilder builder = new URIBuilder(accountChooserUrl);
|
||||
|
||||
builder.addParameter("redirect_uri", redirectUri);
|
||||
|
||||
return new IssuerServiceResponse(builder.build().toString());
|
||||
|
||||
} catch (URISyntaxException e) {
|
||||
throw new AuthenticationServiceException("Account Chooser URL is not valid", e);
|
||||
}
|
||||
|
||||
|
||||
URIBuilder builder = new URIBuilder(accountChooserUrl);
|
||||
|
||||
builder.addParameter("redirect_uri", redirectUri);
|
||||
|
||||
return new IssuerServiceResponse(builder.build().toString());
|
||||
|
||||
} catch (URISyntaxException e) {
|
||||
throw new AuthenticationServiceException("Account Chooser URL is not valid", e);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -72,12 +72,12 @@ public class ThirdPartyIssuerService implements IssuerService, InitializingBean
|
|||
/* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
|
||||
*/
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
if (Strings.isNullOrEmpty(this.accountChooserUrl)) {
|
||||
throw new IllegalArgumentException("Account Chooser URL cannot be null or empty");
|
||||
}
|
||||
|
||||
}
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
if (Strings.isNullOrEmpty(this.accountChooserUrl)) {
|
||||
throw new IllegalArgumentException("Account Chooser URL cannot be null or empty");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
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
|
||||
|
@ -18,10 +13,10 @@ public class AbstractOIDCAuthenticationFilterTest {
|
|||
|
||||
//@Autowired
|
||||
private OIDCAuthenticationFilter filter;
|
||||
|
||||
|
||||
//@Test
|
||||
public void testUrlConstruction() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -37,7 +32,7 @@ public class AbstractOIDCAuthenticationFilterTest {
|
|||
public void setFilter(OIDCAuthenticationFilter filter) {
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ package org.mitre.jose;
|
|||
|
||||
import javax.persistence.Basic;
|
||||
import javax.persistence.Embeddable;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Transient;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
|
@ -22,16 +21,16 @@ import com.nimbusds.jose.JWEAlgorithm;
|
|||
public class JWEAlgorithmEmbed {
|
||||
|
||||
public static final JWEAlgorithmEmbed NONE = getForAlgorithmName("none");
|
||||
|
||||
|
||||
private JWEAlgorithm algorithm;
|
||||
|
||||
public JWEAlgorithmEmbed() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public JWEAlgorithmEmbed(JWEAlgorithm algorithm) {
|
||||
this.algorithm = algorithm;
|
||||
}
|
||||
this.algorithm = algorithm;
|
||||
}
|
||||
|
||||
public static JWEAlgorithmEmbed getForAlgorithmName (String algorithmName) {
|
||||
JWEAlgorithmEmbed ent = new JWEAlgorithmEmbed();
|
||||
|
@ -42,7 +41,7 @@ public class JWEAlgorithmEmbed {
|
|||
return ent;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the name of this algorithm, return null if no algorithm set.
|
||||
* @return
|
||||
|
@ -55,9 +54,9 @@ public class JWEAlgorithmEmbed {
|
|||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the name of this algorithm.
|
||||
* Set the name of this algorithm.
|
||||
* Calls JWEAlgorithm.parse()
|
||||
* @param algorithmName
|
||||
*/
|
||||
|
@ -72,15 +71,15 @@ public class JWEAlgorithmEmbed {
|
|||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "JWEAlgorithmEmbed [algorithm=" + algorithm + "]";
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return "JWEAlgorithmEmbed [algorithm=" + algorithm + "]";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the algorithm
|
||||
*/
|
||||
@Transient
|
||||
@Transient
|
||||
public JWEAlgorithm getAlgorithm() {
|
||||
return algorithm;
|
||||
}
|
||||
|
@ -91,5 +90,5 @@ public class JWEAlgorithmEmbed {
|
|||
public void setAlgorithm(JWEAlgorithm algorithm) {
|
||||
this.algorithm = algorithm;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ import javax.persistence.Transient;
|
|||
|
||||
import com.google.common.base.Strings;
|
||||
import com.nimbusds.jose.EncryptionMethod;
|
||||
import com.nimbusds.jose.JWEAlgorithm;
|
||||
|
||||
/**
|
||||
* @author jricher
|
||||
|
@ -19,16 +18,16 @@ import com.nimbusds.jose.JWEAlgorithm;
|
|||
public class JWEEncryptionMethodEmbed {
|
||||
|
||||
public static final JWEEncryptionMethodEmbed NONE = getForAlgorithmName("none");
|
||||
|
||||
|
||||
private EncryptionMethod algorithm;
|
||||
|
||||
public JWEEncryptionMethodEmbed() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public JWEEncryptionMethodEmbed(EncryptionMethod algorithm) {
|
||||
this.algorithm = algorithm;
|
||||
}
|
||||
this.algorithm = algorithm;
|
||||
}
|
||||
|
||||
public static JWEEncryptionMethodEmbed getForAlgorithmName (String algorithmName) {
|
||||
JWEEncryptionMethodEmbed ent = new JWEEncryptionMethodEmbed();
|
||||
|
@ -39,7 +38,7 @@ public class JWEEncryptionMethodEmbed {
|
|||
return ent;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the name of this algorithm, return null if no algorithm set.
|
||||
* @return
|
||||
|
@ -52,9 +51,9 @@ public class JWEEncryptionMethodEmbed {
|
|||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the name of this algorithm.
|
||||
* Set the name of this algorithm.
|
||||
* Calls EncryptionMethod.parse()
|
||||
* @param algorithmName
|
||||
*/
|
||||
|
@ -69,15 +68,15 @@ public class JWEEncryptionMethodEmbed {
|
|||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "JWEEncryptionMethodEmbed [algorithm=" + algorithm + "]";
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return "JWEEncryptionMethodEmbed [algorithm=" + algorithm + "]";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the algorithm
|
||||
*/
|
||||
@Transient
|
||||
@Transient
|
||||
public EncryptionMethod getAlgorithm() {
|
||||
return algorithm;
|
||||
}
|
||||
|
@ -88,6 +87,6 @@ public class JWEEncryptionMethodEmbed {
|
|||
public void setAlgorithm(EncryptionMethod algorithm) {
|
||||
this.algorithm = algorithm;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -5,8 +5,6 @@ package org.mitre.jose;
|
|||
|
||||
import javax.persistence.Basic;
|
||||
import javax.persistence.Embeddable;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Transient;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
|
@ -23,17 +21,17 @@ import com.nimbusds.jose.JWSAlgorithm;
|
|||
public class JWSAlgorithmEmbed {
|
||||
|
||||
public static final JWSAlgorithmEmbed NONE = getForAlgorithmName("none");
|
||||
|
||||
|
||||
private JWSAlgorithm algorithm;
|
||||
|
||||
public JWSAlgorithmEmbed() {
|
||||
|
||||
|
||||
public JWSAlgorithmEmbed() {
|
||||
|
||||
}
|
||||
|
||||
public JWSAlgorithmEmbed(JWSAlgorithm algorithm) {
|
||||
this.algorithm = algorithm;
|
||||
}
|
||||
|
||||
this.algorithm = algorithm;
|
||||
}
|
||||
|
||||
public static JWSAlgorithmEmbed getForAlgorithmName (String algorithmName) {
|
||||
JWSAlgorithmEmbed ent = new JWSAlgorithmEmbed();
|
||||
ent.setAlgorithmName(algorithmName);
|
||||
|
@ -56,9 +54,9 @@ public class JWSAlgorithmEmbed {
|
|||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the name of this algorithm.
|
||||
* Set the name of this algorithm.
|
||||
* Calls JWSAlgorithm.parse()
|
||||
* @param algorithmName
|
||||
*/
|
||||
|
@ -88,11 +86,11 @@ public class JWSAlgorithmEmbed {
|
|||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "JWSAlgorithmEmbed [algorithm=" + algorithm + "]";
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return "JWSAlgorithmEmbed [algorithm=" + algorithm + "]";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -21,26 +21,26 @@ import com.nimbusds.jose.jwk.JWKSet;
|
|||
public class JWKSetKeyStore implements InitializingBean {
|
||||
|
||||
private JWKSet jwkSet;
|
||||
|
||||
|
||||
private Resource location;
|
||||
|
||||
|
||||
public JWKSetKeyStore() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public JWKSetKeyStore(JWKSet jwkSet) {
|
||||
this.jwkSet = jwkSet;
|
||||
}
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
|
||||
*/
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
|
||||
|
||||
if (jwkSet == null) {
|
||||
if (location != null) {
|
||||
|
||||
|
||||
if (location.exists() && location.isReadable()) {
|
||||
|
||||
// read in the file from disk
|
||||
|
@ -48,11 +48,11 @@ public class JWKSetKeyStore implements InitializingBean {
|
|||
|
||||
// parse it into a jwkSet object
|
||||
jwkSet = JWKSet.parse(s);
|
||||
|
||||
|
||||
} else {
|
||||
throw new IllegalArgumentException("Key Set resource could not be read: " + location);
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
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
|
||||
*/
|
||||
public List<JWK> getKeys() {
|
||||
return jwkSet.getKeys();
|
||||
}
|
||||
|
||||
|
||||
public List<JWK> getKeys() {
|
||||
return jwkSet.getKeys();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
package org.mitre.jwt.signer.service;
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PublicKey;
|
||||
import java.util.Map;
|
||||
|
||||
import com.nimbusds.jose.JWSAlgorithm;
|
||||
|
@ -29,7 +28,7 @@ public interface JwtSigningAndValidationService {
|
|||
* Get all public keys for this service, mapped by their Key ID
|
||||
*/
|
||||
public Map<String, JWK> getAllPublicKeys();
|
||||
|
||||
|
||||
/**
|
||||
* Checks the signature of the given JWT against all configured signers,
|
||||
* returns true if at least one of the signers validates it.
|
||||
|
@ -37,17 +36,17 @@ public interface JwtSigningAndValidationService {
|
|||
* @param jwtString
|
||||
* the string representation of the JWT as sent on the wire
|
||||
* @return true if the signature is valid, false if not
|
||||
* @throws NoSuchAlgorithmException
|
||||
* @throws NoSuchAlgorithmException
|
||||
*/
|
||||
public boolean validateSignature(SignedJWT jwtString);
|
||||
|
||||
|
||||
/**
|
||||
* Called to sign a jwt in place for a client that hasn't registered a preferred signing algorithm.
|
||||
* Use the default algorithm to sign.
|
||||
*
|
||||
* @param jwt the jwt to sign
|
||||
* @return the signed jwt
|
||||
* @throws NoSuchAlgorithmException
|
||||
* @throws NoSuchAlgorithmException
|
||||
*/
|
||||
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.
|
||||
* @return
|
||||
*/
|
||||
public JWSAlgorithm getDefaultSigningAlgorithm();
|
||||
public JWSAlgorithm getDefaultSigningAlgorithm();
|
||||
|
||||
/**
|
||||
* 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
|
||||
//public Jwt signJwt(Jwt jwt, String alg);
|
||||
|
||||
|
||||
/**
|
||||
* TODO: method to sign a jwt using a specified algorithm and a key id
|
||||
*/
|
||||
|
|
|
@ -52,9 +52,9 @@ public class DefaultJwtSigningAndValidationService implements JwtSigningAndValid
|
|||
private static Logger logger = LoggerFactory.getLogger(DefaultJwtSigningAndValidationService.class);
|
||||
|
||||
private String defaultSignerKeyId;
|
||||
|
||||
|
||||
private JWSAlgorithm defaultAlgorithm;
|
||||
|
||||
|
||||
// map of identifier to key
|
||||
private Map<String, JWK> keys = new HashMap<String, JWK>();
|
||||
|
||||
|
@ -70,10 +70,10 @@ public class DefaultJwtSigningAndValidationService implements JwtSigningAndValid
|
|||
* @throws NoSuchAlgorithmException
|
||||
* If there is no appropriate algorithm to tie the keys to.
|
||||
*/
|
||||
public DefaultJwtSigningAndValidationService(Map<String, JWK> keys) throws NoSuchAlgorithmException, InvalidKeySpecException {
|
||||
this.keys = keys;
|
||||
buildSignersAndVerifiers();
|
||||
}
|
||||
public DefaultJwtSigningAndValidationService(Map<String, JWK> keys) throws NoSuchAlgorithmException, InvalidKeySpecException {
|
||||
this.keys = keys;
|
||||
buildSignersAndVerifiers();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* If there is no appropriate algorithm to tie the keys to.
|
||||
*/
|
||||
public DefaultJwtSigningAndValidationService(JWKSetKeyStore keyStore) throws NoSuchAlgorithmException, InvalidKeySpecException {
|
||||
// convert all keys in the keystore to a map based on key id
|
||||
for (JWK key : keyStore.getKeys()) {
|
||||
if (!Strings.isNullOrEmpty(key.getKeyID())) {
|
||||
this.keys.put(key.getKeyID(), key);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Tried to load a key from a keystore without a 'kid' field: " + key);
|
||||
}
|
||||
}
|
||||
buildSignersAndVerifiers();
|
||||
}
|
||||
|
||||
public DefaultJwtSigningAndValidationService(JWKSetKeyStore keyStore) throws NoSuchAlgorithmException, InvalidKeySpecException {
|
||||
// convert all keys in the keystore to a map based on key id
|
||||
for (JWK key : keyStore.getKeys()) {
|
||||
if (!Strings.isNullOrEmpty(key.getKeyID())) {
|
||||
this.keys.put(key.getKeyID(), key);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Tried to load a key from a keystore without a 'kid' field: " + key);
|
||||
}
|
||||
}
|
||||
buildSignersAndVerifiers();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the defaultSignerKeyId
|
||||
*/
|
||||
|
@ -117,22 +117,22 @@ public class DefaultJwtSigningAndValidationService implements JwtSigningAndValid
|
|||
* @return
|
||||
*/
|
||||
@Override
|
||||
public JWSAlgorithm getDefaultSigningAlgorithm() {
|
||||
return defaultAlgorithm;
|
||||
}
|
||||
|
||||
public void setDefaultSigningAlgorithmName(String algName) {
|
||||
defaultAlgorithm = JWSAlgorithm.parse(algName);
|
||||
}
|
||||
|
||||
public String getDefaultSigningAlgorithmName() {
|
||||
if (defaultAlgorithm != null) {
|
||||
return defaultAlgorithm.getName();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public JWSAlgorithm getDefaultSigningAlgorithm() {
|
||||
return defaultAlgorithm;
|
||||
}
|
||||
|
||||
public void setDefaultSigningAlgorithmName(String algName) {
|
||||
defaultAlgorithm = JWSAlgorithm.parse(algName);
|
||||
}
|
||||
|
||||
public String getDefaultSigningAlgorithmName() {
|
||||
if (defaultAlgorithm != null) {
|
||||
return defaultAlgorithm.getName();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
|
@ -145,9 +145,9 @@ public class DefaultJwtSigningAndValidationService implements JwtSigningAndValid
|
|||
if (keys == null) {
|
||||
throw new IllegalArgumentException("Signing and validation service must have at least one key configured.");
|
||||
}
|
||||
|
||||
|
||||
buildSignersAndVerifiers();
|
||||
|
||||
|
||||
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 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()) {
|
||||
|
||||
String id = jwkEntry.getKey();
|
||||
JWK jwk = jwkEntry.getValue();
|
||||
|
||||
if (jwk instanceof RSAKey) {
|
||||
// build RSA signers & verifiers
|
||||
|
||||
if (jwk.isPrivate()) { // only add the signer if there's a private key
|
||||
RSASSASigner signer = new RSASSASigner(((RSAKey) jwk).toRSAPrivateKey());
|
||||
signers.put(id, signer);
|
||||
}
|
||||
|
||||
RSASSAVerifier verifier = new RSASSAVerifier(((RSAKey) jwk).toRSAPublicKey());
|
||||
verifiers.put(id, verifier);
|
||||
|
||||
} else if (jwk instanceof ECKey) {
|
||||
// build EC signers & verifiers
|
||||
|
||||
// TODO: add support for EC keys
|
||||
logger.warn("EC Keys are not yet supported.");
|
||||
|
||||
} else if (jwk instanceof OctetSequenceKey) {
|
||||
// build HMAC signers & verifiers
|
||||
|
||||
if (jwk.isPrivate()) { // technically redundant check because all HMAC keys are private
|
||||
MACSigner signer = new MACSigner(((OctetSequenceKey) jwk).toByteArray());
|
||||
signers.put(id, signer);
|
||||
}
|
||||
|
||||
MACVerifier verifier = new MACVerifier(((OctetSequenceKey) jwk).toByteArray());
|
||||
verifiers.put(id, verifier);
|
||||
|
||||
} else {
|
||||
logger.warn("Unknown key type: " + jwk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (jwk instanceof RSAKey) {
|
||||
// build RSA signers & verifiers
|
||||
|
||||
if (jwk.isPrivate()) { // only add the signer if there's a private key
|
||||
RSASSASigner signer = new RSASSASigner(((RSAKey) jwk).toRSAPrivateKey());
|
||||
signers.put(id, signer);
|
||||
}
|
||||
|
||||
RSASSAVerifier verifier = new RSASSAVerifier(((RSAKey) jwk).toRSAPublicKey());
|
||||
verifiers.put(id, verifier);
|
||||
|
||||
} else if (jwk instanceof ECKey) {
|
||||
// build EC signers & verifiers
|
||||
|
||||
// TODO: add support for EC keys
|
||||
logger.warn("EC Keys are not yet supported.");
|
||||
|
||||
} else if (jwk instanceof OctetSequenceKey) {
|
||||
// build HMAC signers & verifiers
|
||||
|
||||
if (jwk.isPrivate()) { // technically redundant check because all HMAC keys are private
|
||||
MACSigner signer = new MACSigner(((OctetSequenceKey) jwk).toByteArray());
|
||||
signers.put(id, signer);
|
||||
}
|
||||
|
||||
MACVerifier verifier = new MACVerifier(((OctetSequenceKey) jwk).toByteArray());
|
||||
verifiers.put(id, verifier);
|
||||
|
||||
} else {
|
||||
logger.warn("Unknown key type: " + jwk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sign a jwt in place using the configured default signer.
|
||||
|
@ -204,18 +204,18 @@ public class DefaultJwtSigningAndValidationService implements JwtSigningAndValid
|
|||
if (getDefaultSignerKeyId() == null) {
|
||||
throw new IllegalStateException("Tried to call default signing with no default signer ID set");
|
||||
}
|
||||
|
||||
|
||||
JWSSigner signer = signers.get(getDefaultSignerKeyId());
|
||||
|
||||
try {
|
||||
jwt.sign(signer);
|
||||
} catch (JOSEException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
jwt.sign(signer);
|
||||
} catch (JOSEException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean validateSignature(SignedJWT jwt) {
|
||||
|
||||
|
@ -225,9 +225,9 @@ public class DefaultJwtSigningAndValidationService implements JwtSigningAndValid
|
|||
return true;
|
||||
}
|
||||
} catch (JOSEException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -235,17 +235,17 @@ public class DefaultJwtSigningAndValidationService implements JwtSigningAndValid
|
|||
@Override
|
||||
public Map<String, JWK> getAllPublicKeys() {
|
||||
Map<String, JWK> pubKeys = new HashMap<String, JWK>();
|
||||
|
||||
|
||||
// pull all keys out of the verifiers if we know how
|
||||
for (String keyId : keys.keySet()) {
|
||||
JWK key = keys.get(keyId);
|
||||
JWK pub = key.toPublicJWK();
|
||||
if (pub != null) {
|
||||
pubKeys.put(keyId, pub);
|
||||
}
|
||||
}
|
||||
|
||||
JWK key = keys.get(keyId);
|
||||
JWK pub = key.toPublicJWK();
|
||||
if (pub != null) {
|
||||
pubKeys.put(keyId, pub);
|
||||
}
|
||||
}
|
||||
|
||||
return pubKeys;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -3,12 +3,6 @@
|
|||
*/
|
||||
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 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.CacheBuilder;
|
||||
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.KeyType;
|
||||
import com.nimbusds.jose.jwk.RSAKey;
|
||||
|
||||
/**
|
||||
*
|
||||
* Creates a
|
||||
* Creates a
|
||||
*
|
||||
* @author jricher
|
||||
*
|
||||
|
@ -46,49 +35,49 @@ public class JWKSetSigningAndValidationServiceCacheService {
|
|||
.maximumSize(100)
|
||||
.build(new JWKSetVerifierFetcher());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* @return
|
||||
* @throws ExecutionException
|
||||
* @see com.google.common.cache.Cache#get(java.lang.Object)
|
||||
*/
|
||||
public JwtSigningAndValidationService get(String key) {
|
||||
try {
|
||||
return cache.get(key);
|
||||
} catch (ExecutionException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
public JwtSigningAndValidationService get(String key) {
|
||||
try {
|
||||
return cache.get(key);
|
||||
} catch (ExecutionException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @author jricher
|
||||
*
|
||||
*/
|
||||
private class JWKSetVerifierFetcher extends CacheLoader<String, JwtSigningAndValidationService> {
|
||||
private HttpClient httpClient = new DefaultHttpClient();
|
||||
private HttpComponentsClientHttpRequestFactory httpFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
|
||||
private RestTemplate restTemplate = new RestTemplate(httpFactory);
|
||||
|
||||
/**
|
||||
* Load the JWK Set and build the appropriate signing service.
|
||||
*/
|
||||
@Override
|
||||
public JwtSigningAndValidationService load(String key) throws Exception {
|
||||
* @author jricher
|
||||
*
|
||||
*/
|
||||
private class JWKSetVerifierFetcher extends CacheLoader<String, JwtSigningAndValidationService> {
|
||||
private HttpClient httpClient = new DefaultHttpClient();
|
||||
private HttpComponentsClientHttpRequestFactory httpFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
|
||||
private RestTemplate restTemplate = new RestTemplate(httpFactory);
|
||||
|
||||
String jsonString = restTemplate.getForObject(key, String.class);
|
||||
JWKSet jwkSet = JWKSet.parse(jsonString);
|
||||
|
||||
JWKSetKeyStore keyStore = new JWKSetKeyStore(jwkSet);
|
||||
|
||||
JwtSigningAndValidationService service = new DefaultJwtSigningAndValidationService(keyStore);
|
||||
/**
|
||||
* Load the JWK Set and build the appropriate signing service.
|
||||
*/
|
||||
@Override
|
||||
public JwtSigningAndValidationService load(String key) throws Exception {
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -22,13 +22,13 @@ import org.springframework.security.oauth2.provider.OAuth2Authentication;
|
|||
public class AuthenticationHolderEntity {
|
||||
|
||||
private Long id;
|
||||
|
||||
|
||||
private Long ownerId;
|
||||
|
||||
|
||||
private OAuth2Authentication authentication;
|
||||
|
||||
|
||||
public AuthenticationHolderEntity() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Id
|
||||
|
@ -60,7 +60,7 @@ public class AuthenticationHolderEntity {
|
|||
public void setAuthentication(OAuth2Authentication authentication) {
|
||||
this.authentication = authentication;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -28,18 +28,18 @@ import org.springframework.security.oauth2.provider.OAuth2Authentication;
|
|||
public class AuthorizationCodeEntity {
|
||||
|
||||
private Long id;
|
||||
|
||||
|
||||
private String code;
|
||||
|
||||
|
||||
private OAuth2Authentication authentication;
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
public AuthorizationCodeEntity() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a new AuthorizationCodeEntity with the given code and AuthorizationRequestHolder.
|
||||
*
|
||||
|
@ -50,12 +50,12 @@ public class AuthorizationCodeEntity {
|
|||
this.code = code;
|
||||
this.authentication = authRequest;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the id
|
||||
*/
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
@ -98,5 +98,5 @@ public class AuthorizationCodeEntity {
|
|||
public void setAuthentication(OAuth2Authentication authentication) {
|
||||
this.authentication = authentication;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -67,7 +67,7 @@ public class ClientDetailsEntity implements ClientDetails {
|
|||
private static final long serialVersionUID = -1617727085733786296L;
|
||||
|
||||
private Long id;
|
||||
|
||||
|
||||
/** Fields from the OAuth2 Dynamic Registration Specification */
|
||||
private String clientId = null; // client_id
|
||||
private String clientSecret = null; // client_secret
|
||||
|
@ -75,7 +75,7 @@ public class ClientDetailsEntity implements ClientDetails {
|
|||
private String clientName; // client_name
|
||||
private String clientUri; // client_uri
|
||||
private String logoUri; // logo_uri
|
||||
private Set<String> contacts; // contacts
|
||||
private Set<String> contacts; // contacts
|
||||
private String tosUri; // tos_uri
|
||||
private AuthMethod tokenEndpointAuthMethod = AuthMethod.SECRET_BASIC; // token_endpoint_auth_method
|
||||
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 String policyUri;
|
||||
private String jwksUri;
|
||||
|
||||
/** Fields from OIDC Client Registration Specification **/
|
||||
|
||||
/** Fields from OIDC Client Registration Specification **/
|
||||
private AppType applicationType; // application_type
|
||||
private String sectorIdentifierUri; // sector_identifier_uri
|
||||
private SubjectType subjectType; // subject_type
|
||||
|
||||
|
||||
private JWSAlgorithmEmbed requestObjectSigningAlg = JWSAlgorithmEmbed.NONE; // request_object_signing_alg
|
||||
|
||||
|
||||
private JWSAlgorithmEmbed userInfoSignedResponseAlg = JWSAlgorithmEmbed.NONE; // user_info_signed_response_alg
|
||||
private JWEAlgorithmEmbed userInfoEncryptedResponseAlg = JWEAlgorithmEmbed.NONE; // user_info_encrypted_response_alg
|
||||
private JWEEncryptionMethodEmbed userInfoEncryptedResponseEnc = JWEEncryptionMethodEmbed.NONE; // user_info_encrypted_response_enc
|
||||
|
||||
|
||||
private JWSAlgorithmEmbed idTokenSignedResponseAlg = JWSAlgorithmEmbed.NONE; // id_token_signed_response_alg
|
||||
private JWEAlgorithmEmbed idTokenEncryptedResponseAlg = JWEAlgorithmEmbed.NONE; // id_token_encrypted_response_alg
|
||||
private JWEEncryptionMethodEmbed idTokenEncryptedResponseEnc = JWEEncryptionMethodEmbed.NONE; // id_token_encrypted_response_enc
|
||||
|
||||
|
||||
private Integer defaultMaxAge; // default_max_age
|
||||
private Boolean requireAuthTime; // require_auth_time
|
||||
private Set<String> defaultACRvalues; // default_acr_values
|
||||
|
||||
|
||||
private String initiateLoginUri; // initiate_login_uri
|
||||
private String postLogoutRedirectUri; // post_logout_redirect_uri
|
||||
|
||||
|
||||
private Set<String> requestUris; // request_uris
|
||||
|
||||
|
||||
/** Fields to support the ClientDetails interface **/
|
||||
private Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
|
||||
private Integer accessTokenValiditySeconds = 0; // in seconds
|
||||
private Integer refreshTokenValiditySeconds = 0; // in seconds
|
||||
private Integer accessTokenValiditySeconds = 0; // in seconds
|
||||
private Integer refreshTokenValiditySeconds = 0; // in seconds
|
||||
private Set<String> resourceIds = new HashSet<String>();
|
||||
private Map<String, Object> additionalInformation = new HashMap<String, Object>();
|
||||
|
||||
|
||||
/** Our own fields **/
|
||||
private String clientDescription = ""; // human-readable description
|
||||
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 Integer idTokenValiditySeconds; //timeout for id tokens
|
||||
private Date createdAt; // time the client was created
|
||||
|
||||
|
||||
public enum AuthMethod {
|
||||
SECRET_POST("client_secret_post"),
|
||||
SECRET_BASIC("client_secret_basic"),
|
||||
SECRET_JWT("client_secret_jwt"),
|
||||
PRIVATE_KEY("private_key_jwt"),
|
||||
SECRET_POST("client_secret_post"),
|
||||
SECRET_BASIC("client_secret_basic"),
|
||||
SECRET_JWT("client_secret_jwt"),
|
||||
PRIVATE_KEY("private_key_jwt"),
|
||||
NONE("none");
|
||||
|
||||
|
||||
private final String value;
|
||||
|
||||
|
||||
// map to aid reverse lookup
|
||||
private static final Map<String, AuthMethod> lookup = new HashMap<String, AuthMethod>();
|
||||
static {
|
||||
|
@ -139,77 +139,77 @@ public class ClientDetailsEntity implements ClientDetails {
|
|||
lookup.put(a.getValue(), a);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
AuthMethod(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
public static AuthMethod getByValue(String value) {
|
||||
return lookup.get(value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public enum AppType {
|
||||
WEB("web"), NATIVE("native");
|
||||
|
||||
|
||||
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>();
|
||||
static {
|
||||
for (AppType a : AppType.values()) {
|
||||
lookup.put(a.getValue(), a);
|
||||
}
|
||||
lookup.put(a.getValue(), a);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
AppType(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
public static AppType getByValue(String value) {
|
||||
return lookup.get(value);
|
||||
}
|
||||
}
|
||||
|
||||
public enum SubjectType {
|
||||
PAIRWISE("pairwise"), PUBLIC("public");
|
||||
|
||||
public enum SubjectType {
|
||||
PAIRWISE("pairwise"), PUBLIC("public");
|
||||
|
||||
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>();
|
||||
static {
|
||||
for (SubjectType u : SubjectType.values()) {
|
||||
lookup.put(u.getValue(), u);
|
||||
}
|
||||
lookup.put(u.getValue(), u);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SubjectType(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
public static SubjectType getByValue(String value) {
|
||||
return lookup.get(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a blank ClientDetailsEntity
|
||||
*/
|
||||
public ClientDetailsEntity() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -228,34 +228,34 @@ public class ClientDetailsEntity implements ClientDetails {
|
|||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the clientDescription
|
||||
*/
|
||||
* @return the clientDescription
|
||||
*/
|
||||
@Basic
|
||||
@Column(name="client_description")
|
||||
public String getClientDescription() {
|
||||
return clientDescription;
|
||||
}
|
||||
public String getClientDescription() {
|
||||
return clientDescription;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param clientDescription Human-readable long description of the client (optional)
|
||||
*/
|
||||
public void setClientDescription(String clientDescription) {
|
||||
this.clientDescription = clientDescription;
|
||||
}
|
||||
* @param clientDescription Human-readable long description of the client (optional)
|
||||
*/
|
||||
public void setClientDescription(String clientDescription) {
|
||||
this.clientDescription = clientDescription;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the allowRefresh
|
||||
*/
|
||||
* @return the allowRefresh
|
||||
*/
|
||||
@Transient
|
||||
public boolean isAllowRefresh() {
|
||||
public boolean isAllowRefresh() {
|
||||
if (grantTypes != null) {
|
||||
return getAuthorizedGrantTypes().contains("refresh_token");
|
||||
} else {
|
||||
return false; // if there are no grants, we can't be refreshing them, can we?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Basic
|
||||
@Column(name="reuse_refresh_tokens")
|
||||
|
@ -266,7 +266,7 @@ public class ClientDetailsEntity implements ClientDetails {
|
|||
public void setReuseRefreshToken(boolean reuseRefreshToken) {
|
||||
this.reuseRefreshToken = reuseRefreshToken;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the idTokenValiditySeconds
|
||||
*/
|
||||
|
@ -282,7 +282,7 @@ public class ClientDetailsEntity implements ClientDetails {
|
|||
public void setIdTokenValiditySeconds(Integer idTokenValiditySeconds) {
|
||||
this.idTokenValiditySeconds = idTokenValiditySeconds;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the dynamicallyRegistered
|
||||
*/
|
||||
|
@ -298,148 +298,149 @@ public class ClientDetailsEntity implements ClientDetails {
|
|||
public void setDynamicallyRegistered(boolean dynamicallyRegistered) {
|
||||
this.dynamicallyRegistered = dynamicallyRegistered;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return the allowIntrospection
|
||||
*/
|
||||
* @return the allowIntrospection
|
||||
*/
|
||||
@Basic
|
||||
@Column(name="allow_introspection")
|
||||
public boolean isAllowIntrospection() {
|
||||
return allowIntrospection;
|
||||
}
|
||||
public boolean isAllowIntrospection() {
|
||||
return allowIntrospection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param allowIntrospection the allowIntrospection to set
|
||||
*/
|
||||
public void setAllowIntrospection(boolean allowIntrospection) {
|
||||
this.allowIntrospection = allowIntrospection;
|
||||
}
|
||||
* @param allowIntrospection the allowIntrospection to set
|
||||
*/
|
||||
public void setAllowIntrospection(boolean allowIntrospection) {
|
||||
this.allowIntrospection = allowIntrospection;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
@Transient
|
||||
public boolean isSecretRequired() {
|
||||
// TODO: this should check the auth method field instead
|
||||
return getClientSecret() != null;
|
||||
}
|
||||
*/
|
||||
@Override
|
||||
@Transient
|
||||
public boolean isSecretRequired() {
|
||||
// TODO: this should check the auth method field instead
|
||||
return getClientSecret() != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the scope list is not null or empty, then this client has been scoped.
|
||||
*/
|
||||
@Override
|
||||
@Transient
|
||||
public boolean isScoped() {
|
||||
return getScope() != null && !getScope().isEmpty();
|
||||
}
|
||||
|
||||
*/
|
||||
@Override
|
||||
@Transient
|
||||
public boolean isScoped() {
|
||||
return getScope() != null && !getScope().isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the clientId
|
||||
*/
|
||||
* @return the clientId
|
||||
*/
|
||||
@Basic
|
||||
@Override
|
||||
@Column(name="client_id")
|
||||
public String getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
public String getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param clientId The OAuth2 client_id, must be unique to this client
|
||||
*/
|
||||
public void setClientId(String clientId) {
|
||||
this.clientId = clientId;
|
||||
}
|
||||
* @param clientId The OAuth2 client_id, must be unique to this client
|
||||
*/
|
||||
public void setClientId(String clientId) {
|
||||
this.clientId = clientId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the clientSecret
|
||||
*/
|
||||
* @return the clientSecret
|
||||
*/
|
||||
@Basic
|
||||
@Override
|
||||
@Column(name="client_secret")
|
||||
public String getClientSecret() {
|
||||
return clientSecret;
|
||||
}
|
||||
return clientSecret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param clientSecret the OAuth2 client_secret (optional)
|
||||
*/
|
||||
public void setClientSecret(String clientSecret) {
|
||||
this.clientSecret = clientSecret;
|
||||
}
|
||||
* @param clientSecret the OAuth2 client_secret (optional)
|
||||
*/
|
||||
public void setClientSecret(String clientSecret) {
|
||||
this.clientSecret = clientSecret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the scope
|
||||
*/
|
||||
* @return the scope
|
||||
*/
|
||||
@ElementCollection(fetch = FetchType.EAGER)
|
||||
@CollectionTable(
|
||||
name="client_scope",
|
||||
joinColumns=@JoinColumn(name="owner_id")
|
||||
)
|
||||
)
|
||||
@Override
|
||||
@Column(name="scope")
|
||||
public Set<String> getScope() {
|
||||
return scope;
|
||||
}
|
||||
return scope;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param scope the set of scopes allowed to be issued to this client
|
||||
*/
|
||||
public void setScope(Set<String> scope) {
|
||||
this.scope = scope;
|
||||
}
|
||||
* @param scope the set of scopes allowed to be issued to this client
|
||||
*/
|
||||
public void setScope(Set<String> scope) {
|
||||
this.scope = scope;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the authorizedGrantTypes
|
||||
*/
|
||||
* @return the authorizedGrantTypes
|
||||
*/
|
||||
@ElementCollection(fetch = FetchType.EAGER)
|
||||
@CollectionTable(
|
||||
name="client_grant_type",
|
||||
joinColumns=@JoinColumn(name="owner_id")
|
||||
)
|
||||
)
|
||||
@Column(name="grant_type")
|
||||
public Set<String> getGrantTypes() {
|
||||
return grantTypes;
|
||||
}
|
||||
return grantTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param authorizedGrantTypes the OAuth2 grant types that this client is allowed to use
|
||||
*/
|
||||
public void setGrantTypes(Set<String> grantTypes) {
|
||||
this.grantTypes = grantTypes;
|
||||
}
|
||||
* @param authorizedGrantTypes the OAuth2 grant types that this client is allowed to use
|
||||
*/
|
||||
public void setGrantTypes(Set<String> 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)
|
||||
@CollectionTable(
|
||||
name="client_authority",
|
||||
joinColumns=@JoinColumn(name="owner_id")
|
||||
)
|
||||
)
|
||||
@Override
|
||||
@Column(name="authority")
|
||||
public Set<GrantedAuthority> getAuthorities() {
|
||||
return authorities;
|
||||
}
|
||||
public Set<GrantedAuthority> getAuthorities() {
|
||||
return authorities;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param authorities the Spring Security authorities this client is given
|
||||
*/
|
||||
public void setAuthorities(Set<GrantedAuthority> authorities) {
|
||||
this.authorities = authorities;
|
||||
}
|
||||
* @param authorities the Spring Security authorities this client is given
|
||||
*/
|
||||
public void setAuthorities(Set<GrantedAuthority> authorities) {
|
||||
this.authorities = authorities;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Basic
|
||||
|
@ -447,13 +448,13 @@ public class ClientDetailsEntity implements ClientDetails {
|
|||
public Integer getAccessTokenValiditySeconds() {
|
||||
return accessTokenValiditySeconds;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param accessTokenTimeout the accessTokenTimeout to set
|
||||
*/
|
||||
public void setAccessTokenValiditySeconds(Integer accessTokenValiditySeconds) {
|
||||
this.accessTokenValiditySeconds = accessTokenValiditySeconds;
|
||||
}
|
||||
* @param accessTokenTimeout the accessTokenTimeout to set
|
||||
*/
|
||||
public void setAccessTokenValiditySeconds(Integer accessTokenValiditySeconds) {
|
||||
this.accessTokenValiditySeconds = accessTokenValiditySeconds;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Basic
|
||||
|
@ -461,64 +462,65 @@ public class ClientDetailsEntity implements ClientDetails {
|
|||
public Integer getRefreshTokenValiditySeconds() {
|
||||
return refreshTokenValiditySeconds;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param refreshTokenTimeout Lifetime of refresh tokens, in seconds (optional - leave null for no timeout)
|
||||
*/
|
||||
public void setRefreshTokenValiditySeconds(Integer refreshTokenValiditySeconds) {
|
||||
this.refreshTokenValiditySeconds = refreshTokenValiditySeconds;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the registeredRedirectUri
|
||||
*/
|
||||
@ElementCollection(fetch = FetchType.EAGER)
|
||||
* @param refreshTokenTimeout Lifetime of refresh tokens, in seconds (optional - leave null for no timeout)
|
||||
*/
|
||||
public void setRefreshTokenValiditySeconds(Integer refreshTokenValiditySeconds) {
|
||||
this.refreshTokenValiditySeconds = refreshTokenValiditySeconds;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the registeredRedirectUri
|
||||
*/
|
||||
@ElementCollection(fetch = FetchType.EAGER)
|
||||
@CollectionTable(
|
||||
name="client_redirect_uri",
|
||||
joinColumns=@JoinColumn(name="owner_id")
|
||||
)
|
||||
@Column(name="redirect_uri")
|
||||
public Set<String> getRedirectUris() {
|
||||
return redirectUris;
|
||||
}
|
||||
)
|
||||
@Column(name="redirect_uri")
|
||||
public Set<String> getRedirectUris() {
|
||||
return redirectUris;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param registeredRedirectUri the registeredRedirectUri to set
|
||||
*/
|
||||
public void setRedirectUris(Set<String> redirectUris) {
|
||||
this.redirectUris = redirectUris;
|
||||
}
|
||||
* @param registeredRedirectUri the registeredRedirectUri to set
|
||||
*/
|
||||
public void setRedirectUris(Set<String> 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)
|
||||
@CollectionTable(
|
||||
name="client_resource",
|
||||
joinColumns=@JoinColumn(name="owner_id")
|
||||
)
|
||||
)
|
||||
@Column(name="resource_id")
|
||||
public Set<String> getResourceIds() {
|
||||
return resourceIds;
|
||||
}
|
||||
public Set<String> getResourceIds() {
|
||||
return resourceIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param resourceIds the resourceIds to set
|
||||
*/
|
||||
public void setResourceIds(Set<String> resourceIds) {
|
||||
this.resourceIds = resourceIds;
|
||||
}
|
||||
* @param resourceIds the resourceIds to set
|
||||
*/
|
||||
public void setResourceIds(Set<String> resourceIds) {
|
||||
this.resourceIds = resourceIds;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This library does not make use of this field, so it is not
|
||||
* stored using our persistence layer.
|
||||
|
@ -533,7 +535,7 @@ public class ClientDetailsEntity implements ClientDetails {
|
|||
return this.additionalInformation;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
|
@ -580,7 +582,7 @@ public class ClientDetailsEntity implements ClientDetails {
|
|||
@CollectionTable(
|
||||
name="client_contact",
|
||||
joinColumns=@JoinColumn(name="owner_id")
|
||||
)
|
||||
)
|
||||
@Column(name="contact")
|
||||
public Set<String> getContacts() {
|
||||
return contacts;
|
||||
|
@ -599,7 +601,7 @@ public class ClientDetailsEntity implements ClientDetails {
|
|||
public void setLogoUri(String logoUri) {
|
||||
this.logoUri = logoUri;
|
||||
}
|
||||
|
||||
|
||||
@Basic
|
||||
@Column(name="policy_uri")
|
||||
public String getPolicyUri() {
|
||||
|
@ -611,36 +613,36 @@ public class ClientDetailsEntity implements ClientDetails {
|
|||
}
|
||||
|
||||
/**
|
||||
* @return the clientUrl
|
||||
*/
|
||||
* @return the clientUrl
|
||||
*/
|
||||
@Basic
|
||||
@Column(name="client_uri")
|
||||
public String getClientUri() {
|
||||
return clientUri;
|
||||
}
|
||||
public String getClientUri() {
|
||||
return clientUri;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param clientUrl the clientUrl to set
|
||||
*/
|
||||
public void setClientUri(String clientUri) {
|
||||
this.clientUri = clientUri;
|
||||
}
|
||||
* @param clientUrl the clientUrl to set
|
||||
*/
|
||||
public void setClientUri(String clientUri) {
|
||||
this.clientUri = clientUri;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the tosUrl
|
||||
*/
|
||||
@Basic
|
||||
@Column(name="tos_uri")
|
||||
public String getTosUri() {
|
||||
return tosUri;
|
||||
}
|
||||
* @return the tosUrl
|
||||
*/
|
||||
@Basic
|
||||
@Column(name="tos_uri")
|
||||
public String getTosUri() {
|
||||
return tosUri;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param tosUrl the tosUrl to set
|
||||
*/
|
||||
public void setTosUri(String tosUri) {
|
||||
this.tosUri = tosUri;
|
||||
}
|
||||
* @param tosUrl the tosUrl to set
|
||||
*/
|
||||
public void setTosUri(String tosUri) {
|
||||
this.tosUri = tosUri;
|
||||
}
|
||||
|
||||
@Basic
|
||||
@Column(name="jwks_uri")
|
||||
|
@ -708,7 +710,7 @@ public class ClientDetailsEntity implements ClientDetails {
|
|||
|
||||
public void setUserInfoEncryptedResponseEnc(JWEEncryptionMethodEmbed userInfoEncryptedResponseEnc) {
|
||||
this.userInfoEncryptedResponseEnc = userInfoEncryptedResponseEnc;
|
||||
}
|
||||
}
|
||||
|
||||
@Embedded
|
||||
@AttributeOverrides({
|
||||
|
@ -773,7 +775,7 @@ public class ClientDetailsEntity implements ClientDetails {
|
|||
@CollectionTable(
|
||||
name="client_response_type",
|
||||
joinColumns=@JoinColumn(name="response_type")
|
||||
)
|
||||
)
|
||||
@Column(name="response_type")
|
||||
public Set<String> getResponseTypes() {
|
||||
return responseTypes;
|
||||
|
@ -793,7 +795,7 @@ public class ClientDetailsEntity implements ClientDetails {
|
|||
@CollectionTable(
|
||||
name="client_default_acr_value",
|
||||
joinColumns=@JoinColumn(name="owner_id")
|
||||
)
|
||||
)
|
||||
@Column(name="default_acr_value")
|
||||
public Set<String> getDefaultACRvalues() {
|
||||
return defaultACRvalues;
|
||||
|
@ -845,7 +847,7 @@ public class ClientDetailsEntity implements ClientDetails {
|
|||
@CollectionTable(
|
||||
name="client_request_uri",
|
||||
joinColumns=@JoinColumn(name="owner_id")
|
||||
)
|
||||
)
|
||||
@Column(name="request_uri")
|
||||
public Set<String> getRequestUris() {
|
||||
return requestUris;
|
||||
|
@ -863,15 +865,15 @@ public class ClientDetailsEntity implements ClientDetails {
|
|||
*/
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
@Column(name="created_at")
|
||||
public Date getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
public Date getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param createdAt the createdAt to set
|
||||
*/
|
||||
public void setCreatedAt(Date createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
public void setCreatedAt(Date createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -71,17 +71,17 @@ public class OAuth2AccessTokenEntity implements OAuth2AccessToken {
|
|||
public static final String REGISTRATION_TOKEN_SCOPE = "registration-token";
|
||||
|
||||
public static String ID_TOKEN = "id_token";
|
||||
|
||||
|
||||
private Long id;
|
||||
|
||||
|
||||
private ClientDetailsEntity client;
|
||||
|
||||
|
||||
private AuthenticationHolderEntity authenticationHolder; // the authentication that made this access
|
||||
|
||||
|
||||
private JWT jwtValue; // JWT-encoded access token value
|
||||
|
||||
|
||||
private OAuth2AccessTokenEntity idToken; // JWT-encoded OpenID Connect IdToken
|
||||
|
||||
|
||||
private Date expiration;
|
||||
|
||||
private String tokenType = OAuth2AccessToken.BEARER_TYPE;
|
||||
|
@ -89,14 +89,14 @@ public class OAuth2AccessTokenEntity implements OAuth2AccessToken {
|
|||
private OAuth2RefreshTokenEntity refreshToken;
|
||||
|
||||
private Set<String> scope;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new, blank access token
|
||||
*/
|
||||
public OAuth2AccessTokenEntity() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @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
|
||||
public Map<String, Object> getAdditionalInformation() {
|
||||
Map<String, Object> map = new HashMap<String, Object>(); //super.getAdditionalInformation();
|
||||
|
@ -124,121 +125,127 @@ public class OAuth2AccessTokenEntity implements OAuth2AccessToken {
|
|||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The authentication in place when this token was created.
|
||||
* @return the authentication
|
||||
*/
|
||||
* @return the authentication
|
||||
*/
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "auth_holder_id")
|
||||
public AuthenticationHolderEntity getAuthenticationHolder() {
|
||||
return authenticationHolder;
|
||||
}
|
||||
public AuthenticationHolderEntity getAuthenticationHolder() {
|
||||
return authenticationHolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param authentication the authentication to set
|
||||
*/
|
||||
public void setAuthenticationHolder(AuthenticationHolderEntity authenticationHolder) {
|
||||
this.authenticationHolder = authenticationHolder;
|
||||
}
|
||||
* @param authentication the authentication to set
|
||||
*/
|
||||
public void setAuthenticationHolder(AuthenticationHolderEntity authenticationHolder) {
|
||||
this.authenticationHolder = authenticationHolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the client
|
||||
*/
|
||||
* @return the client
|
||||
*/
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "client_id")
|
||||
public ClientDetailsEntity getClient() {
|
||||
return client;
|
||||
}
|
||||
public ClientDetailsEntity getClient() {
|
||||
return client;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param client the client to set
|
||||
*/
|
||||
public void setClient(ClientDetailsEntity client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the string-encoded value of this access token.
|
||||
*/
|
||||
@Basic
|
||||
@Column(name="token_value")
|
||||
public String getValue() {
|
||||
* @param client the client to set
|
||||
*/
|
||||
public void setClient(ClientDetailsEntity client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the string-encoded value of this access token.
|
||||
*/
|
||||
@Override
|
||||
@Basic
|
||||
@Column(name="token_value")
|
||||
public String getValue() {
|
||||
return jwtValue.serialize();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the "value" of this Access Token
|
||||
*
|
||||
* @param value the JWT string
|
||||
* @throws ParseException if "value" is not a properly formatted JWT string
|
||||
*/
|
||||
public void setValue(String value) throws ParseException {
|
||||
/**
|
||||
* Set the "value" of this Access Token
|
||||
*
|
||||
* @param value the JWT string
|
||||
* @throws ParseException if "value" is not a properly formatted JWT string
|
||||
*/
|
||||
public void setValue(String value) throws ParseException {
|
||||
setJwt(JWTParser.parse(value));
|
||||
}
|
||||
}
|
||||
|
||||
@Basic
|
||||
@Temporal(javax.persistence.TemporalType.TIMESTAMP)
|
||||
public Date getExpiration() {
|
||||
return expiration;
|
||||
}
|
||||
@Override
|
||||
@Basic
|
||||
@Temporal(javax.persistence.TemporalType.TIMESTAMP)
|
||||
public Date getExpiration() {
|
||||
return expiration;
|
||||
}
|
||||
|
||||
public void setExpiration(Date expiration) {
|
||||
this.expiration = expiration;
|
||||
}
|
||||
public void setExpiration(Date expiration) {
|
||||
this.expiration = expiration;
|
||||
}
|
||||
|
||||
@Basic
|
||||
@Column(name="token_type")
|
||||
public String getTokenType() {
|
||||
return tokenType;
|
||||
}
|
||||
@Override
|
||||
@Basic
|
||||
@Column(name="token_type")
|
||||
public String getTokenType() {
|
||||
return tokenType;
|
||||
}
|
||||
|
||||
public void setTokenType(String tokenType) {
|
||||
this.tokenType = tokenType;
|
||||
}
|
||||
public void setTokenType(String tokenType) {
|
||||
this.tokenType = tokenType;
|
||||
}
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name="refresh_token_id")
|
||||
public OAuth2RefreshTokenEntity getRefreshToken() {
|
||||
return refreshToken;
|
||||
}
|
||||
@Override
|
||||
@ManyToOne
|
||||
@JoinColumn(name="refresh_token_id")
|
||||
public OAuth2RefreshTokenEntity getRefreshToken() {
|
||||
return refreshToken;
|
||||
}
|
||||
|
||||
public void setRefreshToken(OAuth2RefreshTokenEntity refreshToken) {
|
||||
this.refreshToken = refreshToken;
|
||||
}
|
||||
public void setRefreshToken(OAuth2RefreshTokenEntity refreshToken) {
|
||||
this.refreshToken = refreshToken;
|
||||
}
|
||||
|
||||
public void setRefreshToken(OAuth2RefreshToken refreshToken) {
|
||||
if (!(refreshToken instanceof OAuth2RefreshTokenEntity)) {
|
||||
// TODO: make a copy constructor instead....
|
||||
throw new IllegalArgumentException("Not a storable refresh token entity!");
|
||||
}
|
||||
// force a pass through to the entity version
|
||||
setRefreshToken((OAuth2RefreshTokenEntity)refreshToken);
|
||||
}
|
||||
|
||||
@ElementCollection(fetch=FetchType.EAGER)
|
||||
@CollectionTable(
|
||||
joinColumns=@JoinColumn(name="owner_id"),
|
||||
name="token_scope"
|
||||
)
|
||||
public Set<String> getScope() {
|
||||
return scope;
|
||||
}
|
||||
public void setRefreshToken(OAuth2RefreshToken refreshToken) {
|
||||
if (!(refreshToken instanceof OAuth2RefreshTokenEntity)) {
|
||||
// TODO: make a copy constructor instead....
|
||||
throw new IllegalArgumentException("Not a storable refresh token entity!");
|
||||
}
|
||||
// force a pass through to the entity version
|
||||
setRefreshToken((OAuth2RefreshTokenEntity)refreshToken);
|
||||
}
|
||||
|
||||
public void setScope(Set<String> scope) {
|
||||
this.scope = scope;
|
||||
}
|
||||
@Override
|
||||
@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() {
|
||||
return getExpiration() == null ? false : System.currentTimeMillis() > getExpiration().getTime();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the idToken
|
||||
*/
|
||||
@OneToOne(cascade=CascadeType.ALL) // one-to-one mapping for now
|
||||
@JoinColumn(name = "id_token_id")
|
||||
@OneToOne(cascade=CascadeType.ALL) // one-to-one mapping for now
|
||||
@JoinColumn(name = "id_token_id")
|
||||
public OAuth2AccessTokenEntity getIdToken() {
|
||||
return idToken;
|
||||
}
|
||||
|
@ -249,7 +256,7 @@ public class OAuth2AccessTokenEntity implements OAuth2AccessToken {
|
|||
public void setIdToken(OAuth2AccessTokenEntity idToken) {
|
||||
this.idToken = idToken;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the idTokenString
|
||||
*/
|
||||
|
|
|
@ -39,9 +39,7 @@ import javax.persistence.Transient;
|
|||
import org.springframework.security.oauth2.common.OAuth2RefreshToken;
|
||||
|
||||
import com.nimbusds.jwt.JWT;
|
||||
import com.nimbusds.jwt.JWTClaimsSet;
|
||||
import com.nimbusds.jwt.JWTParser;
|
||||
import com.nimbusds.jwt.PlainJWT;
|
||||
|
||||
/**
|
||||
* @author jricher
|
||||
|
@ -58,14 +56,14 @@ import com.nimbusds.jwt.PlainJWT;
|
|||
public class OAuth2RefreshTokenEntity implements OAuth2RefreshToken {
|
||||
|
||||
private Long id;
|
||||
|
||||
|
||||
private AuthenticationHolderEntity authenticationHolder;
|
||||
|
||||
|
||||
private ClientDetailsEntity client;
|
||||
|
||||
//JWT-encoded representation of this access token entity
|
||||
private JWT jwt;
|
||||
|
||||
|
||||
// our refresh tokens might expire
|
||||
private Date expiration;
|
||||
|
||||
|
@ -91,97 +89,98 @@ public class OAuth2RefreshTokenEntity implements OAuth2RefreshToken {
|
|||
public void setId(Long 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
|
||||
*/
|
||||
public void setAuthenticationHolder(AuthenticationHolderEntity authenticationHolder) {
|
||||
this.authenticationHolder = authenticationHolder;
|
||||
}
|
||||
* 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
|
||||
*/
|
||||
public void setAuthenticationHolder(AuthenticationHolderEntity authenticationHolder) {
|
||||
this.authenticationHolder = authenticationHolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the JWT-encoded value of this token
|
||||
*/
|
||||
@Basic
|
||||
@Column(name="token_value")
|
||||
public String getValue() {
|
||||
return jwt.serialize();
|
||||
}
|
||||
@Override
|
||||
@Basic
|
||||
@Column(name="token_value")
|
||||
public String getValue() {
|
||||
return jwt.serialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of this token as a string. Parses the string into a JWT.
|
||||
* @param value
|
||||
* @throws ParseException if the value is not a valid JWT string
|
||||
*/
|
||||
public void setValue(String value) throws ParseException {
|
||||
setJwt(JWTParser.parse(value));
|
||||
}
|
||||
/**
|
||||
* Set the value of this token as a string. Parses the string into a JWT.
|
||||
* @param value
|
||||
* @throws ParseException if the value is not a valid JWT string
|
||||
*/
|
||||
public void setValue(String value) throws ParseException {
|
||||
setJwt(JWTParser.parse(value));
|
||||
}
|
||||
|
||||
@Basic
|
||||
@Temporal(javax.persistence.TemporalType.TIMESTAMP)
|
||||
public Date getExpiration() {
|
||||
return expiration;
|
||||
}
|
||||
@Basic
|
||||
@Temporal(javax.persistence.TemporalType.TIMESTAMP)
|
||||
public Date getExpiration() {
|
||||
return expiration;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.security.oauth2.common.ExpiringOAuth2RefreshToken#setExpiration(java.util.Date)
|
||||
*/
|
||||
|
||||
public void setExpiration(Date expiration) {
|
||||
this.expiration = expiration;
|
||||
}
|
||||
* @see org.springframework.security.oauth2.common.ExpiringOAuth2RefreshToken#setExpiration(java.util.Date)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Has this token expired?
|
||||
* @return true if it has a timeout set and the timeout has passed
|
||||
*/
|
||||
@Transient
|
||||
public void setExpiration(Date expiration) {
|
||||
this.expiration = expiration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Has this token expired?
|
||||
* @return true if it has a timeout set and the timeout has passed
|
||||
*/
|
||||
@Transient
|
||||
public boolean isExpired() {
|
||||
return getExpiration() == null ? false : System.currentTimeMillis() > getExpiration().getTime();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the client
|
||||
*/
|
||||
* @return the client
|
||||
*/
|
||||
@ManyToOne(fetch = FetchType.EAGER)
|
||||
@JoinColumn(name = "client_id")
|
||||
public ClientDetailsEntity getClient() {
|
||||
return client;
|
||||
}
|
||||
public ClientDetailsEntity getClient() {
|
||||
return client;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param client the client to set
|
||||
*/
|
||||
public void setClient(ClientDetailsEntity client) {
|
||||
this.client = client;
|
||||
}
|
||||
* @param client the client to set
|
||||
*/
|
||||
public void setClient(ClientDetailsEntity 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ public class SystemScope {
|
|||
private Long id;
|
||||
private String value; // scope value
|
||||
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 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
|
||||
*/
|
||||
public SystemScope() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Make a system scope with the given scope value
|
||||
* @param value
|
||||
*/
|
||||
public SystemScope(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
public SystemScope(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
/**
|
||||
* @return the id
|
||||
*/
|
||||
|
@ -117,7 +117,7 @@ public class SystemScope {
|
|||
public void setAllowDynReg(boolean allowDynReg) {
|
||||
this.allowDynReg = allowDynReg;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the defaultScope
|
||||
*/
|
||||
|
@ -136,71 +136,71 @@ public class SystemScope {
|
|||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + (allowDynReg ? 1231 : 1237);
|
||||
result = prime * result + (defaultScope ? 1231 : 1237);
|
||||
result = prime * result + ((description == null) ? 0 : description.hashCode());
|
||||
result = prime * result + ((icon == null) ? 0 : icon.hashCode());
|
||||
result = prime * result + ((id == null) ? 0 : id.hashCode());
|
||||
result = prime * result + ((value == null) ? 0 : value.hashCode());
|
||||
return result;
|
||||
}
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + (allowDynReg ? 1231 : 1237);
|
||||
result = prime * result + (defaultScope ? 1231 : 1237);
|
||||
result = prime * result + ((description == null) ? 0 : description.hashCode());
|
||||
result = prime * result + ((icon == null) ? 0 : icon.hashCode());
|
||||
result = prime * result + ((id == null) ? 0 : id.hashCode());
|
||||
result = prime * result + ((value == null) ? 0 : value.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
SystemScope other = (SystemScope) obj;
|
||||
if (allowDynReg != other.allowDynReg) {
|
||||
return false;
|
||||
}
|
||||
if (defaultScope != other.defaultScope) {
|
||||
return false;
|
||||
}
|
||||
if (description == null) {
|
||||
if (other.description != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!description.equals(other.description)) {
|
||||
return false;
|
||||
}
|
||||
if (icon == null) {
|
||||
if (other.icon != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!icon.equals(other.icon)) {
|
||||
return false;
|
||||
}
|
||||
if (id == null) {
|
||||
if (other.id != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!id.equals(other.id)) {
|
||||
return false;
|
||||
}
|
||||
if (value == null) {
|
||||
if (other.value != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!value.equals(other.value)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
SystemScope other = (SystemScope) obj;
|
||||
if (allowDynReg != other.allowDynReg) {
|
||||
return false;
|
||||
}
|
||||
if (defaultScope != other.defaultScope) {
|
||||
return false;
|
||||
}
|
||||
if (description == null) {
|
||||
if (other.description != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!description.equals(other.description)) {
|
||||
return false;
|
||||
}
|
||||
if (icon == null) {
|
||||
if (other.icon != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!icon.equals(other.icon)) {
|
||||
return false;
|
||||
}
|
||||
if (id == null) {
|
||||
if (other.id != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!id.equals(other.id)) {
|
||||
return false;
|
||||
}
|
||||
if (value == null) {
|
||||
if (other.value != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!value.equals(other.value)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -6,13 +6,13 @@ import org.springframework.security.oauth2.provider.OAuth2Authentication;
|
|||
public interface AuthenticationHolderRepository {
|
||||
|
||||
public AuthenticationHolderEntity getById(Long id);
|
||||
|
||||
|
||||
public AuthenticationHolderEntity getByAuthentication(OAuth2Authentication a);
|
||||
|
||||
|
||||
public void removeById(Long id);
|
||||
|
||||
|
||||
public void remove(AuthenticationHolderEntity a);
|
||||
|
||||
|
||||
public AuthenticationHolderEntity save(AuthenticationHolderEntity a);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import org.springframework.security.oauth2.common.exceptions.InvalidGrantExcepti
|
|||
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
|
||||
*
|
||||
|
@ -19,14 +19,14 @@ public interface AuthorizationCodeRepository {
|
|||
* @return the saved AuthorizationCodeEntity
|
||||
*/
|
||||
public AuthorizationCodeEntity save(AuthorizationCodeEntity authorizationCode);
|
||||
|
||||
|
||||
/**
|
||||
* Consume an authorization code.
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
public OAuth2Authentication consume(String code) throws InvalidGrantException;
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ import java.util.Collection;
|
|||
import org.mitre.oauth2.model.ClientDetailsEntity;
|
||||
|
||||
public interface OAuth2ClientRepository {
|
||||
|
||||
|
||||
public ClientDetailsEntity getById(Long id);
|
||||
|
||||
public ClientDetailsEntity getClientByClientId(String clientId);
|
||||
|
|
|
@ -27,17 +27,17 @@ public interface OAuth2TokenRepository {
|
|||
public OAuth2AccessTokenEntity saveAccessToken(OAuth2AccessTokenEntity token);
|
||||
|
||||
public OAuth2RefreshTokenEntity getRefreshTokenByValue(String refreshTokenValue);
|
||||
|
||||
|
||||
public OAuth2RefreshTokenEntity getRefreshTokenById(Long Id);
|
||||
|
||||
public void clearAccessTokensForRefreshToken(OAuth2RefreshTokenEntity refreshToken);
|
||||
|
||||
public void removeRefreshToken(OAuth2RefreshTokenEntity refreshToken);
|
||||
|
||||
|
||||
public OAuth2RefreshTokenEntity saveRefreshToken(OAuth2RefreshTokenEntity refreshToken);
|
||||
|
||||
public OAuth2AccessTokenEntity getAccessTokenByValue(String accessTokenValue);
|
||||
|
||||
|
||||
public OAuth2AccessTokenEntity getAccessTokenById(Long id);
|
||||
|
||||
public void removeAccessToken(OAuth2AccessTokenEntity accessToken);
|
||||
|
@ -55,8 +55,8 @@ public interface OAuth2TokenRepository {
|
|||
public OAuth2AccessTokenEntity getByAuthentication(OAuth2Authentication auth);
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public OAuth2AccessTokenEntity getAccessTokenForIdToken(OAuth2AccessTokenEntity idToken);
|
||||
|
||||
* @return
|
||||
*/
|
||||
public OAuth2AccessTokenEntity getAccessTokenForIdToken(OAuth2AccessTokenEntity idToken);
|
||||
|
||||
}
|
||||
|
|
|
@ -14,13 +14,13 @@ import org.mitre.oauth2.model.SystemScope;
|
|||
public interface SystemScopeRepository {
|
||||
|
||||
public Set<SystemScope> getAll();
|
||||
|
||||
|
||||
public SystemScope getById(Long id);
|
||||
|
||||
|
||||
public SystemScope getByValue(String value);
|
||||
|
||||
|
||||
public void remove(SystemScope scope);
|
||||
|
||||
|
||||
public SystemScope save(SystemScope scope);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -24,19 +24,20 @@ import org.springframework.security.oauth2.provider.ClientDetailsService;
|
|||
public interface ClientDetailsEntityService extends ClientDetailsService {
|
||||
|
||||
public ClientDetailsEntity saveNewClient(ClientDetailsEntity client);
|
||||
|
||||
|
||||
public ClientDetailsEntity getClientById(Long id);
|
||||
|
||||
|
||||
@Override
|
||||
public ClientDetailsEntity loadClientByClientId(String clientId) throws OAuth2Exception;
|
||||
|
||||
public void deleteClient(ClientDetailsEntity client);
|
||||
|
||||
|
||||
public ClientDetailsEntity updateClient(ClientDetailsEntity oldClient, ClientDetailsEntity newClient);
|
||||
|
||||
public Collection<ClientDetailsEntity> getAllClients();
|
||||
|
||||
public ClientDetailsEntity generateClientId(ClientDetailsEntity client);
|
||||
|
||||
|
||||
public ClientDetailsEntity generateClientSecret(ClientDetailsEntity client);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -26,32 +26,34 @@ import org.springframework.security.oauth2.provider.token.ResourceServerTokenSer
|
|||
|
||||
public interface OAuth2TokenEntityService extends AuthorizationServerTokenServices, ResourceServerTokenServices {
|
||||
|
||||
@Override
|
||||
public OAuth2AccessTokenEntity readAccessToken(String accessTokenValue);
|
||||
|
||||
|
||||
public OAuth2RefreshTokenEntity getRefreshToken(String refreshTokenValue);
|
||||
|
||||
public void revokeRefreshToken(OAuth2RefreshTokenEntity refreshToken);
|
||||
|
||||
public void revokeAccessToken(OAuth2AccessTokenEntity accessToken);
|
||||
|
||||
|
||||
public List<OAuth2AccessTokenEntity> getAccessTokensForClient(ClientDetailsEntity client);
|
||||
|
||||
|
||||
public List<OAuth2RefreshTokenEntity> getRefreshTokensForClient(ClientDetailsEntity client);
|
||||
|
||||
public void clearExpiredTokens();
|
||||
|
||||
|
||||
public OAuth2AccessTokenEntity saveAccessToken(OAuth2AccessTokenEntity accessToken);
|
||||
|
||||
|
||||
public OAuth2RefreshTokenEntity saveRefreshToken(OAuth2RefreshTokenEntity refreshToken);
|
||||
|
||||
|
||||
@Override
|
||||
public OAuth2AccessTokenEntity getAccessToken(OAuth2Authentication authentication);
|
||||
|
||||
|
||||
public OAuth2AccessTokenEntity getAccessTokenById(Long id);
|
||||
|
||||
/**
|
||||
* @param incomingToken
|
||||
* @return
|
||||
*/
|
||||
public OAuth2AccessTokenEntity getAccessTokenForIdToken(OAuth2AccessTokenEntity idToken);
|
||||
|
||||
* @param incomingToken
|
||||
* @return
|
||||
*/
|
||||
public OAuth2AccessTokenEntity getAccessTokenForIdToken(OAuth2AccessTokenEntity idToken);
|
||||
|
||||
}
|
||||
|
|
|
@ -12,15 +12,15 @@ import org.mitre.oauth2.model.SystemScope;
|
|||
*
|
||||
*/
|
||||
public interface SystemScopeService {
|
||||
|
||||
|
||||
public Set<SystemScope> getAll();
|
||||
|
||||
|
||||
/**
|
||||
* Get all scopes that are defaulted to new clients on this system
|
||||
* @return
|
||||
*/
|
||||
public Set<SystemScope> getDefaults();
|
||||
|
||||
|
||||
/**
|
||||
* Get all scopes that are allowed for dynamic registration on this system
|
||||
* @return
|
||||
|
@ -28,20 +28,20 @@ public interface SystemScopeService {
|
|||
public Set<SystemScope> getDynReg();
|
||||
|
||||
public SystemScope getById(Long id);
|
||||
|
||||
|
||||
public SystemScope getByValue(String value);
|
||||
|
||||
|
||||
public void remove(SystemScope scope);
|
||||
|
||||
|
||||
public SystemScope save(SystemScope scope);
|
||||
|
||||
|
||||
/**
|
||||
* Translate the set of scope strings into a set of SystemScope objects.
|
||||
* @param scope
|
||||
* @return
|
||||
*/
|
||||
public Set<SystemScope> fromStrings(Set<String> scope);
|
||||
|
||||
|
||||
/**
|
||||
* Pluck the scope values from the set of SystemScope objects and return a list of strings
|
||||
* @param scope
|
||||
|
|
|
@ -17,7 +17,6 @@ package org.mitre.oauth2.service.impl;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
|
@ -44,32 +43,32 @@ public class DefaultClientUserDetailsService implements UserDetailsService {
|
|||
private ClientDetailsService clientDetailsService;
|
||||
|
||||
@Override
|
||||
public UserDetails loadUserByUsername(String clientId) throws UsernameNotFoundException, DataAccessException {
|
||||
public UserDetails loadUserByUsername(String clientId) throws UsernameNotFoundException, DataAccessException {
|
||||
|
||||
ClientDetails client = clientDetailsService.loadClientByClientId(clientId);
|
||||
|
||||
|
||||
if (client != null) {
|
||||
|
||||
String password = client.getClientSecret();
|
||||
boolean enabled = true;
|
||||
boolean accountNonExpired = true;
|
||||
boolean credentialsNonExpired = true;
|
||||
boolean accountNonLocked = true;
|
||||
Collection<GrantedAuthority> authorities = client.getAuthorities();
|
||||
if (authorities == null || authorities.isEmpty()) {
|
||||
// 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
|
||||
authorities = new ArrayList<GrantedAuthority>();
|
||||
GrantedAuthority roleClient = new SimpleGrantedAuthority("ROLE_CLIENT");
|
||||
authorities.add(roleClient);
|
||||
}
|
||||
|
||||
return new User(clientId, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);
|
||||
|
||||
String password = client.getClientSecret();
|
||||
boolean enabled = true;
|
||||
boolean accountNonExpired = true;
|
||||
boolean credentialsNonExpired = true;
|
||||
boolean accountNonLocked = true;
|
||||
Collection<GrantedAuthority> authorities = client.getAuthorities();
|
||||
if (authorities == null || authorities.isEmpty()) {
|
||||
// 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
|
||||
authorities = new ArrayList<GrantedAuthority>();
|
||||
GrantedAuthority roleClient = new SimpleGrantedAuthority("ROLE_CLIENT");
|
||||
authorities.add(roleClient);
|
||||
}
|
||||
|
||||
return new User(clientId, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);
|
||||
} else {
|
||||
throw new UsernameNotFoundException("Client not found: " + clientId);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public ClientDetailsService getClientDetailsService() {
|
||||
return clientDetailsService;
|
||||
|
@ -78,5 +77,5 @@ public class DefaultClientUserDetailsService implements UserDetailsService {
|
|||
public void setClientDetailsService(ClientDetailsService clientDetailsService) {
|
||||
this.clientDetailsService = clientDetailsService;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ package org.mitre.openid.connect.config;
|
|||
/**
|
||||
* 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
|
||||
* to this bean if you need access to any configuration properties.
|
||||
* to this bean if you need access to any configuration properties.
|
||||
*
|
||||
* @author AANGANES
|
||||
*
|
||||
|
@ -28,22 +28,22 @@ package org.mitre.openid.connect.config;
|
|||
public class ConfigurationPropertiesBean {
|
||||
|
||||
private String issuer;
|
||||
|
||||
|
||||
private String topbarTitle;
|
||||
|
||||
|
||||
private String logoImageUrl;
|
||||
|
||||
|
||||
public ConfigurationPropertiesBean() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the issuer baseUrl
|
||||
*/
|
||||
public String getIssuer() {
|
||||
return issuer;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param iss the issuer to set
|
||||
*/
|
||||
|
|
|
@ -31,9 +31,9 @@ public class ServerConfiguration {
|
|||
private String tokenEndpointUri;
|
||||
|
||||
private String issuer;
|
||||
|
||||
|
||||
private String jwksUri;
|
||||
|
||||
|
||||
private String userInfoUri;
|
||||
|
||||
/**
|
||||
|
@ -105,5 +105,5 @@ public class ServerConfiguration {
|
|||
public void setUserInfoUri(String userInfoUri) {
|
||||
this.userInfoUri = userInfoUri;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -27,7 +27,7 @@ import javax.persistence.Table;
|
|||
@Table(name="address")
|
||||
public class Address {
|
||||
|
||||
|
||||
|
||||
private Long id;
|
||||
private String formatted;
|
||||
private String streetAddress;
|
||||
|
@ -35,14 +35,14 @@ public class Address {
|
|||
private String region;
|
||||
private String postalCode;
|
||||
private String country;
|
||||
|
||||
|
||||
/**
|
||||
* Empty constructor
|
||||
*/
|
||||
public Address() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the formatted address string
|
||||
*/
|
||||
|
@ -125,19 +125,19 @@ public class Address {
|
|||
}
|
||||
|
||||
/**
|
||||
* @return the id
|
||||
*/
|
||||
* @return the id
|
||||
*/
|
||||
@Id
|
||||
@GeneratedValue(strategy=GenerationType.IDENTITY)
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id the id to set
|
||||
*/
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
* @param id the id to set
|
||||
*/
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -52,164 +52,164 @@ import com.google.common.collect.Sets;
|
|||
public class ApprovedSite {
|
||||
|
||||
// unique id
|
||||
private Long id;
|
||||
|
||||
// which user made the approval
|
||||
private Long id;
|
||||
|
||||
// which user made the approval
|
||||
private String userId;
|
||||
|
||||
|
||||
// which OAuth2 client is this tied to
|
||||
private String clientId;
|
||||
|
||||
|
||||
// when was this first approved?
|
||||
private Date creationDate;
|
||||
|
||||
|
||||
// when was this last accessed?
|
||||
private Date accessDate;
|
||||
|
||||
|
||||
// if this is a time-limited access, when does it run out?
|
||||
private Date timeoutDate;
|
||||
|
||||
|
||||
// what scopes have been allowed
|
||||
// this should include all information for what data to access
|
||||
private Set<String> allowedScopes;
|
||||
|
||||
|
||||
// If this AP is a WS, link to the WS
|
||||
private WhitelistedSite whitelistedSite;
|
||||
|
||||
|
||||
//Link to any access tokens approved through this stored decision
|
||||
private Set<OAuth2AccessTokenEntity> approvedAccessTokens = Sets.newHashSet();
|
||||
|
||||
|
||||
/**
|
||||
* Empty constructor
|
||||
*/
|
||||
public ApprovedSite() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the id
|
||||
*/
|
||||
* @return the id
|
||||
*/
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id the id to set
|
||||
*/
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
* @param id the id to set
|
||||
*/
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the userInfo
|
||||
*/
|
||||
@Basic
|
||||
@Column(name="user_id")
|
||||
public String getUserId() {
|
||||
return userId;
|
||||
}
|
||||
* @return the userInfo
|
||||
*/
|
||||
@Basic
|
||||
@Column(name="user_id")
|
||||
public String getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param userInfo the userInfo to set
|
||||
*/
|
||||
public void setUserId(String userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
* @param userInfo the userInfo to set
|
||||
*/
|
||||
public void setUserId(String userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the clientId
|
||||
*/
|
||||
@Basic
|
||||
@Column(name="client_id")
|
||||
public String getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
* @return the clientId
|
||||
*/
|
||||
@Basic
|
||||
@Column(name="client_id")
|
||||
public String getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param clientId the clientId to set
|
||||
*/
|
||||
public void setClientId(String clientId) {
|
||||
this.clientId = clientId;
|
||||
}
|
||||
* @param clientId the clientId to set
|
||||
*/
|
||||
public void setClientId(String clientId) {
|
||||
this.clientId = clientId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the creationDate
|
||||
*/
|
||||
@Basic
|
||||
@Temporal(javax.persistence.TemporalType.TIMESTAMP)
|
||||
@Column(name="creation_date")
|
||||
public Date getCreationDate() {
|
||||
return creationDate;
|
||||
}
|
||||
* @return the creationDate
|
||||
*/
|
||||
@Basic
|
||||
@Temporal(javax.persistence.TemporalType.TIMESTAMP)
|
||||
@Column(name="creation_date")
|
||||
public Date getCreationDate() {
|
||||
return creationDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param creationDate the creationDate to set
|
||||
*/
|
||||
public void setCreationDate(Date creationDate) {
|
||||
this.creationDate = creationDate;
|
||||
}
|
||||
* @param creationDate the creationDate to set
|
||||
*/
|
||||
public void setCreationDate(Date creationDate) {
|
||||
this.creationDate = creationDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the accessDate
|
||||
*/
|
||||
@Basic
|
||||
@Temporal(javax.persistence.TemporalType.TIMESTAMP)
|
||||
@Column(name="access_date")
|
||||
public Date getAccessDate() {
|
||||
return accessDate;
|
||||
}
|
||||
* @return the accessDate
|
||||
*/
|
||||
@Basic
|
||||
@Temporal(javax.persistence.TemporalType.TIMESTAMP)
|
||||
@Column(name="access_date")
|
||||
public Date getAccessDate() {
|
||||
return accessDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param accessDate the accessDate to set
|
||||
*/
|
||||
public void setAccessDate(Date accessDate) {
|
||||
this.accessDate = accessDate;
|
||||
}
|
||||
* @param accessDate the accessDate to set
|
||||
*/
|
||||
public void setAccessDate(Date accessDate) {
|
||||
this.accessDate = accessDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the allowedScopes
|
||||
*/
|
||||
@ElementCollection(fetch = FetchType.EAGER)
|
||||
@CollectionTable(
|
||||
name="approved_site_scope",
|
||||
joinColumns=@JoinColumn(name="owner_id")
|
||||
)
|
||||
@Column(name="scope")
|
||||
public Set<String> getAllowedScopes() {
|
||||
return allowedScopes;
|
||||
}
|
||||
* @return the allowedScopes
|
||||
*/
|
||||
@ElementCollection(fetch = FetchType.EAGER)
|
||||
@CollectionTable(
|
||||
name="approved_site_scope",
|
||||
joinColumns=@JoinColumn(name="owner_id")
|
||||
)
|
||||
@Column(name="scope")
|
||||
public Set<String> getAllowedScopes() {
|
||||
return allowedScopes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param allowedScopes the allowedScopes to set
|
||||
*/
|
||||
public void setAllowedScopes(Set<String> allowedScopes) {
|
||||
this.allowedScopes = allowedScopes;
|
||||
}
|
||||
* @param allowedScopes the allowedScopes to set
|
||||
*/
|
||||
public void setAllowedScopes(Set<String> allowedScopes) {
|
||||
this.allowedScopes = allowedScopes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the timeoutDate
|
||||
*/
|
||||
@Basic
|
||||
@Temporal(javax.persistence.TemporalType.TIMESTAMP)
|
||||
@Column(name="timeout_date")
|
||||
public Date getTimeoutDate() {
|
||||
return timeoutDate;
|
||||
}
|
||||
* @return the timeoutDate
|
||||
*/
|
||||
@Basic
|
||||
@Temporal(javax.persistence.TemporalType.TIMESTAMP)
|
||||
@Column(name="timeout_date")
|
||||
public Date getTimeoutDate() {
|
||||
return timeoutDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param timeoutDate the timeoutDate to set
|
||||
*/
|
||||
public void setTimeoutDate(Date timeoutDate) {
|
||||
this.timeoutDate = timeoutDate;
|
||||
}
|
||||
* @param timeoutDate the timeoutDate to set
|
||||
*/
|
||||
public void setTimeoutDate(Date timeoutDate) {
|
||||
this.timeoutDate = timeoutDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this AP entry correspond to a WS?
|
||||
* @return
|
||||
*/
|
||||
@Transient
|
||||
/**
|
||||
* Does this AP entry correspond to a WS?
|
||||
* @return
|
||||
*/
|
||||
@Transient
|
||||
public Boolean getIsWhitelisted() {
|
||||
return (whitelistedSite != null);
|
||||
}
|
||||
|
@ -227,10 +227,10 @@ public class ApprovedSite {
|
|||
|
||||
/**
|
||||
* Has this approval expired?
|
||||
* @return
|
||||
*/
|
||||
* @return
|
||||
*/
|
||||
@Transient
|
||||
public boolean isExpired() {
|
||||
public boolean isExpired() {
|
||||
if (getTimeoutDate() != null) {
|
||||
Date now = new Date();
|
||||
if (now.after(getTimeoutDate())) {
|
||||
|
@ -241,7 +241,7 @@ public class ApprovedSite {
|
|||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
|
||||
@JoinColumn(name="approved_site_id")
|
||||
|
@ -255,5 +255,5 @@ public class ApprovedSite {
|
|||
public void setApprovedAccessTokens(Set<OAuth2AccessTokenEntity> approvedAccessTokens) {
|
||||
this.approvedAccessTokens = approvedAccessTokens;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -24,41 +24,41 @@ import javax.persistence.Table;
|
|||
})
|
||||
public class BlacklistedSite {
|
||||
|
||||
// unique id
|
||||
private Long id;
|
||||
|
||||
// URI pattern to black list
|
||||
private String uri;
|
||||
|
||||
public BlacklistedSite() {
|
||||
|
||||
}
|
||||
|
||||
// unique id
|
||||
private Long id;
|
||||
|
||||
// URI pattern to black list
|
||||
private String uri;
|
||||
|
||||
public BlacklistedSite() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the id
|
||||
*/
|
||||
* @return the id
|
||||
*/
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id the id to set
|
||||
*/
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
* @param id the id to set
|
||||
*/
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Basic
|
||||
@Column(name="uri")
|
||||
public String getUri() {
|
||||
return uri;
|
||||
}
|
||||
@Basic
|
||||
@Column(name="uri")
|
||||
public String getUri() {
|
||||
return uri;
|
||||
}
|
||||
|
||||
public void setUri(String uri) {
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
public void setUri(String uri) {
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -33,21 +33,21 @@ import com.google.gson.JsonObject;
|
|||
@Table(name="user_info")
|
||||
@NamedQueries({
|
||||
@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.getBySubject", query = "select u from DefaultUserInfo u WHERE u.sub = :sub")
|
||||
@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")
|
||||
})
|
||||
public class DefaultUserInfo implements UserInfo {
|
||||
|
||||
|
||||
private Long id;
|
||||
private String sub;
|
||||
private String sub;
|
||||
private String preferredUsername;
|
||||
private String name;
|
||||
private String givenName;
|
||||
private String familyName;
|
||||
private String middleName;
|
||||
private String nickname;
|
||||
private String name;
|
||||
private String givenName;
|
||||
private String familyName;
|
||||
private String middleName;
|
||||
private String nickname;
|
||||
private String profile;
|
||||
private String picture;
|
||||
private String picture;
|
||||
private String website;
|
||||
private String email;
|
||||
private Boolean emailVerified;
|
||||
|
@ -58,8 +58,8 @@ public class DefaultUserInfo implements UserInfo {
|
|||
private Address address;
|
||||
private String updatedTime;
|
||||
private String birthdate;
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return the id
|
||||
*/
|
||||
|
@ -356,21 +356,23 @@ public class DefaultUserInfo implements UserInfo {
|
|||
}
|
||||
|
||||
/**
|
||||
* @return the birthdate
|
||||
*/
|
||||
* @return the birthdate
|
||||
*/
|
||||
@Override
|
||||
@Basic
|
||||
@Column(name="birthdate")
|
||||
public String getBirthdate() {
|
||||
return birthdate;
|
||||
}
|
||||
public String getBirthdate() {
|
||||
return birthdate;
|
||||
}
|
||||
/**
|
||||
* @param birthdate the birthdate to set
|
||||
*/
|
||||
public void setBirthdate(String birthdate) {
|
||||
this.birthdate = birthdate;
|
||||
}
|
||||
* @param birthdate the birthdate to set
|
||||
*/
|
||||
@Override
|
||||
public void setBirthdate(String birthdate) {
|
||||
this.birthdate = birthdate;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Parse a JsonObject into a UserInfo.
|
||||
* @param o
|
||||
* @return
|
||||
|
@ -379,7 +381,7 @@ public class DefaultUserInfo implements UserInfo {
|
|||
DefaultUserInfo ui = new DefaultUserInfo();
|
||||
|
||||
ui.setSub(obj.has("sub") ? obj.get("sub").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.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.setUpdatedTime(obj.has("updated_time") ? obj.get("updated_time").getAsString() : null);
|
||||
ui.setBirthdate(obj.has("birthdate") ? obj.get("birthdate").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.setPhoneNumber(obj.has("phone_number") ? obj.get("phone_number").getAsString() : null);
|
||||
|
||||
|
||||
|
||||
if (obj.has("address") && obj.get("address").isJsonObject()) {
|
||||
JsonObject addr = obj.get("address").getAsJsonObject();
|
||||
ui.setAddress(new Address());
|
||||
|
||||
|
||||
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().setLocality(addr.has("locality") ? addr.get("locality").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().setCountry(addr.has("country") ? addr.get("country").getAsString() : null);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
return ui;
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -37,50 +37,50 @@ import javax.persistence.Temporal;
|
|||
public class Event {
|
||||
|
||||
public static enum EventType { LOGIN, AUTHORIZATION, ACCESS }
|
||||
|
||||
|
||||
private Long id;
|
||||
private EventType type;
|
||||
private Date timestamp;
|
||||
|
||||
/**
|
||||
* @return the id
|
||||
*/
|
||||
* @return the id
|
||||
*/
|
||||
@Id
|
||||
@GeneratedValue(strategy=GenerationType.IDENTITY)
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
/**
|
||||
* @param id the id to set
|
||||
*/
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
* @param id the id to set
|
||||
*/
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
/**
|
||||
* @return the type
|
||||
*/
|
||||
public EventType getType() {
|
||||
return type;
|
||||
}
|
||||
* @return the type
|
||||
*/
|
||||
public EventType getType() {
|
||||
return type;
|
||||
}
|
||||
/**
|
||||
* @param type the type to set
|
||||
*/
|
||||
public void setType(EventType type) {
|
||||
this.type = type;
|
||||
}
|
||||
* @param type the type to set
|
||||
*/
|
||||
public void setType(EventType type) {
|
||||
this.type = type;
|
||||
}
|
||||
/**
|
||||
* @return the timestamp
|
||||
*/
|
||||
@Basic
|
||||
@Temporal(javax.persistence.TemporalType.TIMESTAMP)
|
||||
public Date getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
* @return the timestamp
|
||||
*/
|
||||
@Basic
|
||||
@Temporal(javax.persistence.TemporalType.TIMESTAMP)
|
||||
public Date getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
/**
|
||||
* @param timestamp the timestamp to set
|
||||
*/
|
||||
public void setTimestamp(Date timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
* @param timestamp the timestamp to set
|
||||
*/
|
||||
public void setTimestamp(Date timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,16 +23,16 @@ import javax.persistence.Temporal;
|
|||
})
|
||||
public class Nonce {
|
||||
|
||||
|
||||
|
||||
private Long id; //the ID of this Nonce
|
||||
|
||||
|
||||
private String value; //the value of 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 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
|
||||
|
@ -86,7 +86,7 @@ public class Nonce {
|
|||
* @return the useDate
|
||||
*/
|
||||
@Basic
|
||||
@Temporal(javax.persistence.TemporalType.TIMESTAMP)
|
||||
@Temporal(javax.persistence.TemporalType.TIMESTAMP)
|
||||
@Column(name="use_date")
|
||||
public Date getUseDate() {
|
||||
return useDate;
|
||||
|
@ -103,7 +103,7 @@ public class Nonce {
|
|||
* @return the expireDate
|
||||
*/
|
||||
@Basic
|
||||
@Temporal(javax.persistence.TemporalType.TIMESTAMP)
|
||||
@Temporal(javax.persistence.TemporalType.TIMESTAMP)
|
||||
@Column(name="expire_date")
|
||||
public Date getExpireDate() {
|
||||
return expireDate;
|
||||
|
@ -115,8 +115,8 @@ public class Nonce {
|
|||
public void setExpireDate(Date expireDate) {
|
||||
this.expireDate = expireDate;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -12,12 +12,12 @@ public interface UserInfo {
|
|||
* @param sub the userId to set
|
||||
*/
|
||||
public abstract void setSub(String sub);
|
||||
|
||||
|
||||
/**
|
||||
* @return the preferred username
|
||||
*/
|
||||
public abstract String getPreferredUsername();
|
||||
|
||||
|
||||
/**
|
||||
* @param preferredUsername the preferredUsername to set
|
||||
*/
|
||||
|
@ -189,7 +189,7 @@ public interface UserInfo {
|
|||
* @return
|
||||
*/
|
||||
public abstract String getBirthdate();
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param birthdate
|
||||
|
|
|
@ -32,7 +32,7 @@ import javax.persistence.NamedQuery;
|
|||
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.
|
||||
* @author jricher, aanganes
|
||||
*
|
||||
|
@ -40,21 +40,21 @@ import javax.persistence.Table;
|
|||
@Entity
|
||||
@Table(name="whitelisted_site")
|
||||
@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.getByCreatoruserId", query = "select w from WhitelistedSite w where w.creatorUserId = :userId")
|
||||
})
|
||||
public class WhitelistedSite {
|
||||
|
||||
// unique id
|
||||
private Long id;
|
||||
|
||||
// Reference to the admin user who created this entry
|
||||
private Long id;
|
||||
|
||||
// Reference to the admin user who created this entry
|
||||
private String creatorUserId;
|
||||
|
||||
|
||||
// which OAuth2 client is this tied to
|
||||
private String clientId;
|
||||
|
||||
|
||||
// what scopes be allowed by default
|
||||
// this should include all information for what data to access
|
||||
private Set<String> allowedScopes;
|
||||
|
@ -63,14 +63,14 @@ public class WhitelistedSite {
|
|||
* Empty constructor
|
||||
*/
|
||||
public WhitelistedSite() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the id
|
||||
*/
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
@ -103,9 +103,9 @@ public class WhitelistedSite {
|
|||
*/
|
||||
@ElementCollection(fetch = FetchType.EAGER)
|
||||
@CollectionTable(
|
||||
name="whitelisted_site_scope",
|
||||
joinColumns=@JoinColumn(name="owner_id")
|
||||
)
|
||||
name="whitelisted_site_scope",
|
||||
joinColumns=@JoinColumn(name="owner_id")
|
||||
)
|
||||
@Column(name="scope")
|
||||
public Set<String> getAllowedScopes() {
|
||||
return allowedScopes;
|
||||
|
|
|
@ -50,7 +50,7 @@ public interface ApprovedSiteRepository {
|
|||
* @param clientId
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
*/
|
||||
public Collection<ApprovedSite> getByClientIdAndUserId(String clientId, String userId);
|
||||
|
||||
/**
|
||||
|
@ -69,14 +69,14 @@ public interface ApprovedSiteRepository {
|
|||
* @return the persisted entity
|
||||
*/
|
||||
public ApprovedSite save(ApprovedSite approvedSite);
|
||||
|
||||
|
||||
/**
|
||||
* Get all sites approved by this user
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
public Collection<ApprovedSite> getByUserId(String userId);
|
||||
|
||||
|
||||
/**
|
||||
* Get all sites associated with this client
|
||||
* @param clientId
|
||||
|
|
|
@ -14,13 +14,13 @@ import org.mitre.openid.connect.model.BlacklistedSite;
|
|||
public interface BlacklistedSiteRepository {
|
||||
|
||||
public Collection<BlacklistedSite> getAll();
|
||||
|
||||
|
||||
public BlacklistedSite getById(Long id);
|
||||
|
||||
|
||||
public void remove(BlacklistedSite blacklistedSite);
|
||||
|
||||
|
||||
public BlacklistedSite save(BlacklistedSite blacklistedSite);
|
||||
|
||||
|
||||
public BlacklistedSite update(BlacklistedSite oldBlacklistedSite, BlacklistedSite blacklistedSite);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -47,8 +47,8 @@ public interface EventRepository {
|
|||
* @param startChunk
|
||||
* the start chuck of a list you desire
|
||||
* @param chunkSize
|
||||
* the size of the chunk you desire
|
||||
*
|
||||
* the size of the chunk you desire
|
||||
*
|
||||
* @return a Collection of Events
|
||||
*/
|
||||
public Collection<Event> getEventsDuringPeriod(Date start, Date end, int startChunk, int chunkSize);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package org.mitre.openid.connect.repository;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.mitre.openid.connect.model.Nonce;
|
||||
|
||||
/**
|
||||
|
@ -19,14 +20,14 @@ public interface NonceRepository {
|
|||
* @return the nonce, if found
|
||||
*/
|
||||
public Nonce getById(Long id);
|
||||
|
||||
|
||||
/**
|
||||
* Remove the given Nonce from the database
|
||||
*
|
||||
* @param nonce the Nonce to remove
|
||||
*/
|
||||
public void remove(Nonce nonce);
|
||||
|
||||
|
||||
/**
|
||||
* Save a new Nonce in the database
|
||||
*
|
||||
|
@ -34,21 +35,21 @@ public interface NonceRepository {
|
|||
* @return the saved Nonce
|
||||
*/
|
||||
public Nonce save(Nonce nonce);
|
||||
|
||||
|
||||
/**
|
||||
* Return all nonces stored in the database
|
||||
*
|
||||
* @return the set of nonces
|
||||
*/
|
||||
public Collection<Nonce> getAll();
|
||||
|
||||
|
||||
/**
|
||||
* Return all expired nonces stored in the database
|
||||
*
|
||||
* @return the set of expired nonces
|
||||
*/
|
||||
public Collection<Nonce> getExpired();
|
||||
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
public Collection<Nonce> getByClientId(String clientId);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -26,24 +26,24 @@ import org.mitre.openid.connect.model.UserInfo;
|
|||
*
|
||||
*/
|
||||
public interface UserInfoRepository {
|
||||
|
||||
|
||||
/**
|
||||
* Returns the UserInfo for the given subject
|
||||
*
|
||||
* @param sub
|
||||
* the subject of the UserInfo
|
||||
* @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
|
||||
* @return
|
||||
*/
|
||||
public UserInfo save(UserInfo userInfo);
|
||||
|
||||
|
||||
/**
|
||||
* Removes the given UserInfo from the repository
|
||||
*
|
||||
|
@ -64,6 +64,6 @@ public interface UserInfoRepository {
|
|||
* @param username
|
||||
* @return
|
||||
*/
|
||||
public UserInfo getByUsername(String username);
|
||||
|
||||
public UserInfo getByUsername(String username);
|
||||
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ public interface WhitelistedSiteRepository {
|
|||
* @return a valid WhitelistedSite if it exists, null otherwise
|
||||
*/
|
||||
public WhitelistedSite getById(Long id);
|
||||
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
public WhitelistedSite getByClientId(String clientId);
|
||||
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @param oldWhitelistedSite
|
||||
* @param whitelistedSite
|
||||
* @return
|
||||
*/
|
||||
public WhitelistedSite update(WhitelistedSite oldWhitelistedSite, WhitelistedSite whitelistedSite);
|
||||
* @param oldWhitelistedSite
|
||||
* @param whitelistedSite
|
||||
* @return
|
||||
*/
|
||||
public WhitelistedSite update(WhitelistedSite oldWhitelistedSite, WhitelistedSite whitelistedSite);
|
||||
|
||||
}
|
||||
|
|
|
@ -30,17 +30,17 @@ import org.springframework.security.oauth2.provider.ClientDetails;
|
|||
*
|
||||
*/
|
||||
public interface ApprovedSiteService {
|
||||
|
||||
|
||||
|
||||
|
||||
public ApprovedSite createApprovedSite(String clientId, String userId, Date timeoutDate, Set<String> allowedScopes, WhitelistedSite whitelistedSite);
|
||||
|
||||
|
||||
/**
|
||||
* Return a collection of all ApprovedSites
|
||||
*
|
||||
* @return the ApprovedSite collection, or null
|
||||
*/
|
||||
public Collection<ApprovedSite> getAll();
|
||||
|
||||
|
||||
/**
|
||||
* Return a collection of ApprovedSite managed by this repository matching the
|
||||
* provided client ID and user ID
|
||||
|
@ -48,9 +48,9 @@ public interface ApprovedSiteService {
|
|||
* @param clientId
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
*/
|
||||
public Collection<ApprovedSite> getByClientIdAndUserId(String clientId, String userId);
|
||||
|
||||
|
||||
/**
|
||||
* Save an ApprovedSite
|
||||
*
|
||||
|
@ -82,14 +82,14 @@ public interface ApprovedSiteService {
|
|||
* @return
|
||||
*/
|
||||
public Collection<ApprovedSite> getByUserId(String userId);
|
||||
|
||||
|
||||
/**
|
||||
* Get all sites associated with this client
|
||||
* @param clientId
|
||||
* @return
|
||||
*/
|
||||
public Collection<ApprovedSite> getByClientId(String clientId);
|
||||
|
||||
|
||||
/**
|
||||
* Clear out any approved sites for a given client.
|
||||
* @param client
|
||||
|
|
|
@ -14,15 +14,15 @@ import org.mitre.openid.connect.model.BlacklistedSite;
|
|||
public interface BlacklistedSiteService {
|
||||
|
||||
public Collection<BlacklistedSite> getAll();
|
||||
|
||||
|
||||
public BlacklistedSite getById(Long id);
|
||||
|
||||
|
||||
public void remove(BlacklistedSite blacklistedSite);
|
||||
|
||||
|
||||
public BlacklistedSite saveNew(BlacklistedSite blacklistedSite);
|
||||
|
||||
|
||||
public BlacklistedSite update(BlacklistedSite oldBlacklistedSite, BlacklistedSite blacklistedSite);
|
||||
|
||||
public boolean isBlacklisted(String uri);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -15,24 +15,24 @@ import org.mitre.openid.connect.model.Nonce;
|
|||
public interface NonceService {
|
||||
|
||||
/**
|
||||
* Create a new nonce.
|
||||
*
|
||||
* Create a new nonce.
|
||||
*
|
||||
* @param clientId the ID of the client
|
||||
* @param value the value of the Nonce
|
||||
* @return the saved Nonce
|
||||
*/
|
||||
public Nonce create(String clientId, String value);
|
||||
|
||||
|
||||
/**
|
||||
* 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 value the value of the nonce
|
||||
* @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
|
||||
*
|
||||
|
@ -40,14 +40,14 @@ public interface NonceService {
|
|||
* @return the nonce, if found
|
||||
*/
|
||||
public Nonce getById(Long id);
|
||||
|
||||
|
||||
/**
|
||||
* Remove the given Nonce from the database
|
||||
*
|
||||
* @param nonce the Nonce to remove
|
||||
*/
|
||||
public void remove(Nonce nonce);
|
||||
|
||||
|
||||
/**
|
||||
* Save a new Nonce in the database
|
||||
*
|
||||
|
@ -55,21 +55,21 @@ public interface NonceService {
|
|||
* @return the saved Nonce
|
||||
*/
|
||||
public Nonce save(Nonce nonce);
|
||||
|
||||
|
||||
/**
|
||||
* Return all nonces stored in the database
|
||||
*
|
||||
* @return the set of nonces
|
||||
*/
|
||||
public Collection<Nonce> getAll();
|
||||
|
||||
|
||||
/**
|
||||
* Return all expired nonces stored in the database
|
||||
*
|
||||
* @return the set of expired nonces
|
||||
*/
|
||||
public Collection<Nonce> getExpired();
|
||||
|
||||
|
||||
/**
|
||||
* Return the set of nonces registered to the given client ID
|
||||
*
|
||||
|
@ -82,5 +82,5 @@ public interface NonceService {
|
|||
* Clear expired nonces from the database
|
||||
*/
|
||||
void clearExpiredNonces();
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -14,9 +14,9 @@ public interface StatsService {
|
|||
/**
|
||||
* Calculate summary statistics
|
||||
* approvalCount: total approved sites
|
||||
* userCount: unique users
|
||||
* clientCount: unique clients
|
||||
*
|
||||
* userCount: unique users
|
||||
* clientCount: unique clients
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Map<String, Integer> calculateSummaryStats();
|
||||
|
|
|
@ -41,7 +41,7 @@ public interface UserInfoService {
|
|||
* @return UserInfo for sub, or null
|
||||
*/
|
||||
public UserInfo getBySubject(String userId);
|
||||
|
||||
|
||||
/**
|
||||
* Remove the UserInfo
|
||||
*
|
||||
|
|
|
@ -33,7 +33,7 @@ public interface WhitelistedSiteService {
|
|||
* @return the WhitelistedSite collection, or null
|
||||
*/
|
||||
public Collection<WhitelistedSite> getAll();
|
||||
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
public WhitelistedSite getByClientId(String clientId);
|
||||
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
public Collection<WhitelistedSite> getByCreator(String creatorId);
|
||||
|
||||
|
||||
/**
|
||||
* Removes the given WhitelistedSite from the repository
|
||||
*
|
||||
|
@ -75,10 +75,10 @@ public interface WhitelistedSiteService {
|
|||
* @return
|
||||
*/
|
||||
public WhitelistedSite saveNew(WhitelistedSite whitelistedSite);
|
||||
|
||||
|
||||
/**
|
||||
* Updates an existing whitelisted site
|
||||
*/
|
||||
public WhitelistedSite update(WhitelistedSite oldWhitelistedSite, WhitelistedSite whitelistedSite);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -42,27 +42,27 @@ import com.nimbusds.jose.jwk.JWKSet;
|
|||
public class JwkKeyListView extends AbstractView {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(JwkKeyListView.class);
|
||||
|
||||
|
||||
@Override
|
||||
protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) {
|
||||
|
||||
response.setContentType("application/json");
|
||||
|
||||
|
||||
|
||||
|
||||
//BiMap<String, PublicKey> keyMap = (BiMap<String, PublicKey>) model.get("keys");
|
||||
Map<String, JWK> keys = (Map<String, JWK>) model.get("keys");
|
||||
|
||||
|
||||
JWKSet jwkSet = new JWKSet(new ArrayList<JWK>(keys.values()));
|
||||
|
||||
|
||||
try {
|
||||
|
||||
|
||||
Writer out = response.getWriter();
|
||||
out.write(jwkSet.toString());
|
||||
|
||||
|
||||
} catch (IOException e) {
|
||||
|
||||
|
||||
logger.error("IOException in JwkKeyListView.java: ", e);
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -27,26 +27,26 @@ import org.springframework.dao.IncorrectResultSizeDataAccessException;
|
|||
* Time: 2:13 PM
|
||||
*/
|
||||
public class JpaUtil {
|
||||
public static <T> T getSingleResult(List<T> list) {
|
||||
switch(list.size()) {
|
||||
case 0:
|
||||
return null;
|
||||
case 1:
|
||||
return list.get(0);
|
||||
default:
|
||||
throw new IncorrectResultSizeDataAccessException(1);
|
||||
}
|
||||
}
|
||||
public static <T> T getSingleResult(List<T> list) {
|
||||
switch(list.size()) {
|
||||
case 0:
|
||||
return null;
|
||||
case 1:
|
||||
return list.get(0);
|
||||
default:
|
||||
throw new IncorrectResultSizeDataAccessException(1);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T, I> T saveOrUpdate(I id, EntityManager entityManager, T entity) {
|
||||
if (id == null) {
|
||||
entityManager.persist(entity);
|
||||
entityManager.flush();
|
||||
return entity;
|
||||
} else {
|
||||
T tmp = entityManager.merge(entity);
|
||||
entityManager.flush();
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
public static <T, I> T saveOrUpdate(I id, EntityManager entityManager, T entity) {
|
||||
if (id == null) {
|
||||
entityManager.persist(entity);
|
||||
entityManager.flush();
|
||||
return entity;
|
||||
} else {
|
||||
T tmp = entityManager.merge(entity);
|
||||
entityManager.flush();
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,13 +18,13 @@ package org.mitre.oauth2.exception;
|
|||
public class DuplicateClientIdException extends RuntimeException {
|
||||
|
||||
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;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ public class JpaAuthenticationHolderRepository implements AuthenticationHolderRe
|
|||
|
||||
@PersistenceContext
|
||||
private EntityManager manager;
|
||||
|
||||
|
||||
@Override
|
||||
public AuthenticationHolderEntity getById(Long id) {
|
||||
return manager.find(AuthenticationHolderEntity.class, id);
|
||||
|
|
|
@ -27,16 +27,16 @@ public class JpaAuthorizationCodeRepository implements AuthorizationCodeReposito
|
|||
|
||||
@PersistenceContext
|
||||
EntityManager manager;
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.mitre.oauth2.repository.AuthorizationCodeRepository#save(org.mitre.oauth2.model.AuthorizationCodeEntity)
|
||||
*/
|
||||
@Override
|
||||
@Transactional
|
||||
public AuthorizationCodeEntity save(AuthorizationCodeEntity authorizationCode) {
|
||||
|
||||
|
||||
return JpaUtil.saveOrUpdate(authorizationCode.getId(), manager, authorizationCode);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
@ -45,20 +45,20 @@ public class JpaAuthorizationCodeRepository implements AuthorizationCodeReposito
|
|||
@Override
|
||||
@Transactional
|
||||
public OAuth2Authentication consume(String code) throws InvalidGrantException {
|
||||
|
||||
|
||||
TypedQuery<AuthorizationCodeEntity> query = manager.createNamedQuery("AuthorizationCodeEntity.getByValue", AuthorizationCodeEntity.class);
|
||||
query.setParameter("code", code);
|
||||
|
||||
|
||||
AuthorizationCodeEntity result = JpaUtil.getSingleResult(query.getResultList());
|
||||
|
||||
|
||||
if (result == null) {
|
||||
throw new InvalidGrantException("JpaAuthorizationCodeRepository: no authorization code found for value " + code);
|
||||
}
|
||||
|
||||
|
||||
OAuth2Authentication authRequest = result.getAuthentication();
|
||||
|
||||
|
||||
manager.remove(result);
|
||||
|
||||
|
||||
return authRequest;
|
||||
|
||||
}
|
||||
|
|
|
@ -37,15 +37,16 @@ public class JpaOAuth2ClientRepository implements OAuth2ClientRepository {
|
|||
|
||||
@PersistenceContext
|
||||
private EntityManager manager;
|
||||
|
||||
|
||||
public JpaOAuth2ClientRepository() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public JpaOAuth2ClientRepository(EntityManager manager) {
|
||||
this.manager = manager;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ClientDetailsEntity getById(Long id) {
|
||||
return manager.find(ClientDetailsEntity.class, id);
|
||||
}
|
||||
|
@ -82,17 +83,17 @@ public class JpaOAuth2ClientRepository implements OAuth2ClientRepository {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ClientDetailsEntity updateClient(Long id, ClientDetailsEntity client) {
|
||||
public ClientDetailsEntity updateClient(Long id, ClientDetailsEntity client) {
|
||||
// sanity check
|
||||
client.setId(id);
|
||||
|
||||
return JpaUtil.saveOrUpdate(id, manager, client);
|
||||
}
|
||||
|
||||
return JpaUtil.saveOrUpdate(id, manager, client);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ClientDetailsEntity> getAllClients() {
|
||||
public Collection<ClientDetailsEntity> getAllClients() {
|
||||
TypedQuery<ClientDetailsEntity> query = manager.createNamedQuery("ClientDetailsEntity.findAll", ClientDetailsEntity.class);
|
||||
return query.getResultList();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -42,18 +42,18 @@ public class JpaOAuth2TokenRepository implements OAuth2TokenRepository {
|
|||
query.setParameter("tokenValue", accessTokenValue);
|
||||
return JpaUtil.getSingleResult(query.getResultList());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public OAuth2AccessTokenEntity getAccessTokenById(Long id) {
|
||||
return manager.find(OAuth2AccessTokenEntity.class, id);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public OAuth2AccessTokenEntity saveAccessToken(OAuth2AccessTokenEntity token) {
|
||||
return JpaUtil.saveOrUpdate(token.getId(), manager, token);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void removeAccessToken(OAuth2AccessTokenEntity accessToken) {
|
||||
|
@ -64,17 +64,17 @@ public class JpaOAuth2TokenRepository implements OAuth2TokenRepository {
|
|||
throw new IllegalArgumentException("Access token not found: " + accessToken);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void clearAccessTokensForRefreshToken(OAuth2RefreshTokenEntity refreshToken) {
|
||||
public void clearAccessTokensForRefreshToken(OAuth2RefreshTokenEntity refreshToken) {
|
||||
TypedQuery<OAuth2AccessTokenEntity> query = manager.createNamedQuery("OAuth2AccessTokenEntity.getByRefreshToken", OAuth2AccessTokenEntity.class);
|
||||
query.setParameter("refreshToken", refreshToken);
|
||||
List<OAuth2AccessTokenEntity> accessTokens = query.getResultList();
|
||||
for (OAuth2AccessTokenEntity accessToken : accessTokens) {
|
||||
removeAccessToken(accessToken);
|
||||
}
|
||||
}
|
||||
List<OAuth2AccessTokenEntity> accessTokens = query.getResultList();
|
||||
for (OAuth2AccessTokenEntity accessToken : accessTokens) {
|
||||
removeAccessToken(accessToken);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OAuth2RefreshTokenEntity getRefreshTokenByValue(String refreshTokenValue) {
|
||||
|
@ -82,105 +82,105 @@ public class JpaOAuth2TokenRepository implements OAuth2TokenRepository {
|
|||
query.setParameter("tokenValue", refreshTokenValue);
|
||||
return JpaUtil.getSingleResult(query.getResultList());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public OAuth2RefreshTokenEntity getRefreshTokenById(Long id) {
|
||||
return manager.find(OAuth2RefreshTokenEntity.class, id);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public OAuth2RefreshTokenEntity saveRefreshToken(OAuth2RefreshTokenEntity refreshToken) {
|
||||
return JpaUtil.saveOrUpdate(refreshToken.getId(), manager, refreshToken);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void removeRefreshToken(OAuth2RefreshTokenEntity refreshToken) {
|
||||
public void removeRefreshToken(OAuth2RefreshTokenEntity refreshToken) {
|
||||
OAuth2RefreshTokenEntity found = getRefreshTokenByValue(refreshToken.getValue());
|
||||
if (found != null) {
|
||||
manager.remove(found);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Refresh token not found: " + refreshToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void clearTokensForClient(ClientDetailsEntity client) {
|
||||
public void clearTokensForClient(ClientDetailsEntity client) {
|
||||
TypedQuery<OAuth2AccessTokenEntity> queryA = manager.createNamedQuery("OAuth2AccessTokenEntity.getByClient", OAuth2AccessTokenEntity.class);
|
||||
queryA.setParameter("client", client);
|
||||
List<OAuth2AccessTokenEntity> accessTokens = queryA.getResultList();
|
||||
for (OAuth2AccessTokenEntity accessToken : accessTokens) {
|
||||
removeAccessToken(accessToken);
|
||||
}
|
||||
List<OAuth2AccessTokenEntity> accessTokens = queryA.getResultList();
|
||||
for (OAuth2AccessTokenEntity accessToken : accessTokens) {
|
||||
removeAccessToken(accessToken);
|
||||
}
|
||||
TypedQuery<OAuth2RefreshTokenEntity> queryR = manager.createNamedQuery("OAuth2RefreshTokenEntity.getByClient", OAuth2RefreshTokenEntity.class);
|
||||
queryR.setParameter("client", client);
|
||||
List<OAuth2RefreshTokenEntity> refreshTokens = queryR.getResultList();
|
||||
for (OAuth2RefreshTokenEntity refreshToken : refreshTokens) {
|
||||
removeRefreshToken(refreshToken);
|
||||
}
|
||||
}
|
||||
List<OAuth2RefreshTokenEntity> refreshTokens = queryR.getResultList();
|
||||
for (OAuth2RefreshTokenEntity refreshToken : refreshTokens) {
|
||||
removeRefreshToken(refreshToken);
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.mitre.oauth2.repository.OAuth2TokenRepository#getAccessTokensForClient(org.mitre.oauth2.model.ClientDetailsEntity)
|
||||
*/
|
||||
@Override
|
||||
public List<OAuth2AccessTokenEntity> getAccessTokensForClient(ClientDetailsEntity client) {
|
||||
* @see org.mitre.oauth2.repository.OAuth2TokenRepository#getAccessTokensForClient(org.mitre.oauth2.model.ClientDetailsEntity)
|
||||
*/
|
||||
@Override
|
||||
public List<OAuth2AccessTokenEntity> getAccessTokensForClient(ClientDetailsEntity client) {
|
||||
TypedQuery<OAuth2AccessTokenEntity> queryA = manager.createNamedQuery("OAuth2AccessTokenEntity.getByClient", OAuth2AccessTokenEntity.class);
|
||||
queryA.setParameter("client", client);
|
||||
List<OAuth2AccessTokenEntity> accessTokens = queryA.getResultList();
|
||||
return accessTokens;
|
||||
}
|
||||
List<OAuth2AccessTokenEntity> accessTokens = queryA.getResultList();
|
||||
return accessTokens;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.mitre.oauth2.repository.OAuth2TokenRepository#getRefreshTokensForClient(org.mitre.oauth2.model.ClientDetailsEntity)
|
||||
*/
|
||||
@Override
|
||||
public List<OAuth2RefreshTokenEntity> getRefreshTokensForClient(ClientDetailsEntity client) {
|
||||
* @see org.mitre.oauth2.repository.OAuth2TokenRepository#getRefreshTokensForClient(org.mitre.oauth2.model.ClientDetailsEntity)
|
||||
*/
|
||||
@Override
|
||||
public List<OAuth2RefreshTokenEntity> getRefreshTokensForClient(ClientDetailsEntity client) {
|
||||
TypedQuery<OAuth2RefreshTokenEntity> queryR = manager.createNamedQuery("OAuth2RefreshTokenEntity.getByClient", OAuth2RefreshTokenEntity.class);
|
||||
queryR.setParameter("client", client);
|
||||
List<OAuth2RefreshTokenEntity> refreshTokens = queryR.getResultList();
|
||||
return refreshTokens;
|
||||
}
|
||||
List<OAuth2RefreshTokenEntity> refreshTokens = queryR.getResultList();
|
||||
return refreshTokens;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.mitre.oauth2.repository.OAuth2TokenRepository#getExpiredAccessTokens()
|
||||
*/
|
||||
@Override
|
||||
public List<OAuth2AccessTokenEntity> getExpiredAccessTokens() {
|
||||
* @see org.mitre.oauth2.repository.OAuth2TokenRepository#getExpiredAccessTokens()
|
||||
*/
|
||||
@Override
|
||||
public List<OAuth2AccessTokenEntity> getExpiredAccessTokens() {
|
||||
TypedQuery<OAuth2AccessTokenEntity> queryA = manager.createNamedQuery("OAuth2AccessTokenEntity.getExpired", OAuth2AccessTokenEntity.class);
|
||||
List<OAuth2AccessTokenEntity> accessTokens = queryA.getResultList();
|
||||
return accessTokens;
|
||||
}
|
||||
List<OAuth2AccessTokenEntity> accessTokens = queryA.getResultList();
|
||||
return accessTokens;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.mitre.oauth2.repository.OAuth2TokenRepository#getExpiredRefreshTokens()
|
||||
*/
|
||||
@Override
|
||||
public List<OAuth2RefreshTokenEntity> getExpiredRefreshTokens() {
|
||||
* @see org.mitre.oauth2.repository.OAuth2TokenRepository#getExpiredRefreshTokens()
|
||||
*/
|
||||
@Override
|
||||
public List<OAuth2RefreshTokenEntity> getExpiredRefreshTokens() {
|
||||
TypedQuery<OAuth2RefreshTokenEntity> queryR = manager.createNamedQuery("OAuth2RefreshTokenEntity.getExpired", OAuth2RefreshTokenEntity.class);
|
||||
List<OAuth2RefreshTokenEntity> refreshTokens = queryR.getResultList();
|
||||
return refreshTokens;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OAuth2AccessTokenEntity getByAuthentication(OAuth2Authentication auth) {
|
||||
TypedQuery<OAuth2AccessTokenEntity> queryA = manager.createNamedQuery("OAuth2AccessTokenEntity.getByAuthentication", OAuth2AccessTokenEntity.class);
|
||||
queryA.setParameter("authentication", auth);
|
||||
List<OAuth2AccessTokenEntity> accessTokens = queryA.getResultList();
|
||||
return JpaUtil.getSingleResult(accessTokens);
|
||||
}
|
||||
List<OAuth2RefreshTokenEntity> refreshTokens = queryR.getResultList();
|
||||
return refreshTokens;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OAuth2AccessTokenEntity getByAuthentication(OAuth2Authentication auth) {
|
||||
TypedQuery<OAuth2AccessTokenEntity> queryA = manager.createNamedQuery("OAuth2AccessTokenEntity.getByAuthentication", OAuth2AccessTokenEntity.class);
|
||||
queryA.setParameter("authentication", auth);
|
||||
List<OAuth2AccessTokenEntity> accessTokens = queryA.getResultList();
|
||||
return JpaUtil.getSingleResult(accessTokens);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.mitre.oauth2.repository.OAuth2TokenRepository#getAccessTokenForIdToken(org.mitre.oauth2.model.OAuth2AccessTokenEntity)
|
||||
*/
|
||||
@Override
|
||||
public OAuth2AccessTokenEntity getAccessTokenForIdToken(OAuth2AccessTokenEntity idToken) {
|
||||
TypedQuery<OAuth2AccessTokenEntity> queryA = manager.createNamedQuery("OAuth2AccessTokenEntity.getByIdToken", OAuth2AccessTokenEntity.class);
|
||||
queryA.setParameter("idToken", idToken);
|
||||
List<OAuth2AccessTokenEntity> accessTokens = queryA.getResultList();
|
||||
return JpaUtil.getSingleResult(accessTokens);
|
||||
}
|
||||
* @see org.mitre.oauth2.repository.OAuth2TokenRepository#getAccessTokenForIdToken(org.mitre.oauth2.model.OAuth2AccessTokenEntity)
|
||||
*/
|
||||
@Override
|
||||
public OAuth2AccessTokenEntity getAccessTokenForIdToken(OAuth2AccessTokenEntity idToken) {
|
||||
TypedQuery<OAuth2AccessTokenEntity> queryA = manager.createNamedQuery("OAuth2AccessTokenEntity.getByIdToken", OAuth2AccessTokenEntity.class);
|
||||
queryA.setParameter("idToken", idToken);
|
||||
List<OAuth2AccessTokenEntity> accessTokens = queryA.getResultList();
|
||||
return JpaUtil.getSingleResult(accessTokens);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
*/
|
||||
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.Set;
|
||||
|
||||
|
@ -15,9 +18,6 @@ import org.mitre.oauth2.repository.SystemScopeRepository;
|
|||
import org.springframework.stereotype.Repository;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import static org.mitre.util.jpa.JpaUtil.getSingleResult;
|
||||
import static org.mitre.util.jpa.JpaUtil.saveOrUpdate;
|
||||
|
||||
/**
|
||||
* @author jricher
|
||||
*
|
||||
|
@ -27,7 +27,7 @@ public class JpaSystemScopeRepository implements SystemScopeRepository {
|
|||
|
||||
@PersistenceContext
|
||||
private EntityManager em;
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.mitre.oauth2.repository.SystemScopeRepository#getAll()
|
||||
*/
|
||||
|
@ -35,7 +35,7 @@ public class JpaSystemScopeRepository implements SystemScopeRepository {
|
|||
@Transactional
|
||||
public Set<SystemScope> getAll() {
|
||||
TypedQuery<SystemScope> query = em.createNamedQuery("SystemScope.findAll", SystemScope.class);
|
||||
|
||||
|
||||
return new LinkedHashSet<SystemScope>(query.getResultList());
|
||||
}
|
||||
|
||||
|
@ -66,7 +66,7 @@ public class JpaSystemScopeRepository implements SystemScopeRepository {
|
|||
@Transactional
|
||||
public void remove(SystemScope scope) {
|
||||
SystemScope found = getById(scope.getId());
|
||||
|
||||
|
||||
if (found != null) {
|
||||
em.remove(found);
|
||||
}
|
||||
|
|
|
@ -23,9 +23,9 @@ public class DefaultOAuth2AuthorizationCodeService implements AuthorizationCodeS
|
|||
|
||||
@Autowired
|
||||
private AuthorizationCodeRepository repository;
|
||||
|
||||
|
||||
private RandomValueStringGenerator generator = new RandomValueStringGenerator();
|
||||
|
||||
|
||||
/**
|
||||
* Generate a random authorization code and create an AuthorizationCodeEntity,
|
||||
* which will be stored in the repository.
|
||||
|
@ -37,16 +37,16 @@ public class DefaultOAuth2AuthorizationCodeService implements AuthorizationCodeS
|
|||
@Override
|
||||
public String createAuthorizationCode(OAuth2Authentication authentication) {
|
||||
String code = generator.generate();
|
||||
|
||||
|
||||
AuthorizationCodeEntity entity = new AuthorizationCodeEntity(code, authentication);
|
||||
repository.save(entity);
|
||||
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Consume a given authorization code.
|
||||
* Match the provided string to an AuthorizationCodeEntity. If one is found, return
|
||||
* Consume a given authorization code.
|
||||
* 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
|
||||
* InvalidGrantException.
|
||||
*
|
||||
|
@ -56,7 +56,7 @@ public class DefaultOAuth2AuthorizationCodeService implements AuthorizationCodeS
|
|||
*/
|
||||
@Override
|
||||
public OAuth2Authentication consumeAuthorizationCode(String code) throws InvalidGrantException {
|
||||
|
||||
|
||||
OAuth2Authentication auth = repository.consume(code);
|
||||
return auth;
|
||||
}
|
||||
|
|
|
@ -39,32 +39,32 @@ import com.google.common.base.Strings;
|
|||
|
||||
@Service
|
||||
public class DefaultOAuth2ClientDetailsEntityService implements ClientDetailsEntityService {
|
||||
|
||||
|
||||
@Autowired
|
||||
private OAuth2ClientRepository clientRepository;
|
||||
|
||||
|
||||
@Autowired
|
||||
private OAuth2TokenRepository tokenRepository;
|
||||
|
||||
|
||||
@Autowired
|
||||
private ApprovedSiteService approvedSiteService;
|
||||
|
||||
|
||||
@Autowired
|
||||
private WhitelistedSiteService whitelistedSiteService;
|
||||
|
||||
|
||||
@Autowired
|
||||
private BlacklistedSiteService blacklistedSiteService;
|
||||
|
||||
|
||||
public DefaultOAuth2ClientDetailsEntityService() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
public DefaultOAuth2ClientDetailsEntityService(OAuth2ClientRepository clientRepository,
|
||||
|
||||
public DefaultOAuth2ClientDetailsEntityService(OAuth2ClientRepository clientRepository,
|
||||
OAuth2TokenRepository tokenRepository) {
|
||||
this.clientRepository = clientRepository;
|
||||
this.tokenRepository = tokenRepository;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ClientDetailsEntity saveNewClient(ClientDetailsEntity client) {
|
||||
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)) {
|
||||
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
|
||||
if (Strings.isNullOrEmpty(client.getClientId())) {
|
||||
client = generateClientId(client);
|
||||
}
|
||||
|
||||
// if the client is flagged to allow for refresh tokens, make sure it's got the right granted scopes
|
||||
if (client.isAllowRefresh()) {
|
||||
client.getScope().add("offline_access");
|
||||
} else {
|
||||
client.getScope().remove("offline_access");
|
||||
}
|
||||
|
||||
// timestamp this to right now
|
||||
client.setCreatedAt(new Date());
|
||||
|
||||
return clientRepository.saveClient(client);
|
||||
if (Strings.isNullOrEmpty(client.getClientId())) {
|
||||
client = generateClientId(client);
|
||||
}
|
||||
|
||||
// if the client is flagged to allow for refresh tokens, make sure it's got the right granted scopes
|
||||
if (client.isAllowRefresh()) {
|
||||
client.getScope().add("offline_access");
|
||||
} else {
|
||||
client.getScope().remove("offline_access");
|
||||
}
|
||||
|
||||
// timestamp this to right now
|
||||
client.setCreatedAt(new Date());
|
||||
|
||||
return clientRepository.saveClient(client);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the client by its internal ID
|
||||
*/
|
||||
@Override
|
||||
public ClientDetailsEntity getClientById(Long id) {
|
||||
ClientDetailsEntity client = clientRepository.getById(id);
|
||||
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the client for the given ClientID
|
||||
*/
|
||||
|
@ -121,87 +122,87 @@ public class DefaultOAuth2ClientDetailsEntityService implements ClientDetailsEnt
|
|||
return client;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
throw new IllegalArgumentException("Client id must not be empty!");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Delete a client and all its associated tokens
|
||||
*/
|
||||
@Override
|
||||
public void deleteClient(ClientDetailsEntity client) throws InvalidClientException {
|
||||
|
||||
public void deleteClient(ClientDetailsEntity client) throws InvalidClientException {
|
||||
|
||||
if (clientRepository.getById(client.getId()) == null) {
|
||||
throw new InvalidClientException("Client with id " + client.getClientId() + " was not found");
|
||||
}
|
||||
|
||||
|
||||
// clean out any tokens that this client had issued
|
||||
tokenRepository.clearTokensForClient(client);
|
||||
|
||||
|
||||
// clean out any approved sites for this client
|
||||
approvedSiteService.clearApprovedSitesForClient(client);
|
||||
|
||||
|
||||
// clear out any whitelisted sites for this client
|
||||
WhitelistedSite whitelistedSite = whitelistedSiteService.getByClientId(client.getClientId());
|
||||
if (whitelistedSite != null) {
|
||||
whitelistedSiteService.remove(whitelistedSite);
|
||||
whitelistedSiteService.remove(whitelistedSite);
|
||||
}
|
||||
|
||||
|
||||
// take care of the client itself
|
||||
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.
|
||||
*/
|
||||
@Override
|
||||
public ClientDetailsEntity updateClient(ClientDetailsEntity oldClient, ClientDetailsEntity newClient) throws IllegalArgumentException {
|
||||
public ClientDetailsEntity updateClient(ClientDetailsEntity oldClient, ClientDetailsEntity newClient) throws IllegalArgumentException {
|
||||
if (oldClient != null && newClient != null) {
|
||||
|
||||
|
||||
for (String uri : newClient.getRegisteredRedirectUri()) {
|
||||
if (blacklistedSiteService.isBlacklisted(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!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all clients in the system
|
||||
*/
|
||||
@Override
|
||||
public Collection<ClientDetailsEntity> getAllClients() {
|
||||
public Collection<ClientDetailsEntity> 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.
|
||||
*/
|
||||
@Override
|
||||
public ClientDetailsEntity generateClientId(ClientDetailsEntity client) {
|
||||
public ClientDetailsEntity generateClientId(ClientDetailsEntity client) {
|
||||
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.
|
||||
*/
|
||||
@Override
|
||||
public ClientDetailsEntity generateClientSecret(ClientDetailsEntity client) {
|
||||
public ClientDetailsEntity generateClientSecret(ClientDetailsEntity client) {
|
||||
client.setClientSecret(Base64.encodeBase64URLSafeString(new BigInteger(512, new SecureRandom()).toByteArray()).replace("=", ""));
|
||||
return client;
|
||||
}
|
||||
return client;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -59,159 +59,159 @@ import com.nimbusds.jwt.PlainJWT;
|
|||
*/
|
||||
@Service
|
||||
public class DefaultOAuth2ProviderTokenService implements OAuth2TokenEntityService {
|
||||
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(DefaultOAuth2ProviderTokenService.class);
|
||||
|
||||
@Autowired
|
||||
private OAuth2TokenRepository tokenRepository;
|
||||
|
||||
|
||||
@Autowired
|
||||
private AuthenticationHolderRepository authenticationHolderRepository;
|
||||
|
||||
|
||||
@Autowired
|
||||
private ClientDetailsEntityService clientDetailsService;
|
||||
|
||||
|
||||
@Autowired
|
||||
private TokenEnhancer tokenEnhancer;
|
||||
|
||||
|
||||
@Autowired
|
||||
private ApprovedSiteService approvedSiteService;
|
||||
|
||||
|
||||
@Override
|
||||
public OAuth2AccessTokenEntity createAccessToken(OAuth2Authentication authentication) throws AuthenticationException, InvalidClientException {
|
||||
public OAuth2AccessTokenEntity createAccessToken(OAuth2Authentication authentication) throws AuthenticationException, InvalidClientException {
|
||||
if (authentication != null && authentication.getOAuth2Request() != null) {
|
||||
// look up our client
|
||||
OAuth2Request clientAuth = authentication.getOAuth2Request();
|
||||
|
||||
|
||||
ClientDetailsEntity client = clientDetailsService.loadClientByClientId(clientAuth.getClientId());
|
||||
|
||||
|
||||
if (client == null) {
|
||||
throw new InvalidClientException("Client not found: " + clientAuth.getClientId());
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
if (client.getAccessTokenValiditySeconds() != null && client.getAccessTokenValiditySeconds() > 0) {
|
||||
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();
|
||||
// attach the client
|
||||
token.setClient(client);
|
||||
|
||||
|
||||
// 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());
|
||||
// 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
|
||||
if (client.getAccessTokenValiditySeconds() != null && client.getAccessTokenValiditySeconds() > 0) {
|
||||
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();
|
||||
|
||||
|
||||
// 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");
|
||||
ApprovedSite ap = approvedSiteService.getById(apId);
|
||||
Set<OAuth2AccessTokenEntity> apTokens = ap.getApprovedAccessTokens();
|
||||
apTokens.add(token);
|
||||
ap.setApprovedAccessTokens(apTokens);
|
||||
approvedSiteService.save(ap);
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (token.getRefreshToken() != null) {
|
||||
tokenRepository.saveRefreshToken(token.getRefreshToken()); // make sure we save any changes that might have been enhanced
|
||||
}
|
||||
|
||||
return token;
|
||||
|
||||
if (token.getRefreshToken() != null) {
|
||||
tokenRepository.saveRefreshToken(token.getRefreshToken()); // make sure we save any changes that might have been enhanced
|
||||
}
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
throw new AuthenticationCredentialsNotFoundException("No authentication credentials found");
|
||||
}
|
||||
|
||||
throw new AuthenticationCredentialsNotFoundException("No authentication credentials found");
|
||||
}
|
||||
|
||||
@Override
|
||||
public OAuth2AccessTokenEntity refreshAccessToken(String refreshTokenValue, TokenRequest authRequest) throws AuthenticationException {
|
||||
|
||||
public OAuth2AccessTokenEntity refreshAccessToken(String refreshTokenValue, TokenRequest authRequest) throws AuthenticationException {
|
||||
|
||||
OAuth2RefreshTokenEntity refreshToken = tokenRepository.getRefreshTokenByValue(refreshTokenValue);
|
||||
|
||||
|
||||
if (refreshToken == null) {
|
||||
throw new InvalidTokenException("Invalid refresh token: " + refreshTokenValue);
|
||||
}
|
||||
|
||||
|
||||
ClientDetailsEntity client = refreshToken.getClient();
|
||||
|
||||
|
||||
AuthenticationHolderEntity authHolder = refreshToken.getAuthenticationHolder();
|
||||
|
||||
|
||||
//Make sure this client allows access token refreshing
|
||||
if (!client.isAllowRefresh()) {
|
||||
throw new InvalidClientException("Client does not allow refreshing access token!");
|
||||
}
|
||||
|
||||
|
||||
// clear out any access tokens
|
||||
// TODO: make this a configurable option
|
||||
tokenRepository.clearAccessTokensForRefreshToken(refreshToken);
|
||||
|
||||
|
||||
if (refreshToken.isExpired()) {
|
||||
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
|
||||
// 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
|
||||
Set<String> refreshScopes = new HashSet<String>(refreshToken.getAuthenticationHolder().getAuthentication().getOAuth2Request().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
|
||||
if (refreshScopes != null && refreshScopes.containsAll(scope)) {
|
||||
// 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)
|
||||
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());
|
||||
|
||||
tokenRepository.saveAccessToken(token);
|
||||
|
||||
return token;
|
||||
|
||||
}
|
||||
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());
|
||||
|
||||
tokenRepository.saveAccessToken(token);
|
||||
|
||||
return token;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public OAuth2Authentication loadAuthentication(String accessTokenValue) throws AuthenticationException {
|
||||
|
||||
public OAuth2Authentication loadAuthentication(String accessTokenValue) throws AuthenticationException {
|
||||
|
||||
OAuth2AccessTokenEntity accessToken = tokenRepository.getAccessTokenByValue(accessTokenValue);
|
||||
|
||||
|
||||
if (accessToken == null) {
|
||||
throw new InvalidTokenException("Invalid access token: " + accessTokenValue);
|
||||
}
|
||||
|
||||
|
||||
if (accessToken.isExpired()) {
|
||||
//tokenRepository.removeAccessToken(accessToken);
|
||||
revokeAccessToken(accessToken);
|
||||
throw new InvalidTokenException("Expired access token: " + accessTokenValue);
|
||||
}
|
||||
|
||||
return accessToken.getAuthenticationHolder().getAuthentication();
|
||||
}
|
||||
|
||||
return accessToken.getAuthenticationHolder().getAuthentication();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get an access token from its token value.
|
||||
*/
|
||||
@Override
|
||||
public OAuth2AccessTokenEntity readAccessToken(String accessTokenValue) throws AuthenticationException {
|
||||
public OAuth2AccessTokenEntity readAccessToken(String accessTokenValue) throws AuthenticationException {
|
||||
OAuth2AccessTokenEntity accessToken = tokenRepository.getAccessTokenByValue(accessTokenValue);
|
||||
if (accessToken == null) {
|
||||
throw new InvalidTokenException("Access token for value " + accessTokenValue + " was not found");
|
||||
}
|
||||
else {
|
||||
return accessToken;
|
||||
return accessToken;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an access token by its authentication object.
|
||||
*/
|
||||
@Override
|
||||
public OAuth2AccessTokenEntity getAccessToken(OAuth2Authentication authentication) {
|
||||
|
||||
|
||||
OAuth2AccessTokenEntity accessToken = tokenRepository.getByAuthentication(authentication);
|
||||
|
||||
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a refresh token by its token value.
|
||||
*/
|
||||
@Override
|
||||
public OAuth2RefreshTokenEntity getRefreshToken(String refreshTokenValue) throws AuthenticationException {
|
||||
public OAuth2RefreshTokenEntity getRefreshToken(String refreshTokenValue) throws AuthenticationException {
|
||||
OAuth2RefreshTokenEntity refreshToken = tokenRepository.getRefreshTokenByValue(refreshTokenValue);
|
||||
if (refreshToken == null) {
|
||||
throw new InvalidTokenException("Refresh token for value " + refreshTokenValue + " was not found");
|
||||
}
|
||||
else {
|
||||
return refreshToken;
|
||||
return refreshToken;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Revoke a refresh token and all access tokens issued to it.
|
||||
*/
|
||||
@Override
|
||||
public void revokeRefreshToken(OAuth2RefreshTokenEntity refreshToken) {
|
||||
tokenRepository.clearAccessTokensForRefreshToken(refreshToken);
|
||||
tokenRepository.removeRefreshToken(refreshToken);
|
||||
}
|
||||
public void revokeRefreshToken(OAuth2RefreshTokenEntity refreshToken) {
|
||||
tokenRepository.clearAccessTokensForRefreshToken(refreshToken);
|
||||
tokenRepository.removeRefreshToken(refreshToken);
|
||||
}
|
||||
|
||||
/**
|
||||
* Revoke an access token.
|
||||
* Revoke an access token.
|
||||
*/
|
||||
@Override
|
||||
public void revokeAccessToken(OAuth2AccessTokenEntity accessToken) {
|
||||
tokenRepository.removeAccessToken(accessToken);
|
||||
}
|
||||
|
||||
public void revokeAccessToken(OAuth2AccessTokenEntity accessToken) {
|
||||
tokenRepository.removeAccessToken(accessToken);
|
||||
}
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.mitre.oauth2.service.OAuth2TokenEntityService#getAccessTokensForClient(org.mitre.oauth2.model.ClientDetailsEntity)
|
||||
*/
|
||||
@Override
|
||||
public List<OAuth2AccessTokenEntity> getAccessTokensForClient(ClientDetailsEntity client) {
|
||||
return tokenRepository.getAccessTokensForClient(client);
|
||||
}
|
||||
* @see org.mitre.oauth2.service.OAuth2TokenEntityService#getAccessTokensForClient(org.mitre.oauth2.model.ClientDetailsEntity)
|
||||
*/
|
||||
@Override
|
||||
public List<OAuth2AccessTokenEntity> getAccessTokensForClient(ClientDetailsEntity client) {
|
||||
return tokenRepository.getAccessTokensForClient(client);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.mitre.oauth2.service.OAuth2TokenEntityService#getRefreshTokensForClient(org.mitre.oauth2.model.ClientDetailsEntity)
|
||||
*/
|
||||
@Override
|
||||
public List<OAuth2RefreshTokenEntity> getRefreshTokensForClient(ClientDetailsEntity client) {
|
||||
return tokenRepository.getRefreshTokensForClient(client);
|
||||
}
|
||||
* @see org.mitre.oauth2.service.OAuth2TokenEntityService#getRefreshTokensForClient(org.mitre.oauth2.model.ClientDetailsEntity)
|
||||
*/
|
||||
@Override
|
||||
public List<OAuth2RefreshTokenEntity> getRefreshTokensForClient(ClientDetailsEntity client) {
|
||||
return tokenRepository.getRefreshTokensForClient(client);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Scheduled(fixedRate = 5 * 60 * 1000) // schedule this task every five minutes
|
||||
public void clearExpiredTokens() {
|
||||
logger.info("Cleaning out all expired tokens");
|
||||
|
||||
List<OAuth2AccessTokenEntity> accessTokens = tokenRepository.getExpiredAccessTokens();
|
||||
logger.info("Found " + accessTokens.size() + " expired access tokens");
|
||||
for (OAuth2AccessTokenEntity oAuth2AccessTokenEntity : accessTokens) {
|
||||
revokeAccessToken(oAuth2AccessTokenEntity);
|
||||
}
|
||||
|
||||
List<OAuth2RefreshTokenEntity> refreshTokens = tokenRepository.getExpiredRefreshTokens();
|
||||
logger.info("Found " + refreshTokens.size() + " expired refresh tokens");
|
||||
for (OAuth2RefreshTokenEntity oAuth2RefreshTokenEntity : refreshTokens) {
|
||||
revokeRefreshToken(oAuth2RefreshTokenEntity);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@Override
|
||||
@Scheduled(fixedRate = 5 * 60 * 1000) // schedule this task every five minutes
|
||||
public void clearExpiredTokens() {
|
||||
logger.info("Cleaning out all expired tokens");
|
||||
|
||||
List<OAuth2AccessTokenEntity> accessTokens = tokenRepository.getExpiredAccessTokens();
|
||||
logger.info("Found " + accessTokens.size() + " expired access tokens");
|
||||
for (OAuth2AccessTokenEntity oAuth2AccessTokenEntity : accessTokens) {
|
||||
revokeAccessToken(oAuth2AccessTokenEntity);
|
||||
}
|
||||
|
||||
List<OAuth2RefreshTokenEntity> refreshTokens = tokenRepository.getExpiredRefreshTokens();
|
||||
logger.info("Found " + refreshTokens.size() + " expired refresh tokens");
|
||||
for (OAuth2RefreshTokenEntity oAuth2RefreshTokenEntity : refreshTokens) {
|
||||
revokeRefreshToken(oAuth2RefreshTokenEntity);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a builder object for this class (for tests)
|
||||
* @return
|
||||
*/
|
||||
public static DefaultOAuth2ProviderTokenServicesBuilder makeBuilder() {
|
||||
return new DefaultOAuth2ProviderTokenServicesBuilder();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Builder class for test harnesses.
|
||||
*/
|
||||
public static class DefaultOAuth2ProviderTokenServicesBuilder {
|
||||
private DefaultOAuth2ProviderTokenService instance;
|
||||
|
||||
|
||||
private DefaultOAuth2ProviderTokenServicesBuilder() {
|
||||
instance = new DefaultOAuth2ProviderTokenService();
|
||||
}
|
||||
|
||||
|
||||
public DefaultOAuth2ProviderTokenServicesBuilder setTokenRepository(OAuth2TokenRepository tokenRepository) {
|
||||
instance.tokenRepository = tokenRepository;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public DefaultOAuth2ProviderTokenServicesBuilder setClientDetailsService(ClientDetailsEntityService clientDetailsService) {
|
||||
instance.clientDetailsService = clientDetailsService;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public DefaultOAuth2ProviderTokenServicesBuilder setTokenEnhancer(TokenEnhancer tokenEnhancer) {
|
||||
instance.tokenEnhancer = tokenEnhancer;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public OAuth2TokenEntityService finish() {
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.mitre.oauth2.service.OAuth2TokenEntityService#saveAccessToken(org.mitre.oauth2.model.OAuth2AccessTokenEntity)
|
||||
*/
|
||||
@Override
|
||||
public OAuth2AccessTokenEntity saveAccessToken(OAuth2AccessTokenEntity accessToken) {
|
||||
return tokenRepository.saveAccessToken(accessToken);
|
||||
}
|
||||
* @see org.mitre.oauth2.service.OAuth2TokenEntityService#saveAccessToken(org.mitre.oauth2.model.OAuth2AccessTokenEntity)
|
||||
*/
|
||||
@Override
|
||||
public OAuth2AccessTokenEntity saveAccessToken(OAuth2AccessTokenEntity accessToken) {
|
||||
return tokenRepository.saveAccessToken(accessToken);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.mitre.oauth2.service.OAuth2TokenEntityService#saveRefreshToken(org.mitre.oauth2.model.OAuth2RefreshTokenEntity)
|
||||
*/
|
||||
@Override
|
||||
public OAuth2RefreshTokenEntity saveRefreshToken(OAuth2RefreshTokenEntity refreshToken) {
|
||||
return tokenRepository.saveRefreshToken(refreshToken);
|
||||
}
|
||||
* @see org.mitre.oauth2.service.OAuth2TokenEntityService#saveRefreshToken(org.mitre.oauth2.model.OAuth2RefreshTokenEntity)
|
||||
*/
|
||||
@Override
|
||||
public OAuth2RefreshTokenEntity saveRefreshToken(OAuth2RefreshTokenEntity refreshToken) {
|
||||
return tokenRepository.saveRefreshToken(refreshToken);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the tokenEnhancer
|
||||
|
@ -424,16 +424,16 @@ public class DefaultOAuth2ProviderTokenService implements OAuth2TokenEntityServi
|
|||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.mitre.oauth2.service.OAuth2TokenEntityService#getAccessTokenForIdToken(org.mitre.oauth2.model.OAuth2AccessTokenEntity)
|
||||
*/
|
||||
@Override
|
||||
public OAuth2AccessTokenEntity getAccessTokenForIdToken(OAuth2AccessTokenEntity idToken) {
|
||||
return tokenRepository.getAccessTokenForIdToken(idToken);
|
||||
}
|
||||
* @see org.mitre.oauth2.service.OAuth2TokenEntityService#getAccessTokenForIdToken(org.mitre.oauth2.model.OAuth2AccessTokenEntity)
|
||||
*/
|
||||
@Override
|
||||
public OAuth2AccessTokenEntity getAccessTokenForIdToken(OAuth2AccessTokenEntity idToken) {
|
||||
return tokenRepository.getAccessTokenForIdToken(idToken);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OAuth2AccessTokenEntity getAccessTokenById(Long id) {
|
||||
return tokenRepository.getAccessTokenById(id);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -29,132 +29,132 @@ public class DefaultSystemScopeService implements SystemScopeService {
|
|||
|
||||
@Autowired
|
||||
private SystemScopeRepository repository;
|
||||
|
||||
|
||||
private Predicate<SystemScope> isDefault = new Predicate<SystemScope>() {
|
||||
@Override
|
||||
public boolean apply(@Nullable SystemScope input) {
|
||||
public boolean apply(@Nullable SystemScope input) {
|
||||
return (input != null && input.isDefaultScope());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
private Predicate<SystemScope> isDynReg = new Predicate<SystemScope>() {
|
||||
@Override
|
||||
public boolean apply(@Nullable SystemScope input) {
|
||||
public boolean apply(@Nullable SystemScope input) {
|
||||
return (input != null && input.isAllowDynReg());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
private Function<String, SystemScope> stringToSystemScope = new Function<String, SystemScope>() {
|
||||
@Override
|
||||
public SystemScope apply(@Nullable String input) {
|
||||
public SystemScope apply(@Nullable String input) {
|
||||
if (input == null) {
|
||||
return null;
|
||||
} else {
|
||||
SystemScope s = getByValue(input);
|
||||
if (s != null) {
|
||||
// get the real scope if it's available
|
||||
return s;
|
||||
} else {
|
||||
// make a fake one otherwise
|
||||
return new SystemScope(input);
|
||||
}
|
||||
SystemScope s = getByValue(input);
|
||||
if (s != null) {
|
||||
// get the real scope if it's available
|
||||
return s;
|
||||
} else {
|
||||
// make a fake one otherwise
|
||||
return new SystemScope(input);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
private Function<SystemScope, String> systemScopeToString = new Function<SystemScope, String>() {
|
||||
@Override
|
||||
public String apply(@Nullable SystemScope input) {
|
||||
public String apply(@Nullable SystemScope input) {
|
||||
if (input == null) {
|
||||
return null;
|
||||
} else {
|
||||
return input.getValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.mitre.oauth2.service.SystemScopeService#getAll()
|
||||
*/
|
||||
@Override
|
||||
public Set<SystemScope> getAll() {
|
||||
return repository.getAll();
|
||||
}
|
||||
@Override
|
||||
public Set<SystemScope> getAll() {
|
||||
return repository.getAll();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.mitre.oauth2.service.SystemScopeService#getDefaults()
|
||||
*/
|
||||
@Override
|
||||
public Set<SystemScope> getDefaults() {
|
||||
@Override
|
||||
public Set<SystemScope> getDefaults() {
|
||||
return Sets.filter(getAll(), isDefault);
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.mitre.oauth2.service.SystemScopeService#getDynReg()
|
||||
*/
|
||||
@Override
|
||||
public Set<SystemScope> getDynReg() {
|
||||
return Sets.filter(getAll(), isDynReg);
|
||||
}
|
||||
@Override
|
||||
public Set<SystemScope> getDynReg() {
|
||||
return Sets.filter(getAll(), isDynReg);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.mitre.oauth2.service.SystemScopeService#getById(java.lang.Long)
|
||||
*/
|
||||
@Override
|
||||
public SystemScope getById(Long id) {
|
||||
return repository.getById(id);
|
||||
}
|
||||
@Override
|
||||
public SystemScope getById(Long id) {
|
||||
return repository.getById(id);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.mitre.oauth2.service.SystemScopeService#getByValue(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public SystemScope getByValue(String value) {
|
||||
return repository.getByValue(value);
|
||||
}
|
||||
@Override
|
||||
public SystemScope getByValue(String value) {
|
||||
return repository.getByValue(value);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.mitre.oauth2.service.SystemScopeService#remove(org.mitre.oauth2.model.SystemScope)
|
||||
*/
|
||||
@Override
|
||||
public void remove(SystemScope scope) {
|
||||
repository.remove(scope);
|
||||
|
||||
}
|
||||
@Override
|
||||
public void remove(SystemScope scope) {
|
||||
repository.remove(scope);
|
||||
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.mitre.oauth2.service.SystemScopeService#save(org.mitre.oauth2.model.SystemScope)
|
||||
*/
|
||||
@Override
|
||||
public SystemScope save(SystemScope scope) {
|
||||
return repository.save(scope);
|
||||
}
|
||||
@Override
|
||||
public SystemScope save(SystemScope scope) {
|
||||
return repository.save(scope);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.mitre.oauth2.service.SystemScopeService#fromStrings(java.util.Set)
|
||||
*/
|
||||
@Override
|
||||
public Set<SystemScope> fromStrings(Set<String> scope) {
|
||||
if (scope == null) {
|
||||
return null;
|
||||
} else {
|
||||
return new LinkedHashSet<SystemScope>(Collections2.filter(Collections2.transform(scope, stringToSystemScope), Predicates.notNull()));
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public Set<SystemScope> fromStrings(Set<String> scope) {
|
||||
if (scope == null) {
|
||||
return null;
|
||||
} else {
|
||||
return new LinkedHashSet<SystemScope>(Collections2.filter(Collections2.transform(scope, stringToSystemScope), Predicates.notNull()));
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.mitre.oauth2.service.SystemScopeService#toStrings(java.util.Set)
|
||||
*/
|
||||
@Override
|
||||
public Set<String> toStrings(Set<SystemScope> scope) {
|
||||
if (scope == null) {
|
||||
return null;
|
||||
} else {
|
||||
return new LinkedHashSet<String>(Collections2.filter(Collections2.transform(scope, systemScopeToString), Predicates.notNull()));
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public Set<String> toStrings(Set<SystemScope> scope) {
|
||||
if (scope == null) {
|
||||
return null;
|
||||
} else {
|
||||
return new LinkedHashSet<String>(Collections2.filter(Collections2.transform(scope, systemScopeToString), Predicates.notNull()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -30,12 +30,12 @@ import com.google.common.collect.Sets;
|
|||
public class ChainedTokenGranter extends AbstractTokenGranter {
|
||||
|
||||
private static final String grantType = "urn:ietf:params:oauth:grant_type:redelegate";
|
||||
|
||||
|
||||
// keep down-cast versions so we can get to the right queries
|
||||
private OAuth2TokenEntityService tokenServices;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param tokenServices
|
||||
* @param clientDetailsService
|
||||
|
@ -46,52 +46,52 @@ public class ChainedTokenGranter extends AbstractTokenGranter {
|
|||
super(tokenServices, clientDetailsService, requestFactory, grantType);
|
||||
this.tokenServices = tokenServices;
|
||||
}
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.security.oauth2.provider.token.AbstractTokenGranter#getOAuth2Authentication(org.springframework.security.oauth2.provider.AuthorizationRequest)
|
||||
*/
|
||||
@Override
|
||||
protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) throws AuthenticationException, InvalidTokenException {
|
||||
// read and load up the existing token
|
||||
String incomingTokenValue = tokenRequest.getRequestParameters().get("token");
|
||||
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)) {
|
||||
* @see org.springframework.security.oauth2.provider.token.AbstractTokenGranter#getOAuth2Authentication(org.springframework.security.oauth2.provider.AuthorizationRequest)
|
||||
*/
|
||||
@Override
|
||||
protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) throws AuthenticationException, InvalidTokenException {
|
||||
// read and load up the existing token
|
||||
String incomingTokenValue = tokenRequest.getRequestParameters().get("token");
|
||||
OAuth2AccessTokenEntity incomingToken = tokenServices.readAccessToken(incomingTokenValue);
|
||||
|
||||
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
|
||||
// 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()) {
|
||||
// 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -40,124 +40,124 @@ public class JwtAssertionTokenGranter extends AbstractTokenGranter {
|
|||
|
||||
// keep down-cast versions so we can get to the right queries
|
||||
private OAuth2TokenEntityService tokenServices;
|
||||
|
||||
|
||||
@Autowired
|
||||
private JwtSigningAndValidationService jwtService;
|
||||
|
||||
|
||||
@Autowired
|
||||
private ConfigurationPropertiesBean config;
|
||||
|
||||
|
||||
@Autowired
|
||||
public JwtAssertionTokenGranter(OAuth2TokenEntityService tokenServices, ClientDetailsEntityService clientDetailsService, OAuth2RequestFactory requestFactory) {
|
||||
super(tokenServices, clientDetailsService, requestFactory, grantType);
|
||||
this.tokenServices = tokenServices;
|
||||
}
|
||||
super(tokenServices, clientDetailsService, requestFactory, grantType);
|
||||
this.tokenServices = tokenServices;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.security.oauth2.provider.token.AbstractTokenGranter#getOAuth2Authentication(org.springframework.security.oauth2.provider.AuthorizationRequest)
|
||||
*/
|
||||
@Override
|
||||
protected OAuth2AccessToken getAccessToken(ClientDetails client, TokenRequest tokenRequest) throws AuthenticationException, InvalidTokenException {
|
||||
// read and load up the existing token
|
||||
String incomingTokenValue = tokenRequest.getRequestParameters().get("assertion");
|
||||
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");
|
||||
}
|
||||
* @see org.springframework.security.oauth2.provider.token.AbstractTokenGranter#getOAuth2Authentication(org.springframework.security.oauth2.provider.AuthorizationRequest)
|
||||
*/
|
||||
@Override
|
||||
protected OAuth2AccessToken getAccessToken(ClientDetails client, TokenRequest tokenRequest) throws AuthenticationException, InvalidTokenException {
|
||||
// read and load up the existing token
|
||||
String incomingTokenValue = tokenRequest.getRequestParameters().get("assertion");
|
||||
OAuth2AccessTokenEntity incomingToken = tokenServices.readAccessToken(incomingTokenValue);
|
||||
|
||||
// it's an ID token, process it accordingly
|
||||
|
||||
try {
|
||||
|
||||
// TODO: make this use a more specific idtoken class
|
||||
JWT idToken = JWTParser.parse(incomingTokenValue);
|
||||
|
||||
OAuth2AccessTokenEntity accessToken = tokenServices.getAccessTokenForIdToken(incomingToken);
|
||||
|
||||
if (accessToken != null) {
|
||||
|
||||
//OAuth2AccessTokenEntity newIdToken = tokenServices.get
|
||||
|
||||
OAuth2AccessTokenEntity newIdTokenEntity = new OAuth2AccessTokenEntity();
|
||||
|
||||
// copy over all existing claims
|
||||
JWTClaimsSet claims = new JWTClaimsSet(idToken.getJWTClaimsSet());
|
||||
|
||||
if (client instanceof ClientDetailsEntity) {
|
||||
|
||||
ClientDetailsEntity clientEntity = (ClientDetailsEntity) client;
|
||||
|
||||
// update expiration and issued-at claims
|
||||
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
|
||||
|
||||
try {
|
||||
|
||||
// TODO: make this use a more specific idtoken class
|
||||
JWT idToken = JWTParser.parse(incomingTokenValue);
|
||||
|
||||
OAuth2AccessTokenEntity accessToken = tokenServices.getAccessTokenForIdToken(incomingToken);
|
||||
|
||||
if (accessToken != null) {
|
||||
|
||||
//OAuth2AccessTokenEntity newIdToken = tokenServices.get
|
||||
|
||||
OAuth2AccessTokenEntity newIdTokenEntity = new OAuth2AccessTokenEntity();
|
||||
|
||||
// copy over all existing 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) {
|
||||
Date expiration = new Date(System.currentTimeMillis() + (clientEntity.getIdTokenValiditySeconds() * 1000L));
|
||||
claims.setExpirationTime(expiration);
|
||||
newIdTokenEntity.setExpiration(expiration);
|
||||
}
|
||||
|
||||
} else {
|
||||
//TODO: What should happen in this case? Is this possible?
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
//TODO: What should happen in this case? Is this possible?
|
||||
}
|
||||
|
||||
claims.setIssueTime(new Date());
|
||||
|
||||
|
||||
|
||||
|
||||
SignedJWT newIdToken = new SignedJWT((JWSHeader) idToken.getHeader(), claims);
|
||||
jwtService.signJwt(newIdToken);
|
||||
|
||||
jwtService.signJwt(newIdToken);
|
||||
|
||||
newIdTokenEntity.setJwt(newIdToken);
|
||||
newIdTokenEntity.setAuthenticationHolder(incomingToken.getAuthenticationHolder());
|
||||
newIdTokenEntity.setScope(incomingToken.getScope());
|
||||
newIdTokenEntity.setClient(incomingToken.getClient());
|
||||
|
||||
|
||||
newIdTokenEntity = tokenServices.saveAccessToken(newIdTokenEntity);
|
||||
|
||||
|
||||
// attach the ID token to the access token entity
|
||||
accessToken.setIdToken(newIdTokenEntity);
|
||||
accessToken = tokenServices.saveAccessToken(accessToken);
|
||||
|
||||
|
||||
// delete the old ID token
|
||||
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;
|
||||
|
||||
/*
|
||||
* Otherwise, process it like an access token assertion ... which we don't support yet so this is all commented out
|
||||
* /
|
||||
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;
|
||||
|
||||
/*
|
||||
* Otherwise, process it like an access token assertion ... which we don't support yet so this is all commented out
|
||||
* /
|
||||
if (jwtService.validateSignature(incomingTokenValue)) {
|
||||
|
||||
Jwt jwt = Jwt.parse(incomingTokenValue);
|
||||
|
||||
|
||||
|
||||
|
||||
if (oldToken.getScope().contains("id-token")) {
|
||||
// TODO: things
|
||||
}
|
||||
|
||||
|
||||
// TODO: should any of these throw an exception instead of returning null?
|
||||
JwtClaims claims = jwt.getClaims();
|
||||
if (!config.getIssuer().equals(claims.getIssuer())) {
|
||||
// issuer isn't us
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
if (!authorizationRequest.getClientId().equals(claims.getAudience())) {
|
||||
// audience isn't the client
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
Date now = new Date();
|
||||
if (!now.after(claims.getExpiration())) {
|
||||
// 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
|
||||
// need to handle id tokens separately.
|
||||
return new OAuth2Authentication(authorizationRequest, null);
|
||||
|
||||
|
||||
} else {
|
||||
return null; // throw error??
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -43,11 +43,11 @@ import com.google.gson.JsonSerializer;
|
|||
|
||||
@Component("tokenIntrospection")
|
||||
public class TokenIntrospectionView extends AbstractView {
|
||||
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(TokenIntrospectionView.class);
|
||||
|
||||
@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() {
|
||||
|
||||
|
@ -68,7 +68,7 @@ public class TokenIntrospectionView extends AbstractView {
|
|||
// serialize other classes without filter (lists and sets and things)
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -84,28 +84,29 @@ public class TokenIntrospectionView extends AbstractView {
|
|||
|
||||
})
|
||||
.registerTypeAdapter(OAuth2AccessTokenEntity.class, new JsonSerializer<OAuth2AccessTokenEntity>() {
|
||||
public JsonElement serialize(OAuth2AccessTokenEntity src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
JsonObject token = new JsonObject();
|
||||
|
||||
token.addProperty("valid", true);
|
||||
|
||||
JsonArray scopes = new JsonArray();
|
||||
for (String scope : src.getScope()) {
|
||||
scopes.add(new JsonPrimitive(scope));
|
||||
}
|
||||
token.add("scope", scopes);
|
||||
|
||||
token.add("expires_at", context.serialize(src.getExpiration()));
|
||||
|
||||
//token.addProperty("audience", src.getAuthenticationHolder().getAuthentication().getAuthorizationRequest().getClientId());
|
||||
|
||||
token.addProperty("subject", src.getAuthenticationHolder().getAuthentication().getName());
|
||||
|
||||
token.addProperty("client_id", src.getAuthenticationHolder().getAuthentication().getOAuth2Request().getClientId());
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement serialize(OAuth2AccessTokenEntity src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
JsonObject token = new JsonObject();
|
||||
|
||||
token.addProperty("valid", true);
|
||||
|
||||
JsonArray scopes = new JsonArray();
|
||||
for (String scope : src.getScope()) {
|
||||
scopes.add(new JsonPrimitive(scope));
|
||||
}
|
||||
token.add("scope", scopes);
|
||||
|
||||
token.add("expires_at", context.serialize(src.getExpiration()));
|
||||
|
||||
//token.addProperty("audience", src.getAuthenticationHolder().getAuthentication().getAuthorizationRequest().getClientId());
|
||||
|
||||
token.addProperty("subject", src.getAuthenticationHolder().getAuthentication().getName());
|
||||
|
||||
token.addProperty("client_id", src.getAuthenticationHolder().getAuthentication().getOAuth2Request().getClientId());
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
})
|
||||
.setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")
|
||||
.create();
|
||||
|
@ -113,9 +114,9 @@ public class TokenIntrospectionView extends AbstractView {
|
|||
response.setContentType("application/json");
|
||||
|
||||
Writer out;
|
||||
|
||||
|
||||
try {
|
||||
|
||||
|
||||
out = response.getWriter();
|
||||
Object obj = model.get("entity");
|
||||
if (obj == null) {
|
||||
|
@ -123,13 +124,13 @@ public class TokenIntrospectionView extends AbstractView {
|
|||
}
|
||||
|
||||
gson.toJson(obj, out);
|
||||
|
||||
|
||||
} catch (IOException e) {
|
||||
|
||||
|
||||
logger.error("IOException occurred in TokenIntrospectionView.java: ", e);
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -44,48 +44,48 @@ public class IntrospectionEndpoint {
|
|||
|
||||
@Autowired
|
||||
private OAuth2TokenEntityService tokenServices;
|
||||
|
||||
|
||||
@Autowired
|
||||
private ClientDetailsEntityService clientService;
|
||||
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(IntrospectionEndpoint.class);
|
||||
|
||||
|
||||
public IntrospectionEndpoint() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public IntrospectionEndpoint(OAuth2TokenEntityService tokenServices) {
|
||||
this.tokenServices = tokenServices;
|
||||
}
|
||||
|
||||
|
||||
@ExceptionHandler(InvalidTokenException.class)
|
||||
public ModelAndView tokenNotFound(InvalidTokenException ex) {
|
||||
Map<String,Boolean> e = ImmutableMap.of("valid", Boolean.FALSE);
|
||||
Map<String, Object> model = new HashMap<String, Object>();
|
||||
model.put("entity", e);
|
||||
|
||||
|
||||
logger.error("InvalidTokenException: ", ex);
|
||||
|
||||
|
||||
model.put("code", HttpStatus.BAD_REQUEST);
|
||||
|
||||
|
||||
return new ModelAndView("jsonEntityView", model);
|
||||
}
|
||||
|
||||
|
||||
@PreAuthorize("hasRole('ROLE_CLIENT')")
|
||||
@RequestMapping("/introspect")
|
||||
public ModelAndView verify(@RequestParam("token") String tokenValue, Principal p, ModelAndView modelAndView) {
|
||||
|
||||
|
||||
/*
|
||||
if (p != null && p instanceof OAuth2Authentication) {
|
||||
OAuth2Authentication auth = (OAuth2Authentication)p;
|
||||
|
||||
|
||||
if (auth.getDetails() != null && auth.getDetails() instanceof OAuth2AuthenticationDetails) {
|
||||
OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails)auth.getDetails();
|
||||
|
||||
|
||||
String tokenValue = details.getTokenValue();
|
||||
|
||||
|
||||
OAuth2AccessTokenEntity token = tokenServices.readAccessToken(tokenValue);
|
||||
|
||||
|
||||
if (token != null) {
|
||||
// if it's a valid token, we'll print out the scope and expiration
|
||||
modelAndView.setViewName("tokenIntrospection");
|
||||
|
@ -93,36 +93,36 @@ public class IntrospectionEndpoint {
|
|||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
if (Strings.isNullOrEmpty(tokenValue)) {
|
||||
logger.error("Verify failed; token value is null");
|
||||
modelAndView.addObject("code", HttpStatus.BAD_REQUEST);
|
||||
modelAndView.setViewName("httpCodeView");
|
||||
return modelAndView;
|
||||
}
|
||||
|
||||
|
||||
OAuth2AccessTokenEntity token = null;
|
||||
|
||||
|
||||
try {
|
||||
token = tokenServices.readAccessToken(tokenValue);
|
||||
token = tokenServices.readAccessToken(tokenValue);
|
||||
} catch (AuthenticationException e) {
|
||||
logger.error("Verify failed; AuthenticationException: ", e);
|
||||
modelAndView.addObject("code", HttpStatus.FORBIDDEN);
|
||||
modelAndView.setViewName("httpCodeView");
|
||||
return modelAndView;
|
||||
}
|
||||
|
||||
|
||||
ClientDetailsEntity tokenClient = token.getClient();
|
||||
// clientID is the principal name in the authentication
|
||||
String clientId = p.getName();
|
||||
ClientDetailsEntity authClient = clientService.loadClientByClientId(clientId);
|
||||
|
||||
|
||||
if (tokenClient != null && authClient != null) {
|
||||
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 (authClient.equals(tokenClient) || authClient.getScope().containsAll(token.getScope())) {
|
||||
|
||||
|
||||
// if it's a valid token, we'll print out information on it
|
||||
modelAndView.setViewName("tokenIntrospection");
|
||||
modelAndView.addObject("entity", token);
|
||||
|
@ -146,7 +146,7 @@ public class IntrospectionEndpoint {
|
|||
modelAndView.setViewName("httpCodeView");
|
||||
return modelAndView;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -51,20 +51,20 @@ public class OAuthConfirmationController {
|
|||
|
||||
@Autowired
|
||||
private ClientDetailsEntityService clientService;
|
||||
|
||||
|
||||
@Autowired
|
||||
private SystemScopeService scopeService;
|
||||
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(OAuthConfirmationController.class);
|
||||
|
||||
|
||||
public OAuthConfirmationController() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public OAuthConfirmationController(ClientDetailsEntityService clientService) {
|
||||
this.clientService = clientService;
|
||||
}
|
||||
|
||||
|
||||
@PreAuthorize("hasRole('ROLE_USER')")
|
||||
@RequestMapping("/oauth/confirm_access")
|
||||
public ModelAndView confimAccess(Map<String, Object> model, @ModelAttribute("authorizationRequest") AuthorizationRequest clientAuth) {
|
||||
|
@ -72,10 +72,10 @@ public class OAuthConfirmationController {
|
|||
//AuthorizationRequest clientAuth = (AuthorizationRequest) model.remove("authorizationRequest");
|
||||
|
||||
ClientDetails client = null;
|
||||
|
||||
|
||||
try {
|
||||
client = clientService.loadClientByClientId(clientAuth.getClientId());
|
||||
} catch (OAuth2Exception e) {
|
||||
} catch (OAuth2Exception e) {
|
||||
logger.error("confirmAccess: OAuth2Exception was thrown when attempting to load client: "
|
||||
, e);
|
||||
model.put("code", HttpStatus.BAD_REQUEST);
|
||||
|
@ -86,7 +86,7 @@ public class OAuthConfirmationController {
|
|||
model.put("code", HttpStatus.BAD_REQUEST);
|
||||
return new ModelAndView("httpCodeView");
|
||||
}
|
||||
|
||||
|
||||
if (client == null) {
|
||||
logger.error("confirmAccess: could not find client " + clientAuth.getClientId());
|
||||
model.put("code", HttpStatus.NOT_FOUND);
|
||||
|
@ -96,49 +96,49 @@ public class OAuthConfirmationController {
|
|||
model.put("client", client);
|
||||
|
||||
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>();
|
||||
for (String scope : clientAuth.getScope()) {
|
||||
scopes.put(scope, Boolean.TRUE);
|
||||
}
|
||||
*/
|
||||
|
||||
Set<SystemScope> scopes = scopeService.fromStrings(clientAuth.getScope());
|
||||
|
||||
Set<SystemScope> sortedScopes = new LinkedHashSet<SystemScope>(scopes.size());
|
||||
Set<SystemScope> systemScopes = scopeService.getAll();
|
||||
|
||||
// sort scopes for display
|
||||
for (SystemScope s : systemScopes) {
|
||||
if (scopes.contains(s)) {
|
||||
sortedScopes.add(s);
|
||||
}
|
||||
}
|
||||
|
||||
sortedScopes.addAll(Sets.difference(scopes, systemScopes));
|
||||
|
||||
model.put("scopes", sortedScopes);
|
||||
|
||||
return new ModelAndView("oauth/approve", model);
|
||||
*/
|
||||
|
||||
Set<SystemScope> scopes = scopeService.fromStrings(clientAuth.getScope());
|
||||
|
||||
Set<SystemScope> sortedScopes = new LinkedHashSet<SystemScope>(scopes.size());
|
||||
Set<SystemScope> systemScopes = scopeService.getAll();
|
||||
|
||||
// sort scopes for display
|
||||
for (SystemScope s : systemScopes) {
|
||||
if (scopes.contains(s)) {
|
||||
sortedScopes.add(s);
|
||||
}
|
||||
}
|
||||
|
||||
sortedScopes.addAll(Sets.difference(scopes, systemScopes));
|
||||
|
||||
model.put("scopes", sortedScopes);
|
||||
|
||||
return new ModelAndView("oauth/approve", model);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the clientService
|
||||
*/
|
||||
public ClientDetailsEntityService getClientService() {
|
||||
return clientService;
|
||||
}
|
||||
* @return the clientService
|
||||
*/
|
||||
public ClientDetailsEntityService getClientService() {
|
||||
return clientService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param clientService the clientService to set
|
||||
*/
|
||||
public void setClientService(ClientDetailsEntityService clientService) {
|
||||
this.clientService = clientService;
|
||||
}
|
||||
|
||||
|
||||
* @param clientService the clientService to set
|
||||
*/
|
||||
public void setClientService(ClientDetailsEntityService clientService) {
|
||||
this.clientService = clientService;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -38,52 +38,52 @@ import org.springframework.web.servlet.ModelAndView;
|
|||
public class RevocationEndpoint {
|
||||
@Autowired
|
||||
OAuth2TokenEntityService tokenServices;
|
||||
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(RevocationEndpoint.class);
|
||||
|
||||
|
||||
public RevocationEndpoint() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public RevocationEndpoint(OAuth2TokenEntityService tokenServices) {
|
||||
this.tokenServices = tokenServices;
|
||||
}
|
||||
|
||||
|
||||
// TODO
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_CLIENT')")
|
||||
@RequestMapping("/revoke")
|
||||
public ModelAndView revoke(@RequestParam("token") String tokenValue, Principal principal,
|
||||
ModelAndView modelAndView) {
|
||||
|
||||
|
||||
|
||||
OAuth2RefreshTokenEntity refreshToken = null;
|
||||
OAuth2AccessTokenEntity accessToken = null;
|
||||
try {
|
||||
refreshToken = tokenServices.getRefreshToken(tokenValue);
|
||||
} catch (InvalidTokenException e) {
|
||||
// it's OK if either of these tokens are bad
|
||||
//TODO: Error Handling
|
||||
}
|
||||
refreshToken = tokenServices.getRefreshToken(tokenValue);
|
||||
} catch (InvalidTokenException e) {
|
||||
// it's OK if either of these tokens are bad
|
||||
//TODO: Error Handling
|
||||
}
|
||||
|
||||
try {
|
||||
accessToken = tokenServices.readAccessToken(tokenValue);
|
||||
} catch (InvalidTokenException e) {
|
||||
// it's OK if either of these tokens are bad
|
||||
//TODO: Error Handling
|
||||
} catch (AuthenticationException e) {
|
||||
//TODO: Error Handling
|
||||
}
|
||||
|
||||
accessToken = tokenServices.readAccessToken(tokenValue);
|
||||
} catch (InvalidTokenException e) {
|
||||
// it's OK if either of these tokens are bad
|
||||
//TODO: Error Handling
|
||||
} catch (AuthenticationException e) {
|
||||
//TODO: Error Handling
|
||||
}
|
||||
|
||||
if (refreshToken == null && accessToken == null) {
|
||||
//TODO: Error Handling
|
||||
// TODO: this should throw a 400 with a JSON error code
|
||||
throw new InvalidTokenException("Invalid OAuth token: " + tokenValue);
|
||||
}
|
||||
|
||||
|
||||
if (principal instanceof OAuth2Authentication) {
|
||||
//TODO what is this variable for? It is unused. is it just a validation check?
|
||||
OAuth2AccessTokenEntity tok = tokenServices.getAccessToken((OAuth2Authentication) principal);
|
||||
|
||||
|
||||
// we've got a client acting on its own behalf, not an admin
|
||||
//ClientAuthentication clientAuth = (ClientAuthenticationToken) ((OAuth2Authentication) auth).getClientAuthentication();
|
||||
OAuth2Request clientAuth = ((OAuth2Authentication) principal).getOAuth2Request();
|
||||
|
@ -91,27 +91,27 @@ public class RevocationEndpoint {
|
|||
if (refreshToken != null) {
|
||||
if (!refreshToken.getClient().getClientId().equals(clientAuth.getClientId())) {
|
||||
// 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
|
||||
throw new PermissionDeniedException("Client tried to revoke a token it doesn't own");
|
||||
}
|
||||
} else {
|
||||
if (!accessToken.getClient().getClientId().equals(clientAuth.getClientId())) {
|
||||
// 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
|
||||
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 (refreshToken != null) {
|
||||
tokenServices.revokeRefreshToken(refreshToken);
|
||||
} else {
|
||||
tokenServices.revokeAccessToken(accessToken);
|
||||
}
|
||||
|
||||
|
||||
// TODO: throw a 200 back (no content?)
|
||||
return modelAndView;
|
||||
}
|
||||
|
|
|
@ -5,9 +5,6 @@ package org.mitre.oauth2.web;
|
|||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.persistence.EntityExistsException;
|
||||
import javax.persistence.TransactionRequiredException;
|
||||
|
||||
import org.mitre.oauth2.model.SystemScope;
|
||||
import org.mitre.oauth2.service.SystemScopeService;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -35,35 +32,35 @@ public class ScopeAPI {
|
|||
|
||||
@Autowired
|
||||
private SystemScopeService scopeService;
|
||||
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(ScopeAPI.class);
|
||||
|
||||
|
||||
private Gson gson = new Gson();
|
||||
|
||||
|
||||
@RequestMapping(value = "", method = RequestMethod.GET, produces = "application/json")
|
||||
public String getAll(ModelMap m) {
|
||||
|
||||
|
||||
Set<SystemScope> allScopes = scopeService.getAll();
|
||||
|
||||
|
||||
m.put("entity", allScopes);
|
||||
|
||||
|
||||
return "jsonEntityView";
|
||||
}
|
||||
|
||||
|
||||
@RequestMapping(value = "/{id}", method = RequestMethod.GET, produces = "application/json")
|
||||
public String getScope(@PathVariable("id") Long id, ModelMap m) {
|
||||
|
||||
|
||||
SystemScope scope = scopeService.getById(id);
|
||||
|
||||
|
||||
if (scope != null) {
|
||||
|
||||
|
||||
m.put("entity", scope);
|
||||
|
||||
|
||||
return "jsonEntityView";
|
||||
} else {
|
||||
|
||||
|
||||
logger.error("getScope failed; scope not found: " + id);
|
||||
|
||||
|
||||
m.put("code", HttpStatus.NOT_FOUND);
|
||||
m.put("errorMessage", "The requested scope with id " + id + " could not be found.");
|
||||
return "jsonErrorView";
|
||||
|
@ -73,46 +70,46 @@ public class ScopeAPI {
|
|||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||
@RequestMapping(value = "/{id}", method = RequestMethod.PUT, produces = "application/json", consumes = "application/json")
|
||||
public String updateScope(@PathVariable("id") Long id, @RequestBody String json, ModelMap m) {
|
||||
|
||||
|
||||
SystemScope existing = scopeService.getById(id);
|
||||
|
||||
|
||||
SystemScope scope = gson.fromJson(json, SystemScope.class);
|
||||
|
||||
|
||||
if (existing != null && scope != null) {
|
||||
|
||||
|
||||
if (existing.getId().equals(scope.getId())) {
|
||||
// sanity check
|
||||
|
||||
|
||||
scope = scopeService.save(scope);
|
||||
|
||||
|
||||
m.put("entity", scope);
|
||||
|
||||
|
||||
return "jsonEntityView";
|
||||
} 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());
|
||||
|
||||
|
||||
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());
|
||||
return "jsonErrorView";
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
logger.error("updateScope failed; scope with id " + id + " not found.");
|
||||
m.put("code", HttpStatus.NOT_FOUND);
|
||||
m.put("errorMessage", "Could not update scope. The scope with id " + id + " could not be found.");
|
||||
return "jsonErrorView";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||
@RequestMapping(value = "", method = RequestMethod.POST, produces = "application/json", consumes = "application/json")
|
||||
public String createScope(@RequestBody String json, ModelMap m) {
|
||||
SystemScope scope = gson.fromJson(json, SystemScope.class);
|
||||
|
||||
|
||||
SystemScope alreadyExists = scopeService.getByValue(scope.getValue());
|
||||
if (alreadyExists != null) {
|
||||
//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.");
|
||||
return "jsonErrorView";
|
||||
}
|
||||
|
||||
|
||||
scope = scopeService.save(scope);
|
||||
|
||||
if (scope != null && scope.getId() != null) {
|
||||
|
||||
m.put("entity", scope);
|
||||
|
||||
|
||||
return "jsonEntityView";
|
||||
} else {
|
||||
|
||||
|
||||
logger.error("createScope failed; JSON was invalid: " + json);
|
||||
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.");
|
||||
return "jsonErrorView";
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||
@RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
|
||||
public String deleteScope(@PathVariable("id") Long id, ModelMap m) {
|
||||
SystemScope existing = scopeService.getById(id);
|
||||
|
||||
|
||||
if (existing != null) {
|
||||
|
||||
scopeService.remove(existing);
|
||||
|
||||
|
||||
return "httpCodeView";
|
||||
} else {
|
||||
|
||||
|
||||
logger.error("deleteScope failed; scope with id " + id + " 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.");
|
||||
return "jsonErrorView";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -36,10 +36,10 @@ import com.nimbusds.jwt.SignedJWT;
|
|||
public class ConnectOAuth2RequestFactory extends DefaultOAuth2RequestFactory {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(ConnectOAuth2RequestFactory.class);
|
||||
|
||||
|
||||
//@Autowired
|
||||
private NonceService nonceService;
|
||||
|
||||
|
||||
//@Autowired
|
||||
private ClientDetailsEntityService clientDetailsService;
|
||||
|
||||
|
@ -58,7 +58,7 @@ public class ConnectOAuth2RequestFactory extends DefaultOAuth2RequestFactory {
|
|||
this.clientDetailsService = clientDetailsService;
|
||||
this.nonceService = nonceService;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Default empty constructor
|
||||
*/
|
||||
|
@ -70,28 +70,28 @@ public class ConnectOAuth2RequestFactory extends DefaultOAuth2RequestFactory {
|
|||
public AuthorizationRequest createAuthorizationRequest(Map<String, String> inputParams) {
|
||||
|
||||
Map<String, String> parameters = processRequestObject(inputParams);
|
||||
|
||||
|
||||
String clientId = parameters.get("client_id");
|
||||
ClientDetails client = null;
|
||||
|
||||
|
||||
if (clientId != null) {
|
||||
client = clientDetailsService.loadClientByClientId(clientId);
|
||||
}
|
||||
|
||||
|
||||
String requestNonce = parameters.get("nonce");
|
||||
|
||||
AuthorizationRequest request = new AuthorizationRequest(parameters, Collections.<String, String> emptyMap(),
|
||||
parameters.get(OAuth2Utils.CLIENT_ID),
|
||||
|
||||
AuthorizationRequest request = new AuthorizationRequest(parameters, Collections.<String, String> emptyMap(),
|
||||
parameters.get(OAuth2Utils.CLIENT_ID),
|
||||
OAuth2Utils.parseParameterList(parameters.get(OAuth2Utils.SCOPE)), null,
|
||||
null, false, parameters.get(OAuth2Utils.STATE),
|
||||
parameters.get(OAuth2Utils.REDIRECT_URI),
|
||||
null, false, parameters.get(OAuth2Utils.STATE),
|
||||
parameters.get(OAuth2Utils.REDIRECT_URI),
|
||||
OAuth2Utils.parseParameterList(parameters.get(OAuth2Utils.RESPONSE_TYPE)));
|
||||
|
||||
//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
|
||||
|
||||
//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
|
||||
//to the auth endpoint.
|
||||
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
|
||||
|
||||
|
||||
if (requestNonce != null && principal != null && principal instanceof User) {
|
||||
|
||||
if (!nonceService.alreadyUsed(clientId, requestNonce)) {
|
||||
|
@ -101,18 +101,18 @@ public class ConnectOAuth2RequestFactory extends DefaultOAuth2RequestFactory {
|
|||
else {
|
||||
throw new NonceReuseException(client == null ? "unidentified client" : client.getClientId(), requestNonce);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
Set<String> scopes = OAuth2Utils.parseParameterList(parameters.get("scope"));
|
||||
if ((scopes == null || scopes.isEmpty()) && client != null) {
|
||||
//TODO: do we want to allow default scoping at all?
|
||||
Set<String> clientScopes = client.getScope();
|
||||
scopes = clientScopes;
|
||||
}
|
||||
|
||||
|
||||
request.setScope(scopes);
|
||||
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
|
@ -120,46 +120,46 @@ public class ConnectOAuth2RequestFactory extends DefaultOAuth2RequestFactory {
|
|||
* @param inputParams
|
||||
* @return
|
||||
*/
|
||||
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;
|
||||
}
|
||||
private Map<String, String> processRequestObject(Map<String, String> inputParams) {
|
||||
|
||||
// start by copying over what's already in there
|
||||
Map<String, String> parameters = new HashMap<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
|
||||
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
|
||||
|
||||
|
||||
String clientId = JSONObjectUtils.getString(claims, "client_id");
|
||||
if (clientId != null) {
|
||||
parameters.put("client_id", clientId);
|
||||
}
|
||||
|
||||
|
||||
ClientDetailsEntity client = clientDetailsService.loadClientByClientId(clientId);
|
||||
|
||||
if (client.getJwksUri() == null) {
|
||||
throw new InvalidClientException("Client must have a JWK URI registered to use request objects.");
|
||||
}
|
||||
|
||||
|
||||
// check JWT signature
|
||||
JwtSigningAndValidationService validator = validators.get(client.getJwksUri());
|
||||
if (validator == null) {
|
||||
throw new InvalidClientException("Client must have a JWK URI registered to use request objects.");
|
||||
}
|
||||
|
||||
|
||||
if (!validator.validateSignature(jwsObject)) {
|
||||
throw new AuthenticationServiceException("Signature did not validate for presented JWT request object.");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* if (in Claims):
|
||||
* if (in params):
|
||||
|
@ -172,57 +172,57 @@ public class ConnectOAuth2RequestFactory extends DefaultOAuth2RequestFactory {
|
|||
* else (not in claims):
|
||||
* we don't care
|
||||
*/
|
||||
|
||||
|
||||
String responseTypes = JSONObjectUtils.getString(claims, "response_type");
|
||||
if (responseTypes != null) {
|
||||
parameters.put("response_type", responseTypes);
|
||||
}
|
||||
|
||||
|
||||
if (claims.get("redirect_uri") != null) {
|
||||
if (inputParams.containsKey("redirect_uri") == false) {
|
||||
parameters.put("redirect_uri", JSONObjectUtils.getString(claims, "redirect_uri"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
String state = JSONObjectUtils.getString(claims, "state");
|
||||
if(state != null) {
|
||||
if (inputParams.containsKey("state") == false) {
|
||||
parameters.put("state", state);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
String nonce = JSONObjectUtils.getString(claims, "nonce");
|
||||
if(nonce != null) {
|
||||
if (inputParams.containsKey("nonce") == false) {
|
||||
parameters.put("nonce", nonce);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
String display = JSONObjectUtils.getString(claims, "display");
|
||||
if (display != null) {
|
||||
if (inputParams.containsKey("display") == false) {
|
||||
parameters.put("display", display);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
String prompt = JSONObjectUtils.getString(claims, "prompt");
|
||||
if (prompt != null) {
|
||||
if (inputParams.containsKey("prompt") == false) {
|
||||
parameters.put("prompt", prompt);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
String scope = JSONObjectUtils.getString(claims, "scope");
|
||||
if (scope != null) {
|
||||
if (inputParams.containsKey("scope") == false) {
|
||||
parameters.put("scope", scope);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (ParseException e) {
|
||||
logger.error("ParseException while parsing RequestObject:", e);
|
||||
}
|
||||
|
||||
} catch (ParseException e) {
|
||||
logger.error("ParseException while parsing RequestObject:", e);
|
||||
}
|
||||
return parameters;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,19 +18,19 @@ public class JwtBearerAssertionAuthenticationToken extends AbstractAuthenticatio
|
|||
|
||||
private String clientId;
|
||||
private JWT jwt;
|
||||
|
||||
|
||||
/**
|
||||
* Create an unauthenticated token with the given client ID and jwt
|
||||
* @param clientId
|
||||
* @param jwt
|
||||
*/
|
||||
public JwtBearerAssertionAuthenticationToken(String clientId, JWT jwt) {
|
||||
super(null);
|
||||
this.clientId = clientId;
|
||||
this.jwt = jwt;
|
||||
setAuthenticated(false);
|
||||
}
|
||||
|
||||
super(null);
|
||||
this.clientId = clientId;
|
||||
this.jwt = jwt;
|
||||
setAuthenticated(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an authenticated token with the given clientID, jwt, and authorities set
|
||||
* @param clientId
|
||||
|
@ -38,11 +38,11 @@ public class JwtBearerAssertionAuthenticationToken extends AbstractAuthenticatio
|
|||
* @param authorities
|
||||
*/
|
||||
public JwtBearerAssertionAuthenticationToken(String clientId, JWT jwt, Collection<? extends GrantedAuthority> authorities) {
|
||||
super(authorities);
|
||||
this.clientId = clientId;
|
||||
this.jwt = jwt;
|
||||
setAuthenticated(true);
|
||||
}
|
||||
super(authorities);
|
||||
this.clientId = clientId;
|
||||
this.jwt = jwt;
|
||||
setAuthenticated(true);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.security.core.Authentication#getCredentials()
|
||||
|
@ -61,42 +61,42 @@ public class JwtBearerAssertionAuthenticationToken extends AbstractAuthenticatio
|
|||
}
|
||||
|
||||
/**
|
||||
* @return the clientId
|
||||
*/
|
||||
public String getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
* @return the clientId
|
||||
*/
|
||||
public String getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param clientId the clientId to set
|
||||
*/
|
||||
public void setClientId(String clientId) {
|
||||
this.clientId = clientId;
|
||||
}
|
||||
* @param clientId the clientId to set
|
||||
*/
|
||||
public void setClientId(String clientId) {
|
||||
this.clientId = clientId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the jwt
|
||||
*/
|
||||
public JWT getJwt() {
|
||||
return jwt;
|
||||
}
|
||||
* @return the jwt
|
||||
*/
|
||||
public JWT getJwt() {
|
||||
return jwt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param jwt the jwt to set
|
||||
*/
|
||||
public void setJwt(JWT jwt) {
|
||||
this.jwt = jwt;
|
||||
}
|
||||
* @param jwt the jwt to set
|
||||
*/
|
||||
public void setJwt(JWT jwt) {
|
||||
this.jwt = jwt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear out the JWT that this token holds.
|
||||
*/
|
||||
@Override
|
||||
public void eraseCredentials() {
|
||||
super.eraseCredentials();
|
||||
setJwt(null);
|
||||
}
|
||||
|
||||
|
||||
*/
|
||||
@Override
|
||||
public void eraseCredentials() {
|
||||
super.eraseCredentials();
|
||||
setJwt(null);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -36,49 +36,49 @@ public class JwtBearerAuthenticationProvider implements AuthenticationProvider {
|
|||
// map of verifiers, load keys for clients
|
||||
@Autowired
|
||||
private JWKSetSigningAndValidationServiceCacheService validators;
|
||||
|
||||
|
||||
// Allow for time sync issues by having a window of X seconds.
|
||||
private int timeSkewAllowance = 300;
|
||||
|
||||
// to load clients
|
||||
@Autowired
|
||||
private ClientDetailsEntityService clientService;
|
||||
|
||||
|
||||
// to get our server's issuer url
|
||||
@Autowired
|
||||
private ConfigurationPropertiesBean config;
|
||||
|
||||
|
||||
/**
|
||||
* Try to validate the client credentials by parsing and validating the JWT.
|
||||
*/
|
||||
@Override
|
||||
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
|
||||
|
||||
JwtBearerAssertionAuthenticationToken jwtAuth = (JwtBearerAssertionAuthenticationToken)authentication;
|
||||
|
||||
|
||||
try {
|
||||
ClientDetailsEntity client = clientService.loadClientByClientId(jwtAuth.getClientId());
|
||||
*/
|
||||
@Override
|
||||
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
|
||||
|
||||
JWT jwt = jwtAuth.getJwt();
|
||||
ReadOnlyJWTClaimsSet jwtClaims = jwt.getJWTClaimsSet();
|
||||
JwtBearerAssertionAuthenticationToken jwtAuth = (JwtBearerAssertionAuthenticationToken)authentication;
|
||||
|
||||
|
||||
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
|
||||
if (jwtClaims.getIssuer() == null) {
|
||||
throw new AuthenticationServiceException("Assertion Token Issuer is null");
|
||||
} else if (!jwtClaims.getIssuer().equals(client.getClientId())){
|
||||
throw new AuthenticationServiceException("Issuers do not match, expected " + client.getClientId() + " got " + jwtClaims.getIssuer());
|
||||
}
|
||||
|
||||
|
||||
// check expiration
|
||||
if (jwtClaims.getExpirationTime() == null) {
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// check not before
|
||||
if (jwtClaims.getNotBeforeTime() != null) {
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// check issued at
|
||||
if (jwtClaims.getIssueTime() != null) {
|
||||
// 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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// check audience
|
||||
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())) {
|
||||
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());
|
||||
|
||||
} catch (ClientNotFoundException e) {
|
||||
throw new UsernameNotFoundException("Could not find client: " + jwtAuth.getClientId());
|
||||
} catch (ParseException e) {
|
||||
// TODO Auto-generated catch block
|
||||
throw new AuthenticationServiceException("Invalid JWT format");
|
||||
}
|
||||
}
|
||||
|
||||
} catch (ClientNotFoundException e) {
|
||||
throw new UsernameNotFoundException("Could not find client: " + jwtAuth.getClientId());
|
||||
} catch (ParseException e) {
|
||||
// TODO Auto-generated catch block
|
||||
throw new AuthenticationServiceException("Invalid JWT format");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* We support {@link JwtBearerAssertionAuthenticationToken}s only.
|
||||
*/
|
||||
@Override
|
||||
public boolean supports(Class<?> authentication) {
|
||||
return (JwtBearerAssertionAuthenticationToken.class.isAssignableFrom(authentication));
|
||||
}
|
||||
*/
|
||||
@Override
|
||||
public boolean supports(Class<?> authentication) {
|
||||
return (JwtBearerAssertionAuthenticationToken.class.isAssignableFrom(authentication));
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -28,74 +28,74 @@ import com.nimbusds.jwt.JWTParser;
|
|||
public class JwtBearerClientAssertionTokenEndpointFilter extends ClientCredentialsTokenEndpointFilter {
|
||||
|
||||
public JwtBearerClientAssertionTokenEndpointFilter() {
|
||||
super();
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
super();
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
public JwtBearerClientAssertionTokenEndpointFilter(String path) {
|
||||
super(path);
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
super(path);
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
/**
|
||||
* Pull the assertion out of the request and send it up to the auth manager for processing.
|
||||
*/
|
||||
@Override
|
||||
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
|
||||
*/
|
||||
@Override
|
||||
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
|
||||
|
||||
// check for appropriate parameters
|
||||
String assertionType = request.getParameter("client_assertion_type");
|
||||
String assertion = request.getParameter("client_assertion");
|
||||
|
||||
try {
|
||||
JWT jwt = JWTParser.parse(assertion);
|
||||
|
||||
String clientId = jwt.getJWTClaimsSet().getSubject();
|
||||
|
||||
Authentication authRequest = new JwtBearerAssertionAuthenticationToken(clientId, jwt);
|
||||
|
||||
return this.getAuthenticationManager().authenticate(authRequest);
|
||||
} catch (ParseException e) {
|
||||
throw new BadCredentialsException("Invalid JWT credential: " + assertion);
|
||||
}
|
||||
}
|
||||
// check for appropriate parameters
|
||||
String assertionType = request.getParameter("client_assertion_type");
|
||||
String assertion = request.getParameter("client_assertion");
|
||||
|
||||
try {
|
||||
JWT jwt = JWTParser.parse(assertion);
|
||||
|
||||
String clientId = jwt.getJWTClaimsSet().getSubject();
|
||||
|
||||
Authentication authRequest = new JwtBearerAssertionAuthenticationToken(clientId, jwt);
|
||||
|
||||
return this.getAuthenticationManager().authenticate(authRequest);
|
||||
} catch (ParseException e) {
|
||||
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.
|
||||
*/
|
||||
@Override
|
||||
protected boolean requiresAuthentication(HttpServletRequest request, HttpServletResponse response) {
|
||||
// check for appropriate parameters
|
||||
String assertionType = request.getParameter("client_assertion_type");
|
||||
String assertion = request.getParameter("client_assertion");
|
||||
*/
|
||||
@Override
|
||||
protected boolean requiresAuthentication(HttpServletRequest request, HttpServletResponse response) {
|
||||
// check for appropriate parameters
|
||||
String assertionType = request.getParameter("client_assertion_type");
|
||||
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());
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -30,5 +30,5 @@ public class ExpiredTokenException extends RuntimeException {
|
|||
public ExpiredTokenException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -30,5 +30,5 @@ public class InvalidJwtIssuerException extends RuntimeException {
|
|||
public InvalidJwtIssuerException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ package org.mitre.openid.connect.exception;
|
|||
public class InvalidJwtSignatureException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
public InvalidJwtSignatureException() {
|
||||
super();
|
||||
}
|
||||
|
@ -30,5 +30,5 @@ public class InvalidJwtSignatureException extends RuntimeException {
|
|||
public InvalidJwtSignatureException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -20,9 +20,9 @@ package org.mitre.openid.connect.exception;
|
|||
*
|
||||
*/
|
||||
public class UnknownUserInfoSchemaException extends RuntimeException {
|
||||
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
public UnknownUserInfoSchemaException() {
|
||||
super();
|
||||
}
|
||||
|
@ -30,5 +30,5 @@ public class UnknownUserInfoSchemaException extends RuntimeException {
|
|||
public UnknownUserInfoSchemaException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -5,23 +5,23 @@ public class UserNotFoundException extends RuntimeException {
|
|||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public UserNotFoundException() {
|
||||
super();
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
super();
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
public UserNotFoundException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
super(message, cause);
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
public UserNotFoundException(String message) {
|
||||
super(message);
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
super(message);
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
public UserNotFoundException(Throwable cause) {
|
||||
super(cause);
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
super(cause);
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@ import javax.persistence.TypedQuery;
|
|||
|
||||
import org.mitre.openid.connect.model.ApprovedSite;
|
||||
import org.mitre.openid.connect.repository.ApprovedSiteRepository;
|
||||
import org.mitre.util.jpa.JpaUtil;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
|
@ -48,7 +47,7 @@ public class JpaApprovedSiteRepository implements ApprovedSiteRepository {
|
|||
"ApprovedSite.getAll", ApprovedSite.class);
|
||||
return query.getResultList();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public ApprovedSite getById(Long id) {
|
||||
|
@ -59,7 +58,7 @@ public class JpaApprovedSiteRepository implements ApprovedSiteRepository {
|
|||
@Transactional
|
||||
public void remove(ApprovedSite approvedSite) {
|
||||
ApprovedSite found = manager.find(ApprovedSite.class, approvedSite.getId());
|
||||
|
||||
|
||||
if (found != null) {
|
||||
manager.remove(found);
|
||||
} else {
|
||||
|
@ -75,30 +74,30 @@ public class JpaApprovedSiteRepository implements ApprovedSiteRepository {
|
|||
|
||||
@Override
|
||||
public Collection<ApprovedSite> getByClientIdAndUserId(String clientId, String userId) {
|
||||
|
||||
|
||||
TypedQuery<ApprovedSite> query = manager.createNamedQuery("ApprovedSite.getByClientIdAndUserId", ApprovedSite.class);
|
||||
query.setParameter("userId", userId);
|
||||
query.setParameter("clientId", clientId);
|
||||
|
||||
|
||||
return query.getResultList();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Collection<ApprovedSite> getByUserId(String userId) {
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Collection<ApprovedSite> getByUserId(String userId) {
|
||||
TypedQuery<ApprovedSite> query = manager.createNamedQuery("ApprovedSite.getByUserId", ApprovedSite.class);
|
||||
query.setParameter("userId", userId);
|
||||
|
||||
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);
|
||||
query.setParameter("clientId", clientId);
|
||||
|
||||
|
||||
return query.getResultList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ public class JpaBlacklistedSiteRepository implements BlacklistedSiteRepository {
|
|||
|
||||
@PersistenceContext
|
||||
private EntityManager manager;
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.mitre.openid.connect.repository.BlacklistedSiteRepository#getAll()
|
||||
*/
|
||||
|
@ -52,7 +52,7 @@ public class JpaBlacklistedSiteRepository implements BlacklistedSiteRepository {
|
|||
@Transactional
|
||||
public void remove(BlacklistedSite blacklistedSite) {
|
||||
BlacklistedSite found = manager.find(BlacklistedSite.class, blacklistedSite.getId());
|
||||
|
||||
|
||||
if (found != null) {
|
||||
manager.remove(found);
|
||||
} else {
|
||||
|
@ -79,7 +79,7 @@ public class JpaBlacklistedSiteRepository implements BlacklistedSiteRepository {
|
|||
|
||||
blacklistedSite.setId(oldBlacklistedSite.getId());
|
||||
return saveOrUpdate(oldBlacklistedSite.getId(), manager, blacklistedSite);
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ import org.springframework.transaction.annotation.Transactional;
|
|||
*/
|
||||
@Repository
|
||||
public class JpaEventRepository implements EventRepository {
|
||||
|
||||
|
||||
@PersistenceContext
|
||||
private EntityManager manager;
|
||||
|
||||
|
@ -52,17 +52,17 @@ public class JpaEventRepository implements EventRepository {
|
|||
@Override
|
||||
@Transactional
|
||||
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.setParameter("start", start, TemporalType.DATE);
|
||||
query = query.setParameter("end", end, TemporalType.DATE);
|
||||
query = query.setFirstResult(startChunk);
|
||||
query = query.setMaxResults(chunkSize);
|
||||
|
||||
query = query.setMaxResults(chunkSize);
|
||||
|
||||
return query.getResultList();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void remove(Event event) {
|
||||
|
|
|
@ -8,7 +8,6 @@ import javax.persistence.EntityManager;
|
|||
import javax.persistence.PersistenceContext;
|
||||
import javax.persistence.TypedQuery;
|
||||
|
||||
import org.mitre.openid.connect.model.ApprovedSite;
|
||||
import org.mitre.openid.connect.model.Nonce;
|
||||
import org.mitre.openid.connect.repository.NonceRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
@ -20,7 +19,7 @@ public class JpaNonceRepository implements NonceRepository {
|
|||
@PersistenceContext
|
||||
private EntityManager manager;
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Nonce getById(Long id) {
|
||||
|
@ -31,7 +30,7 @@ public class JpaNonceRepository implements NonceRepository {
|
|||
@Transactional
|
||||
public void remove(Nonce nonce) {
|
||||
Nonce found = manager.find(Nonce.class, nonce.getId());
|
||||
|
||||
|
||||
if (found != null) {
|
||||
manager.remove(found);
|
||||
} else {
|
||||
|
@ -65,7 +64,7 @@ public class JpaNonceRepository implements NonceRepository {
|
|||
public Collection<Nonce> getByClientId(String clientId) {
|
||||
TypedQuery<Nonce> query = manager.createNamedQuery("Nonce.getByClientId", Nonce.class);
|
||||
query.setParameter("clientId", clientId);
|
||||
|
||||
|
||||
return query.getResultList();
|
||||
}
|
||||
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
******************************************************************************/
|
||||
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.saveOrUpdate;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
|
@ -40,43 +40,43 @@ import org.springframework.transaction.annotation.Transactional;
|
|||
public class JpaUserInfoRepository implements UserInfoRepository {
|
||||
|
||||
@PersistenceContext
|
||||
private EntityManager manager;
|
||||
|
||||
private EntityManager manager;
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
@Transactional
|
||||
public UserInfo getBySubject(String sub) {
|
||||
TypedQuery<DefaultUserInfo> query = manager.createNamedQuery("DefaultUserInfo.getBySubject", DefaultUserInfo.class);
|
||||
query.setParameter("sub", sub);
|
||||
|
||||
|
||||
return getSingleResult(query.getResultList());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
@Transactional
|
||||
public UserInfo save(UserInfo userInfo) {
|
||||
DefaultUserInfo dui = (DefaultUserInfo)userInfo;
|
||||
return saveOrUpdate(dui.getId(), manager, dui);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
@Transactional
|
||||
public void remove(UserInfo userInfo) {
|
||||
DefaultUserInfo dui = (DefaultUserInfo)userInfo;
|
||||
UserInfo found = manager.find(DefaultUserInfo.class, dui.getId());
|
||||
|
||||
|
||||
if (found != null) {
|
||||
manager.remove(userInfo);
|
||||
} else {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
@Transactional
|
||||
public Collection<DefaultUserInfo> getAll() {
|
||||
|
||||
|
||||
TypedQuery<DefaultUserInfo> query = manager.createNamedQuery("DefaultUserInfo.getAll", DefaultUserInfo.class);
|
||||
|
||||
|
||||
return query.getResultList();
|
||||
}
|
||||
|
||||
|
@ -84,12 +84,12 @@ public class JpaUserInfoRepository implements UserInfoRepository {
|
|||
* Get a single UserInfo object by its username
|
||||
*/
|
||||
@Override
|
||||
public UserInfo getByUsername(String username) {
|
||||
public UserInfo getByUsername(String username) {
|
||||
TypedQuery<DefaultUserInfo> query = manager.createNamedQuery("DefaultUserInfo.getByUsername", DefaultUserInfo.class);
|
||||
query.setParameter("username", username);
|
||||
|
||||
|
||||
return getSingleResult(query.getResultList());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -77,10 +77,10 @@ public class JpaWhitelistedSiteRepository implements WhitelistedSiteRepository {
|
|||
public WhitelistedSite update(WhitelistedSite oldWhitelistedSite, WhitelistedSite whitelistedSite) {
|
||||
// sanity check
|
||||
whitelistedSite.setId(oldWhitelistedSite.getId());
|
||||
|
||||
|
||||
return saveOrUpdate(oldWhitelistedSite.getId(), manager, whitelistedSite);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public WhitelistedSite getByClientId(String clientId) {
|
||||
|
@ -94,7 +94,7 @@ public class JpaWhitelistedSiteRepository implements WhitelistedSiteRepository {
|
|||
public Collection<WhitelistedSite> getByCreator(String creatorId) {
|
||||
TypedQuery<WhitelistedSite> query = manager.createNamedQuery("WhitelistedSite.getByCreaterUserId", WhitelistedSite.class);
|
||||
query.setParameter("userId", creatorId);
|
||||
|
||||
|
||||
return query.getResultList();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,26 +42,26 @@ public class DefaultApprovedSiteService implements ApprovedSiteService {
|
|||
|
||||
@Autowired
|
||||
private ApprovedSiteRepository approvedSiteRepository;
|
||||
|
||||
|
||||
@Autowired
|
||||
private OAuth2TokenRepository tokenRepository;
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
*/
|
||||
public DefaultApprovedSiteService() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for use in test harnesses.
|
||||
*
|
||||
* @param repository
|
||||
*/
|
||||
|
||||
/**
|
||||
* Constructor for use in test harnesses.
|
||||
*
|
||||
* @param repository
|
||||
*/
|
||||
public DefaultApprovedSiteService(ApprovedSiteRepository approvedSiteRepository) {
|
||||
this.approvedSiteRepository = approvedSiteRepository;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ApprovedSite> getAll() {
|
||||
return approvedSiteRepository.getAll();
|
||||
|
@ -81,7 +81,7 @@ public class DefaultApprovedSiteService implements ApprovedSiteService {
|
|||
@Override
|
||||
@Transactional
|
||||
public void remove(ApprovedSite approvedSite) {
|
||||
|
||||
|
||||
//Remove any associated access and refresh tokens
|
||||
Set<OAuth2AccessTokenEntity> accessTokens = approvedSite.getApprovedAccessTokens();
|
||||
|
||||
|
@ -91,17 +91,17 @@ public class DefaultApprovedSiteService implements ApprovedSiteService {
|
|||
}
|
||||
tokenRepository.removeAccessToken(token);
|
||||
}
|
||||
|
||||
|
||||
approvedSiteRepository.remove(approvedSite);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public ApprovedSite createApprovedSite(String clientId, String userId, Date timeoutDate, Set<String> allowedScopes,
|
||||
WhitelistedSite whitelistedSite) {
|
||||
|
||||
WhitelistedSite whitelistedSite) {
|
||||
|
||||
ApprovedSite as = approvedSiteRepository.save(new ApprovedSite());
|
||||
|
||||
|
||||
Date now = new Date();
|
||||
as.setCreationDate(now);
|
||||
as.setAccessDate(now);
|
||||
|
@ -110,47 +110,47 @@ public class DefaultApprovedSiteService implements ApprovedSiteService {
|
|||
as.setTimeoutDate(timeoutDate);
|
||||
as.setAllowedScopes(allowedScopes);
|
||||
as.setWhitelistedSite(whitelistedSite);
|
||||
|
||||
|
||||
return save(as);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ApprovedSite> getByClientIdAndUserId(String clientId, String userId) {
|
||||
|
||||
|
||||
return approvedSiteRepository.getByClientIdAndUserId(clientId, userId);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param userId
|
||||
* @return
|
||||
* @see org.mitre.openid.connect.repository.ApprovedSiteRepository#getByUserId(java.lang.String)
|
||||
*/
|
||||
* @param userId
|
||||
* @return
|
||||
* @see org.mitre.openid.connect.repository.ApprovedSiteRepository#getByUserId(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public Collection<ApprovedSite> getByUserId(String userId) {
|
||||
return approvedSiteRepository.getByUserId(userId);
|
||||
}
|
||||
public Collection<ApprovedSite> getByUserId(String userId) {
|
||||
return approvedSiteRepository.getByUserId(userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param clientId
|
||||
* @return
|
||||
* @see org.mitre.openid.connect.repository.ApprovedSiteRepository#getByClientId(java.lang.String)
|
||||
*/
|
||||
* @param clientId
|
||||
* @return
|
||||
* @see org.mitre.openid.connect.repository.ApprovedSiteRepository#getByClientId(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public Collection<ApprovedSite> getByClientId(String clientId) {
|
||||
return approvedSiteRepository.getByClientId(clientId);
|
||||
}
|
||||
public Collection<ApprovedSite> getByClientId(String clientId) {
|
||||
return approvedSiteRepository.getByClientId(clientId);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void clearApprovedSitesForClient(ClientDetails client) {
|
||||
Collection<ApprovedSite> approvedSites = approvedSiteRepository.getByClientId(client.getClientId());
|
||||
Collection<ApprovedSite> approvedSites = approvedSiteRepository.getByClientId(client.getClientId());
|
||||
if (approvedSites != null) {
|
||||
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
Loading…
Reference in New Issue