Package uk.ac.bbsrc.tgac.miso.webapp.context

Source Code of uk.ac.bbsrc.tgac.miso.webapp.context.RestSignatureFilter

/*
* Copyright (c) 2012. The Genome Analysis Centre, Norwich, UK
* MISO project contacts: Robert Davey, Mario Caccamo @ TGAC
* *********************************************************************
*
* This file is part of MISO.
*
* MISO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* MISO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MISO.  If not, see <http://www.gnu.org/licenses/>.
*
* *********************************************************************
*/

package uk.ac.bbsrc.tgac.miso.webapp.context;

import com.eaglegenomics.simlims.core.manager.SecurityManager;

import java.io.IOException;
import java.security.InvalidKeyException;
import java.util.*;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
import org.springframework.security.web.context.HttpRequestResponseHolder;
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
import org.springframework.security.web.context.SecurityContextRepository;
import org.springframework.web.filter.OncePerRequestFilter;
import uk.ac.bbsrc.tgac.miso.core.security.util.LimsSecurityUtils;
import uk.ac.bbsrc.tgac.miso.integration.util.SignatureHelper;

/**
* uk.ac.bbsrc.tgac.miso.webapp.context
* <p/>
* Info
*
* @author Rob Davey
* @date 09/02/12
* @since 0.1.6
*/

public class RestSignatureFilter extends OncePerRequestFilter {
  @Autowired
  AuthenticationManager authenticationManager;
  @Autowired
  SecurityManager securityManager;

  private SecurityContextRepository securityContextRepository = new HttpSessionSecurityContextRepository();

  /**
   * Creates a new RestSignatureFilter instance with a default HttpSessionSecurityContextRepository set
   */
  public RestSignatureFilter() {
    super();
  }

  /**
   * Creates a new RestSignatureFilter instance with a defined SecurityContextRepository
   *
   * @param securityContextRepository of type SecurityContextRepository
   */
  public RestSignatureFilter(SecurityContextRepository securityContextRepository) {
    super();
    this.securityContextRepository = securityContextRepository;
  }

  public void setSecurityManager(SecurityManager securityManager) {
    this.securityManager = securityManager;
  }

  @Override
  protected void doFilterInternal(HttpServletRequest request,
                                  HttpServletResponse response,
                                  FilterChain filterChain) throws ServletException, IOException {
    User userdetails = null;
    com.eaglegenomics.simlims.core.User user = null;
    logger.info("HEADERS: ");
    Enumeration es = request.getHeaderNames();
    while (es.hasMoreElements()) {
      String key = (String) es.nextElement();
      logger.info(key + " -> " + request.getHeader(key));
    }

    String loginName = request.getHeader(SignatureHelper.USER_HEADER);
    if (loginName == null) {
      SecurityContext sc = securityContextRepository.loadContext(new HttpRequestResponseHolder(request, response));
      if (sc != null && sc.getAuthentication() != null) {
        logger.info("User already logged in - chaining");
        SecurityContextHolder.getContextHolderStrategy().setContext(sc);
        filterChain.doFilter(request, response);
      }
      throw new BadCredentialsException("Cannot enact RESTful request without a user specified!");
    }

    if (loginName.equals("notification")) {
      logger.info("Incoming notification request");
      userdetails = new User("notification", "none", true, true, true, true, AuthorityUtils.createAuthorityList("ROLE_INTERNAL"));
    }
    else {
      logger.info("Incoming user REST API request");
      user = securityManager.getUserByLoginName(loginName);
      if (user != null) {
        userdetails = LimsSecurityUtils.toUserDetails(user);
      }
    }

    //String url = request.getHeader(SignatureHelper.URL_X_HEADER);

    String signature = request.getHeader(SignatureHelper.SIGNATURE_HEADER);
    if (signature == null) {
      throw new BadCredentialsException("Cannot enact RESTful request without a signature!");
    }

    boolean validSignature = false;
    try {
      if (loginName.equals("notification")) {
        validSignature = SignatureHelper.validateSignature(request, SignatureHelper.PUBLIC_KEY, signature);
      }
      else {
        validSignature = SignatureHelper.validateSignature(request,
                                                           SignatureHelper.generatePrivateUserKey(
                                                             (user.getLoginName() + "::" + user.getPassword())
                                                                     .getBytes("UTF-8")),
                                                           signature);
      }
    }
    catch (InvalidKeyException e) {
      e.printStackTrace();
    }
    catch (Exception e) {
      e.printStackTrace();
    }

    try {
      if (!validSignature) {
        logger.error("REST KEY INVALID");
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "REST signature failed validation.");
      }
    } catch (Exception e) {
      logger.error("UNABLE TO UNDERTAKE SIGNATURE VALIDATION");
      e.printStackTrace();
      response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "The REST Security Server experienced an internal error.");
    }

    logger.debug("REST KEY OK. Security!");

    if (userdetails != null) {
      PreAuthenticatedAuthenticationToken newAuthentication = new PreAuthenticatedAuthenticationToken(userdetails, userdetails.getPassword(), userdetails.getAuthorities());
      newAuthentication.setAuthenticated(true);
      newAuthentication.setDetails(userdetails);

      try {
        SecurityContext sc = SecurityContextHolder.getContextHolderStrategy().getContext();
        sc.setAuthentication(newAuthentication);
        SecurityContextHolder.getContextHolderStrategy().setContext(sc);
        logger.debug("Set context - chaining");
      }
      catch (AuthenticationException a) {
        a.printStackTrace();
      }
      filterChain.doFilter(request, response);
    }
    else {
      throw new AuthenticationCredentialsNotFoundException("No valid user found to authenticate");
    }
  }
}
TOP

Related Classes of uk.ac.bbsrc.tgac.miso.webapp.context.RestSignatureFilter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.