/* * Copyright (C) 2011-2012 Intel Corporation * All rights reserved. */ package com.intel.mtwilson.security.http.apache; import com.intel.dcsg.cpg.crypto.RsaCredential; import com.intel.mtwilson.security.http.RsaAuthorization; import java.io.IOException; import java.security.SignatureException; import java.util.HashMap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.apache.commons.io.IOUtils; import org.apache.http.Header; import org.apache.http.HttpEntityEnclosingRequest; import org.apache.http.HttpRequest; /** * This class adds an http Authorization header using the "MtWilson" custom scheme. * * @since 0.5.2 * @author jbuhacoff */ public class ApacheRsaHttpAuthorization implements ApacheHttpAuthorization { private Logger log = LoggerFactory.getLogger(getClass()); private RsaAuthorization authority; public ApacheRsaHttpAuthorization(RsaCredential credential) { authority = new RsaAuthorization(credential); } @Override public void addAuthorization(HttpRequest request) throws SignatureException { log.debug("Signing request for URL: {}", request.getRequestLine().getUri()); // it's important to start with the headers that may be already associated // with the request because, for example, the caller may have already defined // the date header that should be included and covered in the signature HashMap<String,String> headers = getHeaders(request); request.addHeader("Authorization", authority.getAuthorizationQuietly(request.getRequestLine().getMethod(), request.getRequestLine().getUri(), headers)); // the RsaAuthorization class may generate headers for the request such as nonce and date, so we look for those and add them. for(String key : headers.keySet()) { request.addHeader(key, headers.get(key)); } } /** * The entity must be repeatable. If the entity is null then an empty string is used to represent it. * @param request */ @Override public void addAuthorization(HttpEntityEnclosingRequest request) throws SignatureException, IOException { log.debug("Signing entity-enclosing request for URL: {}", request.getRequestLine().getUri()); if( request.getEntity() == null ) { addAuthorization((HttpRequest)request); return; } if( !request.getEntity().isRepeatable() ) { throw new IllegalArgumentException("Cannot sign a non-repeatable request"); } String body = IOUtils.toString(request.getEntity().getContent()); // it's important to start with the headers that may be already associated // with the request because, for example, the caller may have already defined // the date header that should be included and covered in the signature HashMap<String,String> headers = getHeaders(request); request.addHeader("Authorization", authority.getAuthorizationQuietly(request.getRequestLine().getMethod(), request.getRequestLine().getUri(), headers, body)); // the RsaAuthorization class may generate headers for the request such as nonce and date, so we look for those and add them. for(String key : headers.keySet()) { request.setHeader(key, headers.get(key)); } } private HashMap<String,String> getHeaders(HttpRequest request) { HashMap<String,String> headers = new HashMap<>(); Header[] allHttpHeaders = request.getAllHeaders(); for(Header httpHeader : allHttpHeaders) { headers.put(httpHeader.getName(), httpHeader.getValue()); // if a header appears multiple times, only the last one "sticks" } return headers; } }