diff --git a/orcid-core/src/main/java/org/orcid/core/common/manager/impl/EventManagerImpl.java b/orcid-core/src/main/java/org/orcid/core/common/manager/impl/EventManagerImpl.java index ef94b970d14..4dde9c4374f 100644 --- a/orcid-core/src/main/java/org/orcid/core/common/manager/impl/EventManagerImpl.java +++ b/orcid-core/src/main/java/org/orcid/core/common/manager/impl/EventManagerImpl.java @@ -20,7 +20,6 @@ import org.orcid.persistence.jpa.entities.EventEntity; import org.orcid.persistence.jpa.entities.EventType; import org.orcid.pojo.ajaxForm.PojoUtil; -import org.orcid.pojo.ajaxForm.RequestInfoForm; /** * @@ -45,11 +44,7 @@ public void createEvent(EventType eventType, HttpServletRequest request) { if (request != null) { Boolean isOauth2ScreensRequest = (Boolean) request.getSession().getAttribute(OrcidOauth2Constants.OAUTH_2SCREENS); - RequestInfoForm requestInfoForm = (RequestInfoForm) request.getSession().getAttribute("requestInfoForm"); - if (requestInfoForm != null) { - clientId = requestInfoForm.getClientId(); - label = "OAuth " + requestInfoForm.getMemberName() + " " + requestInfoForm.getClientName(); - } else if (isOauth2ScreensRequest != null && isOauth2ScreensRequest) { + if (isOauth2ScreensRequest != null && isOauth2ScreensRequest) { String queryString = (String) request.getSession().getAttribute(OrcidOauth2Constants.OAUTH_QUERY_STRING); clientId = getParameterValue(queryString, "client_id"); ClientDetailsEntity clientDetailsEntity = clientDetailsEntityCacheManager.retrieve(clientId); diff --git a/orcid-persistence/src/main/java/org/orcid/persistence/jpa/entities/ClientDetailsEntity.java b/orcid-persistence/src/main/java/org/orcid/persistence/jpa/entities/ClientDetailsEntity.java index 95df58c61cd..bea2df9a6eb 100644 --- a/orcid-persistence/src/main/java/org/orcid/persistence/jpa/entities/ClientDetailsEntity.java +++ b/orcid-persistence/src/main/java/org/orcid/persistence/jpa/entities/ClientDetailsEntity.java @@ -208,9 +208,7 @@ public Set getResourceIds() { Set rids = new HashSet(); if (clientResourceIds != null && !clientResourceIds.isEmpty()) { for (ClientResourceIdEntity resourceIdEntity : clientResourceIds) { - if(resourceIdEntity.getId() != null) { - rids.add(resourceIdEntity.getId().getResourceId()); - } + rids.add(resourceIdEntity.getResourceId()); } } return rids; @@ -277,7 +275,7 @@ public String getClientSecretForJpa() { if (clientSecrets == null || clientSecrets.isEmpty()) { return null; } - return clientSecrets.first().getId().getClientSecret(); + return clientSecrets.first().getClientSecret(); } public void setClientSecretForJpa(String clientSecret) { @@ -327,7 +325,7 @@ public Set getScope() { Set sps = new HashSet(); if (clientScopes != null && !clientScopes.isEmpty()) { for (ClientScopeEntity cse : clientScopes) { - sps.add(cse.getId().getScopeType()); + sps.add(cse.getScopeType()); } } return sps; @@ -344,9 +342,7 @@ public Set getAuthorizedGrantTypes() { Set grants = new HashSet(); if (clientAuthorizedGrantTypes != null && !clientAuthorizedGrantTypes.isEmpty()) { for (ClientAuthorisedGrantTypeEntity cagt : clientAuthorizedGrantTypes) { - if(cagt.getId() != null) { - grants.add(cagt.getId().getGrantType()); - } + grants.add(cagt.getGrantType()); } } return grants; @@ -365,9 +361,7 @@ public Set getRegisteredRedirectUri() { if (clientRegisteredRedirectUris != null && !clientRegisteredRedirectUris.isEmpty()) { redirects = new HashSet(); for (ClientRedirectUriEntity cru : clientRegisteredRedirectUris) { - if(cru.getId() != null) { - redirects.add(cru.getId().getRedirectUri()); - } + redirects.add(cru.getRedirectUri()); } } return redirects; diff --git a/orcid-persistence/src/main/java/org/orcid/persistence/jpa/entities/ClientGrantedAuthorityEntity.java b/orcid-persistence/src/main/java/org/orcid/persistence/jpa/entities/ClientGrantedAuthorityEntity.java index 4d31d2259f3..1d34a930372 100644 --- a/orcid-persistence/src/main/java/org/orcid/persistence/jpa/entities/ClientGrantedAuthorityEntity.java +++ b/orcid-persistence/src/main/java/org/orcid/persistence/jpa/entities/ClientGrantedAuthorityEntity.java @@ -31,13 +31,12 @@ public void setClientId(String clientId) { @Id @Column(name = "granted_authority") - public void setAuthority(String authority) { - this.authority = authority; + public String getAuthority() { + return this.authority; } - @Override - public String getAuthority() { - return this.getAuthority(); + public void setAuthority(String authority) { + this.authority = authority; } @Override diff --git a/orcid-web/src/main/java/org/orcid/frontend/oauth2/OauthController.java b/orcid-web/src/main/java/org/orcid/frontend/oauth2/OauthController.java index cef46258e7b..5375838854a 100644 --- a/orcid-web/src/main/java/org/orcid/frontend/oauth2/OauthController.java +++ b/orcid-web/src/main/java/org/orcid/frontend/oauth2/OauthController.java @@ -23,6 +23,9 @@ import org.orcid.core.oauth.service.OrcidAuthorizationEndpoint; import org.orcid.core.oauth.service.OrcidOAuth2RequestValidator; import org.orcid.core.togglz.Features; +import org.orcid.frontend.util.AuthorizationRequestLocalCache; +import org.orcid.frontend.util.OriginalAuthorizationRequestLocalCache; +import org.orcid.frontend.util.RequestInfoFormLocalCache; import org.orcid.frontend.web.controllers.BaseControllerUtil; import org.orcid.frontend.web.controllers.helper.OauthHelper; import org.orcid.frontend.web.exception.OauthInvalidRequestException; @@ -82,12 +85,23 @@ public class OauthController { @Resource private EventManager eventManager; + @Resource + private RequestInfoFormLocalCache requestInfoFormLocalCache; + + @Resource + private AuthorizationRequestLocalCache authorizationRequestLocalCache; + + @Resource + private OriginalAuthorizationRequestLocalCache originalAuthorizationRequestLocalCache; + @RequestMapping(value = { "/oauth/custom/init.json" }, method = RequestMethod.POST) public @ResponseBody RequestInfoForm loginGetHandler(HttpServletRequest request, Map model, @RequestParam Map requestParameters, SessionStatus sessionStatus, Principal principal) throws UnsupportedEncodingException { // Populate the request info form - RequestInfoForm requestInfoForm = generateRequestInfoForm(request, request.getQueryString(), model, requestParameters, sessionStatus, principal); - request.getSession().setAttribute(OauthHelper.REQUEST_INFO_FORM, requestInfoForm); + RequestInfoForm requestInfoForm = generateRequestInfoForm(request, request.getQueryString(), model, requestParameters, sessionStatus, principal); + + // Store the request info form in the cache + requestInfoFormLocalCache.put(request.getSession().getId(), requestInfoForm); boolean isResponseSet = false; @@ -136,8 +150,9 @@ public class OauthController { @RequestMapping(value = { "/oauth/custom/authorize.json" }, method = RequestMethod.GET) public @ResponseBody RequestInfoForm requestInfoForm(HttpServletRequest request, Map model, @RequestParam Map requestParameters, SessionStatus sessionStatus, Principal principal) throws UnsupportedEncodingException { - RequestInfoForm requestInfoForm = oauthHelper.setUserRequestInfoForm((RequestInfoForm) request.getSession().getAttribute(OauthHelper.REQUEST_INFO_FORM)); - request.getSession().setAttribute(OauthHelper.REQUEST_INFO_FORM, requestInfoForm); + RequestInfoForm requestInfoForm = requestInfoFormLocalCache.get(request.getSession().getId()); + oauthHelper.setUserName(requestInfoForm); + requestInfoFormLocalCache.put(request.getSession().getId(), requestInfoForm); return setAuthorizationRequest(request, model, requestParameters, sessionStatus, principal, requestInfoForm); } @@ -145,29 +160,28 @@ public class OauthController { public @ResponseBody RequestInfoForm customRequestInfoForm(HttpServletRequest request, Map model, @RequestParam Map requestParameters, SessionStatus sessionStatus, Principal principal) throws UnsupportedEncodingException { RequestInfoForm requestInfoForm = new RequestInfoForm(); - - if(request.getSession() != null && request.getSession().getAttribute(OauthHelper.REQUEST_INFO_FORM) != null) { - requestInfoForm = oauthHelper.setUserRequestInfoForm((RequestInfoForm) request.getSession().getAttribute(OauthHelper.REQUEST_INFO_FORM)); - if (requestParameters.isEmpty() && request.getSession().getAttribute(OrcidOauth2Constants.OAUTH_QUERY_STRING) != null) { - try { - String url = URLDecoder.decode((String) request.getSession().getAttribute(OrcidOauth2Constants.OAUTH_QUERY_STRING), "UTF-8").trim(); - if (url.startsWith("oauth=&")) { - url = url.replaceFirst("oauth=&", ""); - } - String[] pairs = url.split("&"); - for (int i = 0; i < pairs.length; i++) { - String pair = pairs[i]; - String[] keyValue = pair.split("="); - requestParameters.put(keyValue[0], keyValue[1]); - } - setAuthorizationRequest(request, model, requestParameters, sessionStatus, principal, requestInfoForm); - } catch (NullPointerException | ArrayIndexOutOfBoundsException e) { - requestInfoForm.setError("oauth_error"); - requestInfoForm.setErrorDescription("Invalid request"); + if(requestInfoFormLocalCache.containsKey(request.getSession().getId())) { + requestInfoForm = requestInfoFormLocalCache.get(request.getSession().getId()); + oauthHelper.setUserName(requestInfoForm); + if (requestParameters.isEmpty() && request.getSession().getAttribute(OrcidOauth2Constants.OAUTH_QUERY_STRING) != null) { + try { + String url = URLDecoder.decode((String) request.getSession().getAttribute(OrcidOauth2Constants.OAUTH_QUERY_STRING), "UTF-8").trim(); + if (url.startsWith("oauth=&")) { + url = url.replaceFirst("oauth=&", ""); + } + String[] pairs = url.split("&"); + for (int i = 0; i < pairs.length; i++) { + String pair = pairs[i]; + String[] keyValue = pair.split("="); + requestParameters.put(keyValue[0], keyValue[1]); } - } + setAuthorizationRequest(request, model, requestParameters, sessionStatus, principal, requestInfoForm); + } catch (NullPointerException | ArrayIndexOutOfBoundsException e) { + requestInfoForm.setError("oauth_error"); + requestInfoForm.setErrorDescription("Invalid request"); + } + } } - request.getSession().setAttribute(OauthHelper.REQUEST_INFO_FORM, requestInfoForm); return requestInfoForm; } @@ -184,7 +198,6 @@ private RequestInfoForm generateRequestInfoForm(HttpServletRequest request, Stri requestInfoForm.setErrorDescription(e.getMessage()); return requestInfoForm; } catch (OauthInvalidRequestException e) { - requestInfoForm = e.getRequestInfoForm(); requestInfoForm.setError("oauth_error"); requestInfoForm.setErrorDescription(e.getMessage()); return requestInfoForm; @@ -302,7 +315,7 @@ private RequestInfoForm generateRequestInfoForm(HttpServletRequest request, Stri boolean tokenLongLifeAlreadyExists = tokenServices.longLifeTokenExist(requestInfoForm.getClientId(), baseControllerUtil.getCurrentUser(sci).getUsername(), OAuth2Utils.parseParameterList(requestInfoForm.getScopesAsString())); if (tokenLongLifeAlreadyExists) { setAuthorizationRequest(request, model, requestParameters, sessionStatus, principal, requestInfoForm); - AuthorizationRequest authorizationRequest = (AuthorizationRequest) request.getSession().getAttribute("authorizationRequest"); + AuthorizationRequest authorizationRequest = authorizationRequestLocalCache.get(request.getSession().getId()); if (authorizationRequest != null) { Map requestParams = new HashMap(); copyRequestParameters(request, requestParams); @@ -334,7 +347,7 @@ private RequestInfoForm generateRequestInfoForm(HttpServletRequest request, Stri Map modelAuth = new HashMap(); modelAuth.put("authorizationRequest", authorizationRequest); - Map originalRequest = (Map) request.getSession().getAttribute(OrcidOauth2Constants.ORIGINAL_AUTHORIZATION_REQUEST); + Map originalRequest = originalAuthorizationRequestLocalCache.get(request.getSession().getId()); if(originalRequest != null) { modelAuth.put(OrcidOauth2Constants.ORIGINAL_AUTHORIZATION_REQUEST, originalRequest); } @@ -344,7 +357,7 @@ private RequestInfoForm generateRequestInfoForm(HttpServletRequest request, Stri RedirectView view = (RedirectView) authorizationEndpoint.approveOrDeny(approvalParams, modelAuth, status, principal); requestInfoForm.setRedirectUrl(view.getUrl()); // Oauth has been approved, hence, remove the oauth flag from the session - request.getSession().setAttribute(OauthHelper.REQUEST_INFO_FORM, null); + requestInfoFormLocalCache.remove(request.getSession().getId()); request.getSession().removeAttribute(OrcidOauth2Constants.OAUTH_2SCREENS); } } @@ -355,7 +368,9 @@ private RequestInfoForm generateRequestInfoForm(HttpServletRequest request, Stri private void populateSession(HttpServletRequest request, RequestInfoForm requestInfoForm) { String url = request.getQueryString(); - request.getSession().setAttribute(OauthHelper.REQUEST_INFO_FORM, requestInfoForm); + + requestInfoFormLocalCache.put(request.getSession().getId(), requestInfoForm); + // Save also the original query string request.getSession().setAttribute(OrcidOauth2Constants.OAUTH_QUERY_STRING, url); @@ -397,13 +412,13 @@ private void populateSession(HttpServletRequest request, RequestInfoForm request } Map originalAuthorizationRequest = Map.copyOf(authorizationRequestMap); - request.getSession().setAttribute(OrcidOauth2Constants.ORIGINAL_AUTHORIZATION_REQUEST, originalAuthorizationRequest); + originalAuthorizationRequestLocalCache.put(request.getSession().getId(), originalAuthorizationRequest); } private RequestInfoForm setAuthorizationRequest(HttpServletRequest request, Map model, @RequestParam Map requestParameters, SessionStatus sessionStatus, Principal principal, RequestInfoForm requestInfoForm) { SecurityContext sci = getSecurityContext(request); - request.getSession().setAttribute("authorizationRequest", null); + authorizationRequestLocalCache.remove(request.getSession().getId()); if (baseControllerUtil.getCurrentUser(sci) != null) { // Authorize the request try { @@ -419,7 +434,7 @@ private RequestInfoForm setAuthorizationRequest(HttpServletRequest request, Map< } AuthorizationRequest authRequest = (AuthorizationRequest) mav.getModel().get("authorizationRequest"); - request.getSession().setAttribute("authorizationRequest", authRequest); + authorizationRequestLocalCache.put(request.getSession().getId(), authRequest); } catch (RedirectMismatchException e ) { requestInfoForm.setError("invalid_grant"); requestInfoForm.setErrorDescription("Redirect URI doesn't match your registered redirect URIs."); diff --git a/orcid-web/src/main/java/org/orcid/frontend/util/AuthorizationRequestLocalCache.java b/orcid-web/src/main/java/org/orcid/frontend/util/AuthorizationRequestLocalCache.java new file mode 100644 index 00000000000..34a5705a193 --- /dev/null +++ b/orcid-web/src/main/java/org/orcid/frontend/util/AuthorizationRequestLocalCache.java @@ -0,0 +1,59 @@ +package org.orcid.frontend.util; +import org.ehcache.Cache; +import org.ehcache.CacheManager; +import org.ehcache.config.builders.CacheConfigurationBuilder; +import org.ehcache.config.builders.CacheManagerBuilder; +import org.ehcache.config.builders.ResourcePoolsBuilder; +import org.ehcache.expiry.Duration; +import org.ehcache.expiry.Expirations; +import org.orcid.pojo.ajaxForm.RequestInfoForm; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.oauth2.provider.AuthorizationRequest; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import java.util.concurrent.TimeUnit; + +@Component +public class AuthorizationRequestLocalCache { + + @Value("${org.orcid.core.session.localCache.ttl:900}") + private int cacheTTLInSeconds; + + @Value("${org.orcid.core.session.localCache.heap:10000}") + private int heapSize; + + private CacheManager cacheManager; + private Cache cache; + + public AuthorizationRequestLocalCache() { + cacheManager = CacheManagerBuilder + .newCacheManagerBuilder().build(); + cacheManager.init(); + } + + @PostConstruct + public void initCache() { + cache = cacheManager + .createCache("squaredNumber", CacheConfigurationBuilder + .newCacheConfigurationBuilder( + String.class, AuthorizationRequest.class, + ResourcePoolsBuilder.heap(heapSize)).withExpiry(Expirations.timeToLiveExpiration(Duration.of(cacheTTLInSeconds, TimeUnit.SECONDS)))); + } + + public AuthorizationRequest get(String key) { + return cache.get(key); + } + + public void put(String key, AuthorizationRequest value) { + cache.put(key, value); + } + + public void remove(String key) { + cache.remove(key); + } + + public boolean containsKey(String key) { + return cache.containsKey(key); + } +} diff --git a/orcid-web/src/main/java/org/orcid/frontend/util/OriginalAuthorizationRequestLocalCache.java b/orcid-web/src/main/java/org/orcid/frontend/util/OriginalAuthorizationRequestLocalCache.java new file mode 100644 index 00000000000..9633e888f57 --- /dev/null +++ b/orcid-web/src/main/java/org/orcid/frontend/util/OriginalAuthorizationRequestLocalCache.java @@ -0,0 +1,59 @@ +package org.orcid.frontend.util; +import org.ehcache.Cache; +import org.ehcache.CacheManager; +import org.ehcache.config.builders.CacheConfigurationBuilder; +import org.ehcache.config.builders.CacheManagerBuilder; +import org.ehcache.config.builders.ResourcePoolsBuilder; +import org.ehcache.expiry.Duration; +import org.ehcache.expiry.Expirations; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.oauth2.provider.AuthorizationRequest; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +@Component +public class OriginalAuthorizationRequestLocalCache { + + @Value("${org.orcid.core.session.localCache.ttl:900}") + private int cacheTTLInSeconds; + + @Value("${org.orcid.core.session.localCache.heap:10000}") + private int heapSize; + + private CacheManager cacheManager; + private Cache cache; + + public OriginalAuthorizationRequestLocalCache() { + cacheManager = CacheManagerBuilder + .newCacheManagerBuilder().build(); + cacheManager.init(); + } + + @PostConstruct + public void initCache() { + cache = cacheManager + .createCache("squaredNumber", CacheConfigurationBuilder + .newCacheConfigurationBuilder( + String.class, Map.class, + ResourcePoolsBuilder.heap(heapSize)).withExpiry(Expirations.timeToLiveExpiration(Duration.of(cacheTTLInSeconds, TimeUnit.SECONDS)))); + } + + public Map get(String key) { + return cache.get(key); + } + + public void put(String key, Map value) { + cache.put(key, value); + } + + public void remove(String key) { + cache.remove(key); + } + + public boolean containsKey(String key) { + return cache.containsKey(key); + } +} diff --git a/orcid-web/src/main/java/org/orcid/frontend/util/RequestInfoFormLocalCache.java b/orcid-web/src/main/java/org/orcid/frontend/util/RequestInfoFormLocalCache.java new file mode 100644 index 00000000000..deba301129d --- /dev/null +++ b/orcid-web/src/main/java/org/orcid/frontend/util/RequestInfoFormLocalCache.java @@ -0,0 +1,58 @@ +package org.orcid.frontend.util; +import org.ehcache.Cache; +import org.ehcache.CacheManager; +import org.ehcache.config.builders.CacheConfigurationBuilder; +import org.ehcache.config.builders.CacheManagerBuilder; +import org.ehcache.config.builders.ResourcePoolsBuilder; +import org.ehcache.expiry.Duration; +import org.ehcache.expiry.Expirations; +import org.orcid.pojo.ajaxForm.RequestInfoForm; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import java.util.concurrent.TimeUnit; + +@Component +public class RequestInfoFormLocalCache { + + @Value("${org.orcid.core.session.localCache.ttl:900}") + private int cacheTTLInSeconds; + + @Value("${org.orcid.core.session.localCache.heap:10000}") + private int heapSize; + + private CacheManager cacheManager; + private Cache cache; + + public RequestInfoFormLocalCache() { + cacheManager = CacheManagerBuilder + .newCacheManagerBuilder().build(); + cacheManager.init(); + } + + @PostConstruct + public void initCache() { + cache = cacheManager + .createCache("squaredNumber", CacheConfigurationBuilder + .newCacheConfigurationBuilder( + String.class, RequestInfoForm.class, + ResourcePoolsBuilder.heap(heapSize)).withExpiry(Expirations.timeToLiveExpiration(Duration.of(cacheTTLInSeconds, TimeUnit.SECONDS)))); + } + + public RequestInfoForm get(String key) { + return cache.get(key); + } + + public void put(String key, RequestInfoForm value) { + cache.put(key, value); + } + + public void remove(String key) { + cache.remove(key); + } + + public boolean containsKey(String key) { + return cache.containsKey(key); + } +} diff --git a/orcid-web/src/main/java/org/orcid/frontend/web/controllers/LoginController.java b/orcid-web/src/main/java/org/orcid/frontend/web/controllers/LoginController.java index b5c479125b7..4b26382d314 100644 --- a/orcid-web/src/main/java/org/orcid/frontend/web/controllers/LoginController.java +++ b/orcid-web/src/main/java/org/orcid/frontend/web/controllers/LoginController.java @@ -26,6 +26,7 @@ import org.orcid.frontend.spring.web.social.config.SocialSignInUtils; import org.orcid.frontend.spring.web.social.config.SocialType; import org.orcid.frontend.spring.web.social.config.UserCookieGenerator; +import org.orcid.frontend.util.RequestInfoFormLocalCache; import org.orcid.frontend.web.controllers.helper.OauthHelper; import org.orcid.jaxb.model.message.ScopePathType; import org.orcid.jaxb.model.v3.release.common.Visibility; @@ -91,6 +92,9 @@ public class LoginController extends OauthControllerBase { @Resource private EventManager eventManager; + + @Resource + private RequestInfoFormLocalCache requestInfoFormLocalCache; @RequestMapping(value = "/account/names/{type}", method = RequestMethod.GET) public @ResponseBody Names getAccountNames(@PathVariable String type) { @@ -251,7 +255,7 @@ private ModelAndView handleOauthSignIn(HttpServletRequest request, HttpServletRe } } - request.getSession().setAttribute(OauthHelper.REQUEST_INFO_FORM, requestInfoForm); + requestInfoFormLocalCache.put(request.getSession().getId(), requestInfoForm); // Save also the original query string request.getSession().setAttribute(OrcidOauth2Constants.OAUTH_QUERY_STRING, queryString); // Save a flag to indicate this is a request from the new diff --git a/orcid-web/src/main/java/org/orcid/frontend/web/controllers/OauthAuthorizeController.java b/orcid-web/src/main/java/org/orcid/frontend/web/controllers/OauthAuthorizeController.java index d33985759b0..141b1440262 100644 --- a/orcid-web/src/main/java/org/orcid/frontend/web/controllers/OauthAuthorizeController.java +++ b/orcid-web/src/main/java/org/orcid/frontend/web/controllers/OauthAuthorizeController.java @@ -15,6 +15,9 @@ import org.orcid.core.manager.v3.ProfileEntityManager; import org.orcid.core.oauth.OrcidRandomValueTokenServices; import org.orcid.core.togglz.Features; +import org.orcid.frontend.util.AuthorizationRequestLocalCache; +import org.orcid.frontend.util.OriginalAuthorizationRequestLocalCache; +import org.orcid.frontend.util.RequestInfoFormLocalCache; import org.orcid.frontend.web.controllers.helper.OauthHelper; import org.orcid.jaxb.model.message.ScopePathType; import org.orcid.persistence.jpa.entities.ClientDetailsEntity; @@ -49,9 +52,6 @@ public class OauthAuthorizeController extends OauthControllerBase { @Resource protected OrcidRandomValueTokenServices tokenServices; - @Resource - private OauthLoginController oauthLoginController; - @Resource(name = "profileEntityManagerV3") private ProfileEntityManager profileEntityManager; @@ -60,7 +60,16 @@ public class OauthAuthorizeController extends OauthControllerBase { @Resource private EventManager eventManager; - + + @Resource + private RequestInfoFormLocalCache requestInfoFormLocalCache; + + @Resource + private AuthorizationRequestLocalCache authorizationRequestLocalCache; + + @Resource + private OriginalAuthorizationRequestLocalCache originalAuthorizationRequestLocalCache; + /** This is called if user is already logged in. * Checks permissions have been granted to client and generates access code. * @@ -76,7 +85,9 @@ public ModelAndView loginGetHandler(HttpServletRequest request, HttpServletRespo String queryString = request.getQueryString(); RequestInfoForm requestInfoForm = oauthHelper.generateRequestInfoForm(queryString); - request.getSession().setAttribute(OauthHelper.REQUEST_INFO_FORM, requestInfoForm); + + // Store the request info form in the cache + requestInfoFormLocalCache.put(request.getSession().getId(), requestInfoForm); boolean usePersistentTokens = false; @@ -149,7 +160,7 @@ public ModelAndView loginGetHandler(HttpServletRequest request, HttpServletRespo if (!forceConfirm && usePersistentTokens) { boolean tokenLongLifeAlreadyExists = tokenServices.longLifeTokenExist(requestInfoForm.getClientId(), getEffectiveUserOrcid(), OAuth2Utils.parseParameterList(requestInfoForm.getScopesAsString())); if (tokenLongLifeAlreadyExists) { - AuthorizationRequest authorizationRequest = (AuthorizationRequest) request.getSession().getAttribute("authorizationRequest"); + AuthorizationRequest authorizationRequest = authorizationRequestLocalCache.get(request.getSession().getId()); Authentication auth = SecurityContextHolder.getContext().getAuthentication(); Map requestParams = new HashMap(); copyRequestParameters(request, requestParams); @@ -209,9 +220,9 @@ public ModelAndView loginGetHandler(HttpServletRequest request, HttpServletRespo @RequestMapping(value = { "/oauth/custom/authorize.json" }, method = RequestMethod.POST) public @ResponseBody RequestInfoForm authorize(HttpServletRequest request, HttpServletResponse response, @RequestBody OauthAuthorizeForm form) { - RequestInfoForm requestInfoForm = (RequestInfoForm) request.getSession().getAttribute(OauthHelper.REQUEST_INFO_FORM); + RequestInfoForm requestInfoForm = requestInfoFormLocalCache.get(request.getSession().getId()); Authentication auth = SecurityContextHolder.getContext().getAuthentication(); - AuthorizationRequest authorizationRequest = (AuthorizationRequest) request.getSession().getAttribute("authorizationRequest"); + AuthorizationRequest authorizationRequest = authorizationRequestLocalCache.get(request.getSession().getId()); Map requestParams = new HashMap(authorizationRequest.getRequestParameters()); Map approvalParams = new HashMap(); @@ -244,7 +255,7 @@ public ModelAndView loginGetHandler(HttpServletRequest request, HttpServletRespo // Authorization request model Map model = new HashMap(); model.put("authorizationRequest", authorizationRequest); - Map originalRequest = (Map) request.getSession().getAttribute(OrcidOauth2Constants.ORIGINAL_AUTHORIZATION_REQUEST); + Map originalRequest = originalAuthorizationRequestLocalCache.get(request.getSession().getId()); if(originalRequest != null) { model.put(OrcidOauth2Constants.ORIGINAL_AUTHORIZATION_REQUEST, originalRequest); } @@ -281,7 +292,10 @@ public ModelAndView loginGetHandler(HttpServletRequest request, HttpServletRespo new HttpSessionRequestCache().removeRequest(request, response); LOGGER.info("OauthConfirmAccessController form.getRedirectUri being sent to client browser: " + requestInfoForm.getRedirectUrl()); //Oauth has been finalized, hence, remove the oauth flag from the session - request.getSession().setAttribute(OauthHelper.REQUEST_INFO_FORM, null); + + // Remove the request info form from the cache + requestInfoFormLocalCache.remove(request.getSession().getId()); + request.getSession().removeAttribute(OrcidOauth2Constants.OAUTH_2SCREENS); return requestInfoForm; } diff --git a/orcid-web/src/main/java/org/orcid/frontend/web/controllers/OauthGenericCallsController.java b/orcid-web/src/main/java/org/orcid/frontend/web/controllers/OauthGenericCallsController.java index 6bb6656f469..95c25bdd6c7 100644 --- a/orcid-web/src/main/java/org/orcid/frontend/web/controllers/OauthGenericCallsController.java +++ b/orcid-web/src/main/java/org/orcid/frontend/web/controllers/OauthGenericCallsController.java @@ -17,6 +17,7 @@ import org.orcid.api.common.oauth.OrcidClientCredentialEndPointDelegator; import org.orcid.core.oauth.OAuthError; import org.orcid.core.oauth.OAuthErrorUtils; +import org.orcid.frontend.util.RequestInfoFormLocalCache; import org.orcid.frontend.web.controllers.helper.OauthHelper; import org.orcid.pojo.ajaxForm.OauthAuthorizeForm; import org.orcid.pojo.ajaxForm.OauthRegistrationForm; @@ -42,6 +43,9 @@ public class OauthGenericCallsController extends OauthControllerBase { @Context private UriInfo uriInfo; + + @Resource + private RequestInfoFormLocalCache requestInfoFormLocalCache; @RequestMapping(value = "/oauth/token", consumes = MediaType.APPLICATION_FORM_URLENCODED, produces = MediaType.APPLICATION_JSON) public ResponseEntity obtainOauth2TokenPost(HttpServletRequest request) { @@ -66,9 +70,8 @@ public ResponseEntity obtainOauth2TokenPost(HttpServletRequest request) { @RequestMapping(value = "/oauth/custom/authorize/get_request_info_form.json", method = RequestMethod.GET) public @ResponseBody RequestInfoForm getRequestInfoForm(HttpServletRequest request) throws UnsupportedEncodingException { RequestInfoForm requestInfoForm = new RequestInfoForm(); - - if(request.getSession() != null && request.getSession().getAttribute(OauthHelper.REQUEST_INFO_FORM) != null) { - requestInfoForm = (RequestInfoForm) request.getSession().getAttribute(OauthHelper.REQUEST_INFO_FORM); + if(requestInfoFormLocalCache.containsKey(request.getSession().getId())) { + requestInfoForm = requestInfoFormLocalCache.get(request.getSession().getId()); } return requestInfoForm; } diff --git a/orcid-web/src/main/java/org/orcid/frontend/web/controllers/OauthLoginController.java b/orcid-web/src/main/java/org/orcid/frontend/web/controllers/OauthLoginController.java index 5b7914028ad..91b838aa8b7 100644 --- a/orcid-web/src/main/java/org/orcid/frontend/web/controllers/OauthLoginController.java +++ b/orcid-web/src/main/java/org/orcid/frontend/web/controllers/OauthLoginController.java @@ -16,6 +16,7 @@ import org.orcid.core.security.UnclaimedProfileExistsException; import org.orcid.core.utils.OrcidRequestUtil; import org.orcid.authorization.authentication.MFAWebAuthenticationDetails; +import org.orcid.frontend.util.RequestInfoFormLocalCache; import org.orcid.frontend.web.controllers.helper.OauthHelper; import org.orcid.frontend.web.exception.Bad2FARecoveryCodeException; import org.orcid.frontend.web.exception.Bad2FAVerificationCodeException; @@ -53,12 +54,16 @@ public class OauthLoginController extends OauthControllerBase { @Resource private OauthHelper oauthHelper; + @Resource + private RequestInfoFormLocalCache requestInfoFormLocalCache; + @RequestMapping(value = { "/oauth/signin", "/oauth/login" }, method = RequestMethod.GET) public ModelAndView loginGetHandler(HttpServletRequest request, HttpServletResponse response, ModelAndView mav) throws UnsupportedEncodingException { String url = request.getQueryString(); // Get and save the request information form RequestInfoForm requestInfoForm = oauthHelper.generateRequestInfoForm(url); - request.getSession().setAttribute(OauthHelper.REQUEST_INFO_FORM, requestInfoForm); + // Store the request info form in the cache + requestInfoFormLocalCache.put(request.getSession().getId(), requestInfoForm); // Check that the client have the required permissions // Get client name @@ -105,7 +110,7 @@ public ModelAndView loginGetHandler(HttpServletRequest request, HttpServletRespo public @ResponseBody OauthAuthorizeForm authenticateAndAuthorize(HttpServletRequest request, HttpServletResponse response, @RequestBody OauthAuthorizeForm form) { // Clean form errors form.setErrors(new ArrayList()); - RequestInfoForm requestInfoForm = (RequestInfoForm) request.getSession().getAttribute(OauthHelper.REQUEST_INFO_FORM); + RequestInfoForm requestInfoForm = requestInfoFormLocalCache.get(request.getSession().getId()); boolean willBeRedirected = false; if (form.getApproved()) { diff --git a/orcid-web/src/main/java/org/orcid/frontend/web/controllers/OauthRegistrationController.java b/orcid-web/src/main/java/org/orcid/frontend/web/controllers/OauthRegistrationController.java index 8a203209136..fb4fd9dd943 100644 --- a/orcid-web/src/main/java/org/orcid/frontend/web/controllers/OauthRegistrationController.java +++ b/orcid-web/src/main/java/org/orcid/frontend/web/controllers/OauthRegistrationController.java @@ -12,6 +12,7 @@ import org.apache.commons.lang.StringUtils; import org.orcid.core.constants.OrcidOauth2Constants; import org.orcid.core.utils.OrcidRequestUtil; +import org.orcid.frontend.util.RequestInfoFormLocalCache; import org.orcid.frontend.web.controllers.helper.OauthHelper; import org.orcid.jaxb.model.message.CreationMethod; import org.orcid.pojo.ajaxForm.OauthRegistrationForm; @@ -38,8 +39,11 @@ public class OauthRegistrationController extends OauthControllerBase { private static final Logger LOGGER = LoggerFactory.getLogger(OauthRegistrationController.class); @Resource - private RegistrationController registrationController; - + private RegistrationController registrationController; + + @Resource + private RequestInfoFormLocalCache requestInfoFormLocalCache; + public RegistrationController getRegistrationController() { return registrationController; } @@ -65,7 +69,7 @@ public void setRegistrationController(RegistrationController registrationControl @RequestMapping(value = "/oauth/custom/register.json", method = RequestMethod.POST) public @ResponseBody OauthRegistrationForm checkRegisterForm(HttpServletRequest request, HttpServletResponse response, @RequestBody OauthRegistrationForm form) { form.setErrors(new ArrayList()); - RequestInfoForm requestInfoForm = (RequestInfoForm) request.getSession().getAttribute(OauthHelper.REQUEST_INFO_FORM); + RequestInfoForm requestInfoForm = requestInfoFormLocalCache.get(request.getSession().getId()); if (form.getApproved()) { registrationController.validateRegistrationFields(request, form); @@ -85,7 +89,7 @@ public void setRegistrationController(RegistrationController registrationControl @RequestMapping(value = "/oauth/custom/registerConfirm.json", method = RequestMethod.POST) public @ResponseBody RequestInfoForm registerAndAuthorize(HttpServletRequest request, HttpServletResponse response, @RequestBody OauthRegistrationForm form) { - RequestInfoForm requestInfoForm = (RequestInfoForm) request.getSession().getAttribute(OauthHelper.REQUEST_INFO_FORM); + RequestInfoForm requestInfoForm = requestInfoFormLocalCache.get(request.getSession().getId()); if (form.getApproved()) { boolean usedCaptcha = false; diff --git a/orcid-web/src/main/java/org/orcid/frontend/web/controllers/RegistrationController.java b/orcid-web/src/main/java/org/orcid/frontend/web/controllers/RegistrationController.java index 295e382f399..f84965c3ad4 100644 --- a/orcid-web/src/main/java/org/orcid/frontend/web/controllers/RegistrationController.java +++ b/orcid-web/src/main/java/org/orcid/frontend/web/controllers/RegistrationController.java @@ -40,6 +40,7 @@ import org.orcid.frontend.spring.ShibbolethAjaxAuthenticationSuccessHandler; import org.orcid.frontend.spring.SocialAjaxAuthenticationSuccessHandler; import org.orcid.frontend.spring.web.social.config.SocialSignInUtils; +import org.orcid.frontend.util.RequestInfoFormLocalCache; import org.orcid.frontend.web.controllers.helper.OauthHelper; import org.orcid.frontend.web.util.RecaptchaVerifier; import org.orcid.jaxb.model.common.AvailableLocales; @@ -101,9 +102,6 @@ public class RegistrationController extends BaseController { @Resource private AuthenticationManager authenticationManager; - @Resource(name = "orcidSearchManagerV3") - private OrcidSearchManager orcidSearchManager; - @Resource private EncryptionManager encryptionManager; @@ -119,21 +117,12 @@ public class RegistrationController extends BaseController { @Resource private ShibbolethAjaxAuthenticationSuccessHandler ajaxAuthenticationSuccessHandlerShibboleth; - @Resource(name = "affiliationsManagerReadOnlyV3") - private AffiliationsManagerReadOnly affiliationsManagerReadOnly; - @Resource(name = "emailManagerReadOnlyV3") private EmailManagerReadOnly emailManagerReadOnly; @Resource(name = "profileHistoryEventManagerV3") private ProfileHistoryEventManager profileHistoryEventManager; - @Resource - private ProfileEntityCacheManager profileEntityCacheManager; - - @Resource - private OrcidUserDetailsService orcidUserDetailsService; - @Resource(name = "recordNameManagerReadOnlyV3") private RecordNameManagerReadOnly recordNameManagerReadOnly; @@ -143,6 +132,9 @@ public class RegistrationController extends BaseController { @Resource private EventManager eventManager; + @Resource + private RequestInfoFormLocalCache requestInfoFormLocalCache; + @RequestMapping(value = "/register.json", method = RequestMethod.GET) public @ResponseBody Registration getRegister(HttpServletRequest request, HttpServletResponse response) { // Remove the session hash if needed @@ -173,7 +165,7 @@ public class RegistrationController extends BaseController { setError(reg.getTermsOfUse(), "validations.acceptTermsAndConditions"); - RequestInfoForm requestInfoForm = (RequestInfoForm) request.getSession().getAttribute(OauthHelper.REQUEST_INFO_FORM); + RequestInfoForm requestInfoForm = requestInfoFormLocalCache.get(request.getSession().getId()); if (requestInfoForm != null) { if (!PojoUtil.isEmpty(requestInfoForm.getUserEmail())) { reg.getEmail().setValue(requestInfoForm.getUserEmail()); diff --git a/orcid-web/src/main/java/org/orcid/frontend/web/controllers/helper/OauthHelper.java b/orcid-web/src/main/java/org/orcid/frontend/web/controllers/helper/OauthHelper.java index 63d82e09895..c9198e286f1 100644 --- a/orcid-web/src/main/java/org/orcid/frontend/web/controllers/helper/OauthHelper.java +++ b/orcid-web/src/main/java/org/orcid/frontend/web/controllers/helper/OauthHelper.java @@ -38,7 +38,6 @@ public class OauthHelper { private static final Logger LOGGER = LoggerFactory.getLogger(OauthHelper.class); public static final String PUBLIC_MEMBER_NAME = "PubApp"; - public static final String REQUEST_INFO_FORM = "requestInfoForm"; private final Pattern redirectUriPattern = Pattern.compile("redirect_uri=([^&]*)"); private final Pattern responseTypePattern = Pattern.compile("response_type=([^&]*)"); @@ -116,7 +115,7 @@ public RequestInfoForm generateRequestInfoForm(String requestUrl) throws Unsuppo infoForm.setClientEmailRequestReason(clientEmailRequestReason); infoForm.setMemberName(memberName); } else { - throw new OauthInvalidRequestException("Please specify a client id", infoForm); + throw new OauthInvalidRequestException("Please specify a client id"); } Matcher orcidMatcher = orcidPattern.matcher(requestUrl); @@ -158,7 +157,7 @@ public RequestInfoForm generateRequestInfoForm(String requestUrl) throws Unsuppo // Replace any number of spaces or a plus (+) sign with a single space scopesString = scopesString.replaceAll("( |\\+)+", " "); if(scopesString == null || scopesString.isBlank()) { - throw new OauthInvalidRequestException("Please specify the desired scopes", infoForm); + throw new OauthInvalidRequestException("Please specify the desired scopes"); } for (ScopePathType theScope : ScopePathType.getScopesFromSpaceSeparatedString(scopesString)) { ScopeInfoForm scopeInfoForm = new ScopeInfoForm(); @@ -173,7 +172,7 @@ public RequestInfoForm generateRequestInfoForm(String requestUrl) throws Unsuppo infoForm.getScopes().add(scopeInfoForm); } } else { - throw new OauthInvalidRequestException("Please specify the desired scopes", infoForm); + throw new OauthInvalidRequestException("Please specify the desired scopes"); } Matcher redirectUriMatcher = redirectUriPattern.matcher(requestUrl); @@ -181,10 +180,10 @@ public RequestInfoForm generateRequestInfoForm(String requestUrl) throws Unsuppo try { infoForm.setRedirectUrl(OrcidStringUtils.stripHtml(URLDecoder.decode(redirectUriMatcher.group(1), "UTF-8").trim())); } catch (UnsupportedEncodingException e) { - throw new OauthInvalidRequestException("Invalid redirect URL", infoForm); + throw new OauthInvalidRequestException("Invalid redirect URL"); } } else { - throw new OauthInvalidRequestException("Please specify a redirect URL", infoForm); + throw new OauthInvalidRequestException("Please specify a redirect URL"); } Matcher stateParamMatcher = stateParamPattern.matcher(requestUrl); @@ -201,10 +200,10 @@ public RequestInfoForm generateRequestInfoForm(String requestUrl) throws Unsuppo try { infoForm.setResponseType(OrcidStringUtils.stripHtml(URLDecoder.decode(responseTypeMatcher.group(1), "UTF-8").trim())); } catch (UnsupportedEncodingException e) { - throw new OauthInvalidRequestException("Invalid response type", infoForm); + throw new OauthInvalidRequestException("Invalid response type"); } } else { - throw new OauthInvalidRequestException("Please specify a response type", infoForm); + throw new OauthInvalidRequestException("Please specify a response type"); } Matcher givenNamesMatcher = RegistrationController.givenNamesPattern.matcher(requestUrl); @@ -239,7 +238,7 @@ public RequestInfoForm generateRequestInfoForm(String requestUrl) throws Unsuppo return infoForm; } - public RequestInfoForm setUserRequestInfoForm(RequestInfoForm requestInfoForm) throws UnsupportedEncodingException { + public void setUserName(RequestInfoForm requestInfoForm) throws UnsupportedEncodingException { String loggedUserOrcid = getEffectiveUserOrcid(); if (!PojoUtil.isEmpty(loggedUserOrcid)) { requestInfoForm.setUserOrcid(loggedUserOrcid); @@ -248,7 +247,6 @@ public RequestInfoForm setUserRequestInfoForm(RequestInfoForm requestInfoForm) t requestInfoForm.setUserName(URLDecoder.decode(creditName, "UTF-8").trim()); } } - return requestInfoForm; } private String getEffectiveUserOrcid() { diff --git a/orcid-web/src/main/java/org/orcid/frontend/web/exception/OauthInvalidRequestException.java b/orcid-web/src/main/java/org/orcid/frontend/web/exception/OauthInvalidRequestException.java index d52a1ffe58a..678da54756d 100644 --- a/orcid-web/src/main/java/org/orcid/frontend/web/exception/OauthInvalidRequestException.java +++ b/orcid-web/src/main/java/org/orcid/frontend/web/exception/OauthInvalidRequestException.java @@ -6,13 +6,6 @@ @SuppressWarnings("serial") public class OauthInvalidRequestException extends InvalidRequestException { - RequestInfoForm requestInfoForm; - - public OauthInvalidRequestException(final String msg, final RequestInfoForm requestInfoForm) { - super(msg); - this.requestInfoForm = requestInfoForm; - } - public OauthInvalidRequestException(final String msg) { super(msg); } @@ -21,8 +14,4 @@ public OauthInvalidRequestException(final String msg, final Throwable t) { super(msg, t); } - public RequestInfoForm getRequestInfoForm() { - return this.requestInfoForm; - } - } diff --git a/orcid-web/src/main/java/org/orcid/frontend/web/filter/OAuthAuthorizeNotSignedInFilter.java b/orcid-web/src/main/java/org/orcid/frontend/web/filter/OAuthAuthorizeNotSignedInFilter.java index 845512e2720..10e6339cf2c 100644 --- a/orcid-web/src/main/java/org/orcid/frontend/web/filter/OAuthAuthorizeNotSignedInFilter.java +++ b/orcid-web/src/main/java/org/orcid/frontend/web/filter/OAuthAuthorizeNotSignedInFilter.java @@ -15,6 +15,7 @@ import org.orcid.core.constants.OrcidOauth2Constants; import org.orcid.core.manager.impl.OrcidUrlManager; +import org.orcid.frontend.util.RequestInfoFormLocalCache; import org.orcid.frontend.web.controllers.BaseControllerUtil; import org.orcid.frontend.web.controllers.helper.OauthHelper; import org.orcid.pojo.ajaxForm.RequestInfoForm; @@ -35,6 +36,9 @@ public class OAuthAuthorizeNotSignedInFilter implements Filter { @Resource private OauthHelper oauthHelper; + + @Resource + private RequestInfoFormLocalCache requestInfoFormLocalCache; @Override public void destroy() { @@ -62,7 +66,10 @@ public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) if (session != null) { new HttpSessionRequestCache().saveRequest(request, response); RequestInfoForm rif = oauthHelper.generateRequestInfoForm(request.getQueryString()); - request.getSession().setAttribute(OauthHelper.REQUEST_INFO_FORM, rif); + + // Store the request info form in the cache + requestInfoFormLocalCache.put(request.getSession().getId(), rif); + request.getSession().setAttribute(OrcidOauth2Constants.OAUTH_QUERY_STRING, queryString); } response.sendRedirect(orcidUrlManager.getBaseUrl() + "/signin?oauth&" + queryString); diff --git a/orcid-web/src/test/java/org/orcid/frontend/web/controllers/OauthRegistrationControllerTest.java b/orcid-web/src/test/java/org/orcid/frontend/web/controllers/OauthRegistrationControllerTest.java index c8f8b9554f1..f315d4cfa15 100644 --- a/orcid-web/src/test/java/org/orcid/frontend/web/controllers/OauthRegistrationControllerTest.java +++ b/orcid-web/src/test/java/org/orcid/frontend/web/controllers/OauthRegistrationControllerTest.java @@ -79,7 +79,6 @@ public void testStripHtmlFromNames() throws UnsupportedEncodingException { RequestInfoForm rf = new RequestInfoForm(); RedirectView mv = new RedirectView(); when(servletRequest.getSession()).thenReturn(session); - when(servletRequest.getSession().getAttribute("requestInfoForm")).thenReturn(rf); when(authorizationEndpoint.approveOrDeny(Matchers.anyMap(), Matchers.anyMap(), Matchers.any(SessionStatus.class), Matchers.any(Principal.class))).thenReturn(mv); when(authenticationManager.authenticate(Matchers.any(Authentication.class))).thenAnswer(new Answer(){ @Override