]> git.basschouten.com Git - openhab-addons.git/blob
3756a9045451ab358c51afe71874bfeb2cce8687
[openhab-addons.git] /
1 /*
2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3  *
4  * Copyright (c) 2013-2015 Oracle and/or its affiliates. All rights reserved.
5  *
6  * The contents of this file are subject to the terms of either the GNU
7  * General Public License Version 2 only ("GPL") or the Common Development
8  * and Distribution License("CDDL") (collectively, the "License").  You
9  * may not use this file except in compliance with the License.  You can
10  * obtain a copy of the License at
11  * http://glassfish.java.net/public/CDDL+GPL_1_1.html
12  * or packager/legal/LICENSE.txt.  See the License for the specific
13  * language governing permissions and limitations under the License.
14  *
15  * When distributing the software, include this License Header Notice in each
16  * file and include the License file at packager/legal/LICENSE.txt.
17  *
18  * GPL Classpath Exception:
19  * Oracle designates this particular file as subject to the "Classpath"
20  * exception as provided by Oracle in the GPL Version 2 section of the License
21  * file that accompanied this code.
22  *
23  * Modifications:
24  * If applicable, add the following below the License Header, with the fields
25  * enclosed by brackets [] replaced by your own identifying information:
26  * "Portions Copyright [year] [name of copyright owner]"
27  *
28  * Contributor(s):
29  * If you wish your version of this file to be governed by only the CDDL or
30  * only the GPL Version 2, indicate your decision by adding "[Contributor]
31  * elects to include this software in this distribution under the [CDDL or GPL
32  * Version 2] license."  If you don't indicate a single choice of license, a
33  * recipient has the option to distribute your version of this file under
34  * either the CDDL, the GPL Version 2 or to extend the choice of license to
35  * its licensees as provided above.  However, if you add GPL Version 2 code
36  * and therefore, elected the GPL Version 2 license, then the option applies
37  * only if the new code is made subject to such option by the copyright
38  * holder.
39  */
40 package org.openhab.binding.lametrictime.api.authentication;
41
42 import java.util.Base64;
43
44 import javax.ws.rs.client.ClientRequestContext;
45 import javax.ws.rs.client.ClientResponseContext;
46 import javax.ws.rs.core.HttpHeaders;
47
48 /**
49  * Implementation of Basic Http Authentication method (RFC 2617).
50  *
51  * @author Miroslav Fuksa
52  * @author Jakub Podlesak (jakub.podlesak at oracle.com)
53  * @author Craig McClanahan
54  */
55 final class BasicAuthenticator {
56
57     private final HttpAuthenticationFilter.Credentials defaultCredentials;
58
59     /**
60      * Creates a new instance of basic authenticator.
61      *
62      * @param defaultCredentials Credentials. Can be {@code null} if no default credentials should be
63      *            used.
64      */
65     BasicAuthenticator(HttpAuthenticationFilter.Credentials defaultCredentials) {
66         this.defaultCredentials = defaultCredentials;
67     }
68
69     private String calculateAuthentication(HttpAuthenticationFilter.Credentials credentials) {
70         String username = credentials.getUsername();
71         byte[] password = credentials.getPassword();
72         if (username == null) {
73             username = "";
74         }
75
76         if (password == null) {
77             password = new byte[0];
78         }
79
80         final byte[] prefix = (username + ":").getBytes(HttpAuthenticationFilter.CHARACTER_SET);
81         final byte[] usernamePassword = new byte[prefix.length + password.length];
82
83         System.arraycopy(prefix, 0, usernamePassword, 0, prefix.length);
84         System.arraycopy(password, 0, usernamePassword, prefix.length, password.length);
85
86         return "Basic " + Base64.getEncoder().encodeToString(usernamePassword);
87     }
88
89     /**
90      * Adds authentication information to the request.
91      *
92      * @param request Request context.
93      * @throws RequestAuthenticationException in case that basic credentials missing or are in invalid format
94      */
95     public void filterRequest(ClientRequestContext request) throws RequestAuthenticationException {
96         HttpAuthenticationFilter.Credentials credentials = HttpAuthenticationFilter.getCredentials(request,
97                 defaultCredentials, HttpAuthenticationFilter.Type.BASIC);
98         if (credentials == null) {
99             throw new RequestAuthenticationException("BasicAuth credentials are missing.");
100         }
101         request.getHeaders().add(HttpHeaders.AUTHORIZATION, calculateAuthentication(credentials));
102     }
103
104     /**
105      * Checks the response and if basic authentication is required then performs a new request
106      * with basic authentication.
107      *
108      * @param request Request context.
109      * @param response Response context (will be updated with newest response data if the request was repeated).
110      * @return {@code true} if response does not require authentication or if authentication is required,
111      *         new request was done with digest authentication information and authentication was successful.
112      * @throws ResponseAuthenticationException in case that basic credentials missing or are in invalid format
113      */
114     public boolean filterResponseAndAuthenticate(ClientRequestContext request, ClientResponseContext response) {
115         final String authenticate = response.getHeaders().getFirst(HttpHeaders.WWW_AUTHENTICATE);
116         if (authenticate != null && authenticate.trim().toUpperCase().startsWith("BASIC")) {
117             HttpAuthenticationFilter.Credentials credentials = HttpAuthenticationFilter.getCredentials(request,
118                     defaultCredentials, HttpAuthenticationFilter.Type.BASIC);
119
120             if (credentials == null) {
121                 throw new ResponseAuthenticationException(null, "BasicAuth credentials are missing.");
122             }
123
124             return HttpAuthenticationFilter.repeatRequest(request, response, calculateAuthentication(credentials));
125         }
126         return false;
127     }
128 }