View Javadoc

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