View Javadoc

1   /*
2    * $Id: HttpBasicAuthenticationFilter.java 10662 2008-02-01 13:10:14Z romikk $
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.AuthenticationException;
35  import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
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      @Override
62      protected void doInitialise() throws InitialisationException
63      {
64          if (realm == null)
65          {
66              if (isRealmRequired())
67              {
68                  throw new InitialisationException(SpringSecurityMessages.authRealmMustBeSetOnFilter(), this);
69              }
70              else
71              {
72                  logger.warn("There is no security realm set, using default: null");
73              }
74          }
75      }
76  
77      public String getRealm()
78      {
79          return realm;
80      }
81  
82      public void setRealm(String realm)
83      {
84          this.realm = realm;
85      }
86  
87      public boolean isRealmRequired()
88      {
89          return realmRequired;
90      }
91  
92      public void setRealmRequired(boolean realmRequired)
93      {
94          this.realmRequired = realmRequired;
95      }
96  
97      /**
98       * Authenticates the current message if authenticate is set to true. This method
99       * will always populate the secure context in the session
100      * 
101      * @param event the current message recieved
102      * @throws org.mule.api.security.SecurityException if authentication fails
103      */
104     @Override
105     public void authenticateInbound(MuleEvent event)
106         throws SecurityException, SecurityProviderNotFoundException, UnknownAuthenticationTypeException
107     {
108         String header = event.getMessage().getInboundProperty(HttpConstants.HEADER_AUTHORIZATION);
109 
110         if (logger.isDebugEnabled())
111         {
112             logger.debug("Authorization header: " + header);
113         }
114 
115         if ((header != null) && header.startsWith("Basic "))
116         {
117             String base64Token = header.substring(6);
118             String token = new String(Base64.decodeBase64(base64Token.getBytes()));
119 
120             String username = "";
121             String password = "";
122             int delim = token.indexOf(":");
123 
124             if (delim != -1)
125             {
126                 username = token.substring(0, delim);
127                 password = token.substring(delim + 1);
128             }
129 
130             UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(
131                 username, password);
132             authRequest.setDetails(event.getMessage().getInboundProperty(MuleProperties.MULE_ENDPOINT_PROPERTY));
133 
134             Authentication authResult;
135 
136             Authentication authentication = new SpringAuthenticationAdapter(authRequest);
137 
138             try
139             {
140                 authResult = getSecurityManager().authenticate(authentication);
141             }
142             catch (UnauthorisedException e)
143             {
144                 // Authentication failed
145                 if (logger.isDebugEnabled())
146                 {
147                     logger.debug("Authentication request for user: " + username + " failed: " + e.toString());
148                 }
149                 setUnauthenticated(event);
150                 throw new UnauthorisedException(CoreMessages.authFailedForUser(username), e);
151             }
152 
153             // Authentication success
154             if (logger.isDebugEnabled())
155             {
156                 logger.debug("Authentication success: " + authResult.toString());
157             }
158 
159             SecurityContext context = getSecurityManager().createSecurityContext(authResult);
160             context.setAuthentication(authResult);
161             event.getSession().setSecurityContext(context);
162         }
163         else if (header == null)
164         {
165             setUnauthenticated(event);
166             throw new UnauthorisedException(event, event.getSession().getSecurityContext(),
167                 getEndpoint(), this);
168         }
169         else
170         {
171             setUnauthenticated(event);
172             throw new UnsupportedAuthenticationSchemeException(
173                 SpringSecurityMessages.basicFilterCannotHandleHeader(header), event);
174         }
175     }
176 
177     protected void setUnauthenticated(MuleEvent event)
178     {
179         String realmHeader = "Basic realm=";
180         if (realm != null)
181         {
182             realmHeader += "\"" + realm + "\"";
183         }
184         MuleMessage msg = event.getMessage();
185         msg.setOutboundProperty(HttpConstants.HEADER_WWW_AUTHENTICATE, realmHeader);
186         msg.setOutboundProperty(HttpConnector.HTTP_STATUS_PROPERTY, HttpConstants.SC_UNAUTHORIZED);
187     }
188 
189     /**
190      * Authenticates the current message if authenticate is set to true. This method
191      * will always populate the secure context in the session
192      * 
193      * @param event the current event being dispatched
194      * @throws org.mule.api.security.SecurityException if authentication fails
195      */
196     @Override
197     public void authenticateOutbound(MuleEvent event)
198         throws SecurityException, SecurityProviderNotFoundException
199     {
200         if (event.getSession().getSecurityContext() == null)
201         {
202             if (isAuthenticate())
203             {
204                 throw new UnauthorisedException(event, event.getSession().getSecurityContext(),
205                     event.getEndpoint(), this);
206             }
207             else
208             {
209                 return;
210             }
211         }
212 
213         Authentication auth = event.getSession().getSecurityContext().getAuthentication();
214         if (isAuthenticate())
215         {
216             auth = getSecurityManager().authenticate(auth);
217             if (logger.isDebugEnabled())
218             {
219                 logger.debug("Authentication success: " + auth.toString());
220             }
221         }
222 
223         StringBuffer header = new StringBuffer(128);
224         header.append("Basic ");
225         String token = auth.getCredentials().toString();
226         header.append(new String(Base64.encodeBase64(token.getBytes())));
227 
228         event.getMessage().setOutboundProperty(HttpConstants.HEADER_AUTHORIZATION, header.toString());
229     }
230 
231 }