From 939a8010484fbbb9e6dbbc5bde6aef7e8d0980af Mon Sep 17 00:00:00 2001 From: Amanda Anganes Date: Tue, 23 Apr 2013 17:40:22 -0400 Subject: [PATCH] Redid approved site -> token mapping so it is unidirectional from ApprovedSite side. Fixed some error logging, added a new view for ApprovedSite which will only show the IDs of the tokens in the approvedTokens list --- .../oauth2/model/OAuth2AccessTokenEntity.java | 36 ++++---- .../service/OAuth2TokenEntityService.java | 2 + .../openid/connect/model/ApprovedSite.java | 11 +-- .../DefaultOAuth2ProviderTokenService.java | 27 +++++- .../connect/token/ConnectTokenEnhancer.java | 12 +-- .../token/TofuUserApprovalHandler.java | 6 +- .../connect/view/JsonApprovedSiteView.java | 89 +++++++++++++++++++ .../openid/connect/web/ApprovedSiteAPI.java | 4 +- 8 files changed, 147 insertions(+), 40 deletions(-) create mode 100644 openid-connect-server/src/main/java/org/mitre/openid/connect/view/JsonApprovedSiteView.java diff --git a/openid-connect-common/src/main/java/org/mitre/oauth2/model/OAuth2AccessTokenEntity.java b/openid-connect-common/src/main/java/org/mitre/oauth2/model/OAuth2AccessTokenEntity.java index 6bf6111ef..ad713b761 100644 --- a/openid-connect-common/src/main/java/org/mitre/oauth2/model/OAuth2AccessTokenEntity.java +++ b/openid-connect-common/src/main/java/org/mitre/oauth2/model/OAuth2AccessTokenEntity.java @@ -91,7 +91,23 @@ public class OAuth2AccessTokenEntity implements OAuth2AccessToken { private Set scope; - private ApprovedSite approvedSite; //Back-reference for one-to-many relationship +// private ApprovedSite approvedSite; +// +// /** +// * @return the approvedSite +// */ +// @ManyToOne(fetch=FetchType.EAGER) +// @JoinColumn(name="approved_site_id", referencedColumnName="id") +// public ApprovedSite getApprovedSite() { +// return approvedSite; +// } +// +// /** +// * @param approvedSite the approvedSite to set +// */ +// public void setApprovedSite(ApprovedSite approvedSite) { +// this.approvedSite = approvedSite; +// } /** * Create a new, blank access token @@ -167,7 +183,7 @@ public class OAuth2AccessTokenEntity implements OAuth2AccessToken { @Basic @Column(name="token_value") public String getValue() { - return jwtValue.serialize(); + return jwtValue.serialize(); } /** @@ -177,7 +193,7 @@ public class OAuth2AccessTokenEntity implements OAuth2AccessToken { * @throws ParseException if "value" is not a properly formatted JWT string */ public void setValue(String value) throws ParseException { - setJwt(JWTParser.parse(value)); + setJwt(JWTParser.parse(value)); } @Basic @@ -286,19 +302,5 @@ public class OAuth2AccessTokenEntity implements OAuth2AccessToken { return 0; } - /** - * @return the approvedSite - */ - @ManyToOne(fetch=FetchType.EAGER) - @JoinColumn(name="approved_site_id", referencedColumnName="id") - public ApprovedSite getApprovedSite() { - return approvedSite; - } - /** - * @param approvedSite the approvedSite to set - */ - public void setApprovedSite(ApprovedSite approvedSite) { - this.approvedSite = approvedSite; - } } diff --git a/openid-connect-common/src/main/java/org/mitre/oauth2/service/OAuth2TokenEntityService.java b/openid-connect-common/src/main/java/org/mitre/oauth2/service/OAuth2TokenEntityService.java index cdb25b6a7..1780a5c17 100644 --- a/openid-connect-common/src/main/java/org/mitre/oauth2/service/OAuth2TokenEntityService.java +++ b/openid-connect-common/src/main/java/org/mitre/oauth2/service/OAuth2TokenEntityService.java @@ -45,6 +45,8 @@ public interface OAuth2TokenEntityService extends AuthorizationServerTokenServic public OAuth2RefreshTokenEntity saveRefreshToken(OAuth2RefreshTokenEntity refreshToken); public OAuth2AccessTokenEntity getAccessToken(OAuth2Authentication authentication); + + public OAuth2AccessTokenEntity getAccessTokenById(Long id); /** * @param incomingToken diff --git a/openid-connect-common/src/main/java/org/mitre/openid/connect/model/ApprovedSite.java b/openid-connect-common/src/main/java/org/mitre/openid/connect/model/ApprovedSite.java index 245ded4df..2e0205697 100644 --- a/openid-connect-common/src/main/java/org/mitre/openid/connect/model/ApprovedSite.java +++ b/openid-connect-common/src/main/java/org/mitre/openid/connect/model/ApprovedSite.java @@ -246,10 +246,8 @@ public class ApprovedSite implements Serializable { } } - /** - * @return the approvedAccessTokens - */ - @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="approvedSite") + @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER) + @JoinColumn(name="approved_site_id") public Set getApprovedAccessTokens() { return approvedAccessTokens; } @@ -261,11 +259,6 @@ public class ApprovedSite implements Serializable { this.approvedAccessTokens = approvedAccessTokens; } - public void addApprovedAccessToken(OAuth2AccessTokenEntity token) { - this.getApprovedAccessTokens(); - this.approvedAccessTokens.add(token); - } - /* (non-Javadoc) * @see java.lang.Object#hashCode() */ diff --git a/openid-connect-server/src/main/java/org/mitre/oauth2/service/impl/DefaultOAuth2ProviderTokenService.java b/openid-connect-server/src/main/java/org/mitre/oauth2/service/impl/DefaultOAuth2ProviderTokenService.java index 57f38db77..559cac112 100644 --- a/openid-connect-server/src/main/java/org/mitre/oauth2/service/impl/DefaultOAuth2ProviderTokenService.java +++ b/openid-connect-server/src/main/java/org/mitre/oauth2/service/impl/DefaultOAuth2ProviderTokenService.java @@ -32,6 +32,8 @@ import org.mitre.oauth2.repository.AuthenticationHolderRepository; import org.mitre.oauth2.repository.OAuth2TokenRepository; import org.mitre.oauth2.service.ClientDetailsEntityService; import org.mitre.oauth2.service.OAuth2TokenEntityService; +import org.mitre.openid.connect.model.ApprovedSite; +import org.mitre.openid.connect.service.ApprovedSiteService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -71,6 +73,9 @@ public class DefaultOAuth2ProviderTokenService implements OAuth2TokenEntityServi @Autowired private TokenEnhancer tokenEnhancer; + @Autowired + private ApprovedSiteService approvedSiteService; + @Override public OAuth2AccessTokenEntity createAccessToken(OAuth2Authentication authentication) throws AuthenticationException, InvalidClientException { if (authentication != null && authentication.getAuthorizationRequest() != null) { @@ -140,11 +145,26 @@ public class DefaultOAuth2ProviderTokenService implements OAuth2TokenEntityServi token.setRefreshToken(refreshToken); } - + tokenEnhancer.enhance(token, authentication); tokenRepository.saveAccessToken(token); + //Add approved site reference, if any + AuthorizationRequest originalAuthRequest = authHolder.getAuthentication().getAuthorizationRequest(); + + if (originalAuthRequest.getExtensionProperties().containsKey("approved_site")) { + + Long apId = (Long) originalAuthRequest.getExtensionProperties().get("approved_site"); + ApprovedSite ap = approvedSiteService.getById(apId); + //token.setApprovedSite(ap); + Set 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 } @@ -410,5 +430,10 @@ public class DefaultOAuth2ProviderTokenService implements OAuth2TokenEntityServi public OAuth2AccessTokenEntity getAccessTokenForIdToken(OAuth2AccessTokenEntity idToken) { return tokenRepository.getAccessTokenForIdToken(idToken); } + + @Override + public OAuth2AccessTokenEntity getAccessTokenById(Long id) { + return tokenRepository.getAccessTokenById(id); + } } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/token/ConnectTokenEnhancer.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/token/ConnectTokenEnhancer.java index 586d4e721..679348bd6 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/token/ConnectTokenEnhancer.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/token/ConnectTokenEnhancer.java @@ -24,7 +24,7 @@ import org.mitre.oauth2.model.ClientDetailsEntity; import org.mitre.oauth2.model.OAuth2AccessTokenEntity; import org.mitre.oauth2.service.ClientDetailsEntityService; import org.mitre.openid.connect.config.ConfigurationPropertiesBean; -import org.mitre.openid.connect.model.ApprovedSite; +import org.mitre.openid.connect.service.ApprovedSiteService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -55,19 +55,15 @@ public class ConnectTokenEnhancer implements TokenEnhancer { @Autowired private ClientDetailsEntityService clientService; + @Autowired + private ApprovedSiteService approvedSiteService; + @Override public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) { OAuth2AccessTokenEntity token = (OAuth2AccessTokenEntity) accessToken; AuthorizationRequest originalAuthRequest = authentication.getAuthorizationRequest(); - if (originalAuthRequest.getExtensionProperties().containsKey("approved_site")) { - //Add the token to the approved site reference, if there is one - ApprovedSite ap = (ApprovedSite)originalAuthRequest.getExtensionProperties().get("approved_site"); - //ap.addApprovedAccessToken(token); - token.setApprovedSite(ap); - } - String clientId = originalAuthRequest.getClientId(); ClientDetailsEntity client = clientService.loadClientByClientId(clientId); diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/token/TofuUserApprovalHandler.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/token/TofuUserApprovalHandler.java index ddbb3539d..0c28406ac 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/token/TofuUserApprovalHandler.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/token/TofuUserApprovalHandler.java @@ -117,7 +117,7 @@ public class TofuUserApprovalHandler implements UserApprovalHandler { ap.setAccessDate(new Date()); approvedSiteService.save(ap); - authorizationRequest.getExtensionProperties().put("approved_site", ap); + authorizationRequest.getExtensionProperties().put("approved_site", ap.getId()); authorizationRequest.setApproved(true); alreadyApproved = true; } @@ -130,7 +130,7 @@ public class TofuUserApprovalHandler implements UserApprovalHandler { //Create an approved site ApprovedSite newSite = approvedSiteService.createApprovedSite(clientId, userId, null, ws.getAllowedScopes(), ws); - authorizationRequest.getExtensionProperties().put("approved_site", newSite); + authorizationRequest.getExtensionProperties().put("approved_site", newSite.getId()); authorizationRequest.setApproved(true); } } @@ -192,7 +192,7 @@ public class TofuUserApprovalHandler implements UserApprovalHandler { } ApprovedSite newSite = approvedSiteService.createApprovedSite(clientId, userId, timeout, allowedScopes, null); - authorizationRequest.getExtensionProperties().put("approved_site", newSite); + authorizationRequest.getExtensionProperties().put("approved_site", newSite.getId()); } } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/view/JsonApprovedSiteView.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/view/JsonApprovedSiteView.java new file mode 100644 index 000000000..ebeeb8961 --- /dev/null +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/view/JsonApprovedSiteView.java @@ -0,0 +1,89 @@ +/** + * + */ +package org.mitre.openid.connect.view; + +import java.io.IOException; +import java.io.Writer; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.mitre.oauth2.model.OAuth2AccessTokenEntity; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Component; +import org.springframework.validation.BeanPropertyBindingResult; +import org.springframework.web.servlet.view.AbstractView; + +import com.google.gson.ExclusionStrategy; +import com.google.gson.FieldAttributes; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +/** + * @author jricher + * + */ +@Component("jsonApprovedSiteView") +public class JsonApprovedSiteView extends AbstractView { + + private static Logger logger = LoggerFactory.getLogger(JsonApprovedSiteView.class); + + private Gson gson = new GsonBuilder() + .setExclusionStrategies(new ExclusionStrategy() { + + public boolean shouldSkipField(FieldAttributes f) { + + if (f.getDeclaringClass() == OAuth2AccessTokenEntity.class) { + if (f.getName().equals("id")) { + return false; + } + return true; + } + + return false; + } + + public boolean shouldSkipClass(Class clazz) { + // skip the JPA binding wrapper + if (clazz.equals(BeanPropertyBindingResult.class)) { + return true; + } + return false; + } + + }) + .serializeNulls() + .setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ") + .create(); + + protected void renderMergedOutputModel(Map model, HttpServletRequest request, HttpServletResponse response) { + + response.setContentType("application/json"); + + + HttpStatus code = (HttpStatus) model.get("code"); + if (code == null) { + code = HttpStatus.OK; // default to 200 + } + + response.setStatus(code.value()); + + try { + + Writer out = response.getWriter(); + Object obj = model.get("entity"); + gson.toJson(obj, out); + + } catch (IOException e) { + + //TODO: Error Handling + logger.error("IOException in JsonEntityView.java: ", e); + + } + } + +} diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/web/ApprovedSiteAPI.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/web/ApprovedSiteAPI.java index 5c3907165..5049fb48e 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/web/ApprovedSiteAPI.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/web/ApprovedSiteAPI.java @@ -51,7 +51,7 @@ public class ApprovedSiteAPI { m.put("entity", all); - return "jsonEntityView"; + return "jsonApprovedSiteView"; } /** @@ -112,7 +112,7 @@ public class ApprovedSiteAPI { return "jsonErrorView"; } else { m.put("entity", approvedSite); - return "jsonEntityView"; + return "jsonApprovedSiteView"; } }