View Javadoc

1   /*
2    * $Id: HttpBasicAuthenticationFilter.java 10789 2008-02-12 20:04:43Z dfeist $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.module.acegi.filters.http;
12  
13  import org.mule.api.MuleEvent;
14  import org.mule.api.MuleMessage;
15  import org.mule.api.config.MuleProperties;
16  import org.mule.api.lifecycle.InitialisationException;
17  import org.mule.api.security.Authentication;
18  import org.mule.api.security.SecurityException;
19  import org.mule.api.security.SecurityProviderNotFoundException;
20  import org.mule.api.security.SecurityContext;
21  import org.mule.api.security.UnauthorisedException;
22  import org.mule.api.security.UnknownAuthenticationTypeException;
23  import org.mule.api.security.UnsupportedAuthenticationSchemeException;
24  import org.mule.config.i18n.CoreMessages;
25  import org.mule.module.acegi.AcegiAuthenticationAdapter;
26  import org.mule.module.acegi.i18n.AcegiMessages;
27  import org.mule.security.AbstractEndpointSecurityFilter;
28  import org.mule.transport.http.HttpConnector;
29  import org.mule.transport.http.HttpConstants;
30  
31  import org.acegisecurity.AuthenticationException;
32  import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
33  import org.apache.commons.codec.binary.Base64;
34  import org.apache.commons.logging.Log;
35  import org.apache.commons.logging.LogFactory;
36  
37  /**
38   * <code>HttpBasicAuthenticationFilter</code> TODO
39   */
40  public class HttpBasicAuthenticationFilter extends AbstractEndpointSecurityFilter
41  {
42      /**
43       * logger used by this class
44       */
45      protected static final Log logger = LogFactory.getLog(HttpBasicAuthenticationFilter.class);
46  
47      private String realm;
48  
49      private boolean realmRequired = true;
50  
51      public HttpBasicAuthenticationFilter()
52      {
53          super();
54      }
55  
56      public HttpBasicAuthenticationFilter(String realm)
57      {
58          this.realm = realm;
59      }
60  
61      protected void doInitialise() throws InitialisationException
62      {
63          if (realm == null)
64          {
65              if (isRealmRequired())
66              {
67                  throw new InitialisationException(AcegiMessages.authRealmMustBeSetOnFilter(), this);
68              }
69              else
70              {
71                  logger.warn("There is no security realm set, using default: null");
72              }
73          }
74      }
75  
76      public String getRealm()
77      {
78          return realm;
79      }
80  
81      public void setRealm(String realm)
82      {
83          this.realm = realm;
84      }
85  
86      public boolean isRealmRequired()
87      {
88          return realmRequired;
89      }
90  
91      public void setRealmRequired(boolean realmRequired)
92      {
93          this.realmRequired = realmRequired;
94      }
95  
96      /**
97       * Authenticates the current message if authenticate is set to true. This method
98       * will always populate the secure context in the session
99       * 
100      * @param event the current message recieved
101      * @throws org.mule.api.security.SecurityException if authentication fails
102      */
103     public void authenticateInbound(MuleEvent event)
104         throws SecurityException, SecurityProviderNotFoundException, UnknownAuthenticationTypeException
105     {
106         String header = event.getMessage().getStringProperty(HttpConstants.HEADER_AUTHORIZATION, null);
107 
108         if (logger.isDebugEnabled())
109         {
110             logger.debug("Authorization header: " + header);
111         }
112 
113         if ((header != null) && header.startsWith("Basic "))
114         {
115             String base64Token = header.substring(6);
116             String token = new String(Base64.decodeBase64(base64Token.getBytes()));
117 
118             String username = "";
119             String password = "";
120             int delim = token.indexOf(":");
121 
122             if (delim != -1)
123             {
124                 username = token.substring(0, delim);
125                 password = token.substring(delim + 1);
126             }
127 
128             UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(
129                 username, password);
130             authRequest.setDetails(event.getMessage().getProperty(MuleProperties.MULE_ENDPOINT_PROPERTY));
131 
132             Authentication authResult;
133 
134             Authentication umoAuthentication = new AcegiAuthenticationAdapter(authRequest);
135 
136             try
137             {
138                 authResult = getSecurityManager().authenticate(umoAuthentication);
139             }
140             catch (AuthenticationException e)
141             {
142                 // Authentication failed
143                 if (logger.isDebugEnabled())
144                 {
145                     logger.debug("Authentication request for user: " + username + " failed: " + e.toString());
146                 }
147                 setUnauthenticated(event);
148                 throw new UnauthorisedException(CoreMessages.authFailedForUser(username), e);
149             }
150 
151             // Authentication success
152             if (logger.isDebugEnabled())
153             {
154                 logger.debug("Authentication success: " + authResult.toString());
155             }
156 
157             SecurityContext context = getSecurityManager().createSecurityContext(authResult);
158             context.setAuthentication(authResult);
159             event.getSession().setSecurityContext(context);
160         }
161         else if (header == null)
162         {
163             setUnauthenticated(event);
164             throw new UnauthorisedException(event.getMessage(), event.getSession().getSecurityContext(),
165                 getEndpoint(), this);
166         }
167         else
168         {
169             setUnauthenticated(event);
170             throw new UnsupportedAuthenticationSchemeException(
171                 AcegiMessages.basicFilterCannotHandleHeader(header),
172                 event.getMessage());
173         }
174     }
175 
176     protected void setUnauthenticated(MuleEvent event)
177     {
178         String realmHeader = "Basic realm=";
179         if (realm != null)
180         {
181             realmHeader += "\"" + realm + "\"";
182         }
183         MuleMessage msg = event.getMessage();
184         msg.setProperty(HttpConstants.HEADER_WWW_AUTHENTICATE, realmHeader);
185         msg.setIntProperty(HttpConnector.HTTP_STATUS_PROPERTY, HttpConstants.SC_UNAUTHORIZED);
186     }
187 
188     /**
189      * Authenticates the current message if authenticate is set to true. This method
190      * will always populate the secure context in the session
191      * 
192      * @param event the current event being dispatched
193      * @throws org.mule.api.security.SecurityException if authentication fails
194      */
195     public void authenticateOutbound(MuleEvent event)
196         throws SecurityException, SecurityProviderNotFoundException
197     {
198         if (event.getSession().getSecurityContext() == null)
199         {
200             if (isAuthenticate())
201             {
202                 throw new UnauthorisedException(event.getMessage(), event.getSession().getSecurityContext(),
203                     event.getEndpoint(), this);
204             }
205             else
206             {
207                 return;
208             }
209         }
210 
211         Authentication auth = event.getSession().getSecurityContext().getAuthentication();
212         if (isAuthenticate())
213         {
214             auth = getSecurityManager().authenticate(auth);
215             if (logger.isDebugEnabled())
216             {
217                 logger.debug("Authentication success: " + auth.toString());
218             }
219         }
220 
221         StringBuffer header = new StringBuffer(128);
222         header.append("Basic ");
223         String token = auth.getCredentials().toString();
224         header.append(new String(Base64.encodeBase64(token.getBytes())));
225 
226         event.getMessage().setStringProperty(HttpConstants.HEADER_AUTHORIZATION, header.toString());
227     }
228 
229 }