Java tutorial
/* * Copyright 2017 Regents of the University of California. * * Licensed under the Educational Community License, Version 2.0 (the "license"); * you may not use this file except in compliance with the License. You may * obtain a copy of the license at * * https://opensource.org/licenses/ECL-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.opentestsystem.ap.iat.filter; import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.context.RequestContext; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.exception.ExceptionUtils; import org.opentestsystem.ap.iat.config.AppProperties; import org.opentestsystem.ap.iat.security.ClientOnlyResourceOwnerPasswordResourceDetails; import org.springframework.security.oauth2.client.OAuth2RestTemplate; import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails; import org.springframework.security.oauth2.common.AuthenticationScheme; import org.springframework.security.oauth2.common.OAuth2AccessToken; import org.springframework.security.oauth2.common.OAuth2RefreshToken; import org.springframework.security.oauth2.common.exceptions.InvalidGrantException; import org.springframework.stereotype.Component; import javax.servlet.http.HttpSession; import static org.apache.commons.lang3.StringUtils.containsIgnoreCase; /** * Appends the SESSION cookie to the outbound request where the downstream service uses it to look up the session. If * the request is for specific services then an OAuth2 access token is added as a header. */ @Slf4j @Component public class AppendSessionZuulPreFilter extends ZuulFilter { private final static int GET_ACCESS_TOKEN_FIRST_TRY = 1; private AppProperties appProperties; private OAuth2RestTemplate oauth2RestTemplate; public AppendSessionZuulPreFilter(final AppProperties appProperties) { this.appProperties = appProperties; this.oauth2RestTemplate = newRestTemplate(); } @Override public String filterType() { return "pre"; } @Override public int filterOrder() { return 0; } @Override public boolean shouldFilter() { return true; } @Override public Object run() { final RequestContext context = RequestContext.getCurrentContext(); final HttpSession httpSession = context.getRequest().getSession(); final String requestURI = context.getRequest().getRequestURI(); context.addZuulRequestHeader("Cookie", "SESSION=" + httpSession.getId()); if (containsIgnoreCase(requestURI, appProperties.getSsoRequestPathMatch())) { final String accessToken = getAccessToken(); context.addZuulRequestHeader("Authorization", "Bearer " + accessToken); } return true; } private String getAccessToken() { try { return retrieveAccessTokenFromProvider(); } catch (Exception e) { log.info("Retry access token retrieval, {}", ExceptionUtils.getRootCauseMessage(e)); resetRestTemplate(); return retrieveAccessTokenFromProvider(); } } private synchronized String retrieveAccessTokenFromProvider() { OAuth2AccessToken accessToken = this.oauth2RestTemplate.getAccessToken(); log.debug("Access token expires {}", accessToken.getExpiration()); return accessToken.getValue(); } private synchronized void resetRestTemplate() { this.oauth2RestTemplate = newRestTemplate(); } private OAuth2RestTemplate newRestTemplate() { return new OAuth2RestTemplate(oauth2ProtectedResourceDetails()); } private OAuth2ProtectedResourceDetails oauth2ProtectedResourceDetails() { final ClientOnlyResourceOwnerPasswordResourceDetails resourceDetails = new ClientOnlyResourceOwnerPasswordResourceDetails(); resourceDetails.setUsername(appProperties.getSsoUsername()); resourceDetails.setPassword(appProperties.getSsoPassword()); resourceDetails.setClientId(appProperties.getSsoClientId()); resourceDetails.setClientSecret(appProperties.getSsoClientSecret()); resourceDetails.setAccessTokenUri(appProperties.getSsoUrl()); resourceDetails.setClientAuthenticationScheme(AuthenticationScheme.form); return resourceDetails; } }