/** * Copyright (c) Codice Foundation * <p/> * This is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser * General Public License as published by the Free Software Foundation, either version 3 of the * License, or any later version. * <p/> * This program 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 * Lesser General Public License for more details. A copy of the GNU Lesser General Public License * is distributed along with this program and can be found at * <http://www.gnu.org/licenses/lgpl.html>. */ package org.codice.ddf.security.handler.pki; import java.security.cert.X509Certificate; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import org.codice.ddf.security.handler.api.AuthenticationHandler; import org.codice.ddf.security.handler.api.HandlerResult; import org.codice.ddf.security.handler.api.PKIAuthenticationToken; import org.codice.ddf.security.handler.api.PKIAuthenticationTokenFactory; import org.codice.ddf.security.policy.context.ContextPolicy; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Handler for PKI based authentication. X509 chain will be extracted from the HTTP request and * converted to a BinarySecurityToken. */ public class PKIHandler implements AuthenticationHandler { /** * PKI type to use when configuring context policy. */ public static final String AUTH_TYPE = "PKI"; public static final String SOURCE = "PKIHandler"; private static final Logger LOGGER = LoggerFactory.getLogger(PKIHandler.class); protected PKIAuthenticationTokenFactory tokenFactory; @Override public String getAuthenticationType() { return AUTH_TYPE; } /** * Handler implementing PKI authentication. Returns the {@link org.codice.ddf.security.handler.api.HandlerResult} containing * a BinarySecurityToken if the operation was successful. * * @param request http request to obtain attributes from and to pass into any local filter chains required * @param response http response to return http responses or redirects * @param chain original filter chain (should not be called from your handler) * @param resolve flag with true implying that credentials should be obtained, false implying return if no credentials are found. * @return result of handling this request - status and optional tokens * @throws ServletException */ @Override public HandlerResult getNormalizedToken(ServletRequest request, ServletResponse response, FilterChain chain, boolean resolve) throws ServletException { String realm = (String) request.getAttribute(ContextPolicy.ACTIVE_REALM); HandlerResult handlerResult = new HandlerResult(HandlerResult.Status.NO_ACTION, null); handlerResult.setSource(realm + "-" + SOURCE); HttpServletRequest httpRequest = (HttpServletRequest) request; String path = httpRequest.getServletPath(); LOGGER.debug("Doing PKI authentication and authorization for path {}", path); //doesn't matter what the resolve flag is set to, we do the same action PKIAuthenticationToken token = extractAuthenticationInfo(httpRequest); if (token != null) { handlerResult.setToken(token); handlerResult.setStatus(HandlerResult.Status.COMPLETED); } return handlerResult; } @Override public HandlerResult handleError(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws ServletException { String realm = (String) servletRequest.getAttribute(ContextPolicy.ACTIVE_REALM); HandlerResult result = new HandlerResult(HandlerResult.Status.NO_ACTION, null); result.setSource(realm + "-" + SOURCE); LOGGER.debug("In error handler for pki - no action taken."); return result; } protected PKIAuthenticationToken extractAuthenticationInfo(HttpServletRequest request) { PKIAuthenticationToken token; String realm = (String) request.getAttribute(ContextPolicy.ACTIVE_REALM); X509Certificate[] certs = (X509Certificate[]) request .getAttribute("javax.servlet.request.X509Certificate"); token = tokenFactory.getTokenFromCerts(certs, realm); return token; } public void setTokenFactory(PKIAuthenticationTokenFactory factory) { tokenFactory = factory; } }