org.opentestsystem.ap.iat.filter.AppendSessionZuulPreFilter.java Source code

Java tutorial

Introduction

Here is the source code for org.opentestsystem.ap.iat.filter.AppendSessionZuulPreFilter.java

Source

/*
 * 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;
    }

}