90b0101ed060ee9db55a164e98a2834f6ebb4e54
[moon.git] /
1 /*
2  * Copyright (c) 2015 Brocade Communications Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.aaa.shiro.filters;
10
11 import javax.servlet.ServletRequest;
12 import javax.servlet.ServletResponse;
13 import javax.servlet.http.HttpServletRequest;
14
15 import org.apache.shiro.codec.Base64;
16 import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter;
17 import org.apache.shiro.web.util.WebUtils;
18 import org.slf4j.Logger;
19 import org.slf4j.LoggerFactory;
20
21 /**
22  * Extends <code>BasicHttpAuthenticationFilter</code> to include ability to
23  * authenticate OAuth2 tokens, which is needed for backwards compatibility with
24  * <code>TokenAuthFilter</code>.
25  *
26  * This behavior is enabled by default for backwards compatibility. To disable
27  * OAuth2 functionality, just comment out the following line from the
28  * <code>etc/shiro.ini</code> file:
29  * <code>authcBasic = org.opendaylight.aaa.shiro.filters.ODLHttpAuthenticationFilter</code>
30  * then restart the karaf container.
31  *
32  * @author Ryan Goulding (ryandgoulding@gmail.com)
33  *
34  */
35 public class ODLHttpAuthenticationFilter extends BasicHttpAuthenticationFilter {
36
37     private static final Logger LOG = LoggerFactory.getLogger(ODLHttpAuthenticationFilter.class);
38
39     // defined in lower-case for more efficient string comparison
40     protected static final String BEARER_SCHEME = "bearer";
41
42     protected static final String OPTIONS_HEADER = "OPTIONS";
43
44     public ODLHttpAuthenticationFilter() {
45         super();
46         LOG.info("Creating the ODLHttpAuthenticationFilter");
47     }
48
49     @Override
50     protected String[] getPrincipalsAndCredentials(String scheme, String encoded) {
51         final String decoded = Base64.decodeToString(encoded);
52         // attempt to decode username/password; otherwise decode as token
53         if (decoded.contains(":")) {
54             return decoded.split(":");
55         }
56         return new String[] { encoded };
57     }
58
59     @Override
60     protected boolean isLoginAttempt(String authzHeader) {
61         final String authzScheme = getAuthzScheme().toLowerCase();
62         final String authzHeaderLowerCase = authzHeader.toLowerCase();
63         return authzHeaderLowerCase.startsWith(authzScheme)
64                 || authzHeaderLowerCase.startsWith(BEARER_SCHEME);
65     }
66
67     @Override
68     protected boolean isAccessAllowed(ServletRequest request, ServletResponse response,
69             Object mappedValue) {
70         final HttpServletRequest httpRequest = WebUtils.toHttp(request);
71         final String httpMethod = httpRequest.getMethod();
72         if (OPTIONS_HEADER.equalsIgnoreCase(httpMethod)) {
73             return true;
74         } else {
75             return super.isAccessAllowed(httpRequest, response, mappedValue);
76         }
77     }
78 }