001: /* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
002: *
003: * Licensed under the Apache License, Version 2.0 (the "License");
004: * you may not use this file except in compliance with the License.
005: * You may obtain a copy of the License at
006: *
007: * http://www.apache.org/licenses/LICENSE-2.0
008: *
009: * Unless required by applicable law or agreed to in writing, software
010: * distributed under the License is distributed on an "AS IS" BASIS,
011: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: * See the License for the specific language governing permissions and
013: * limitations under the License.
014: */
015:
016: package org.acegisecurity.context.httpinvoker;
017:
018: import org.acegisecurity.Authentication;
019: import org.acegisecurity.AuthenticationCredentialsNotFoundException;
020:
021: import org.acegisecurity.context.SecurityContextHolder;
022:
023: import org.apache.commons.codec.binary.Base64;
024: import org.apache.commons.logging.Log;
025: import org.apache.commons.logging.LogFactory;
026:
027: import org.springframework.remoting.httpinvoker.SimpleHttpInvokerRequestExecutor;
028:
029: import java.io.IOException;
030:
031: import java.net.HttpURLConnection;
032:
033: /**
034: * Adds BASIC authentication support to <code>SimpleHttpInvokerRequestExecutor</code>.
035: *
036: * @author Ben Alex
037: * @version $Id: AuthenticationSimpleHttpInvokerRequestExecutor.java 1784 2007-02-24 21:00:24Z luke_t $
038: */
039: public class AuthenticationSimpleHttpInvokerRequestExecutor extends
040: SimpleHttpInvokerRequestExecutor {
041: //~ Static fields/initializers =====================================================================================
042:
043: private static final Log logger = LogFactory
044: .getLog(AuthenticationSimpleHttpInvokerRequestExecutor.class);
045:
046: //~ Methods ========================================================================================================
047:
048: /**
049: * Provided so subclasses can perform additional configuration if required (eg set additional request
050: * headers for non-security related information etc).
051: *
052: * @param con the HTTP connection to prepare
053: * @param contentLength the length of the content to send
054: *
055: * @throws IOException if thrown by HttpURLConnection methods
056: */
057: protected void doPrepareConnection(HttpURLConnection con,
058: int contentLength) throws IOException {
059: }
060:
061: /**
062: * Called every time a HTTP invocation is made.<p>Simply allows the parent to setup the connection, and
063: * then adds an <code>Authorization</code> HTTP header property that will be used for BASIC authentication.</p>
064: * <p>The <code>SecurityContextHolder</code> is used to obtain the relevant principal and credentials.</p>
065: *
066: * @param con the HTTP connection to prepare
067: * @param contentLength the length of the content to send
068: *
069: * @throws IOException if thrown by HttpURLConnection methods
070: * @throws AuthenticationCredentialsNotFoundException if the <code>SecurityContextHolder</code> does not contain a
071: * valid <code>Authentication</code> with both its <code>principal</code> and <code>credentials</code> not
072: * <code>null</code>
073: */
074: protected void prepareConnection(HttpURLConnection con,
075: int contentLength) throws IOException,
076: AuthenticationCredentialsNotFoundException {
077: super .prepareConnection(con, contentLength);
078:
079: Authentication auth = SecurityContextHolder.getContext()
080: .getAuthentication();
081:
082: if ((auth != null) && (auth.getName() != null)
083: && (auth.getCredentials() != null)) {
084: String base64 = auth.getName() + ":"
085: + auth.getCredentials().toString();
086: con.setRequestProperty("Authorization",
087: "Basic "
088: + new String(Base64.encodeBase64(base64
089: .getBytes())));
090:
091: if (logger.isDebugEnabled()) {
092: logger
093: .debug("HttpInvocation now presenting via BASIC authentication SecurityContextHolder-derived: "
094: + auth.toString());
095: }
096: } else {
097: if (logger.isDebugEnabled()) {
098: logger
099: .debug("Unable to set BASIC authentication header as SecurityContext did not provide "
100: + "valid Authentication: " + auth);
101: }
102: }
103:
104: doPrepareConnection(con, contentLength);
105: }
106: }
|