001 /*
002 * Copyright 2011-2012 UnboundID Corp.
003 *
004 * This program is free software; you can redistribute it and/or modify
005 * it under the terms of the GNU General Public License (GPLv2 only)
006 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
007 * as published by the Free Software Foundation.
008 *
009 * This program is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012 * GNU General Public License for more details.
013 *
014 * You should have received a copy of the GNU General Public License
015 * along with this program; if not, see <http://www.gnu.org/licenses>.
016 */
017
018 package com.unboundid.scim.sdk;
019
020 import org.apache.wink.client.ClientAuthenticationException;
021 import org.apache.wink.client.ClientRequest;
022 import org.apache.wink.client.ClientResponse;
023 import org.apache.wink.client.handlers.ClientHandler;
024 import org.apache.wink.client.handlers.HandlerContext;
025 import org.apache.wink.common.http.HttpStatus;
026
027 import javax.xml.bind.DatatypeConverter;
028 import java.io.InputStream;
029
030 /**
031 * This class provides HTTP Basic Authentication handling.
032 */
033 public class HttpBasicAuthSecurityHandler implements ClientHandler {
034 private volatile String username;
035 private volatile String encodedCredentials;
036
037 /**
038 * Constructs a fully initialized Security handler.
039 * @param username The Consumer username.
040 * @param password The Consumer password.
041 */
042 public HttpBasicAuthSecurityHandler(final String username,
043 final String password) {
044 this.username = username;
045 String encoded = DatatypeConverter.printBase64Binary(
046 (username + ":" + password).getBytes());
047 this.encodedCredentials = "Basic " + encoded;
048 }
049
050 /**
051 * Attempts to authenticate a Consumer via Http Basic.
052 *
053 * @param request The Client Resource request.
054 * @param context The provided handler chain.
055 * @return Client Response that may indicate success or failure.
056 * @throws Exception Thrown if error handling authentication.
057 */
058 public ClientResponse handle(final ClientRequest request,
059 final HandlerContext context) throws Exception {
060 ClientResponse response = context.doChain(request);
061 if (response.getStatusCode() == HttpStatus.UNAUTHORIZED.getCode()) {
062 InputStream is = response.getEntity(InputStream.class);
063 if(is != null) {
064 // Throw away any entity content.
065 is.close();
066 }
067 request.getHeaders().putSingle("Authorization", this.encodedCredentials);
068 response = context.doChain(request);
069 if (response.getStatusCode() == HttpStatus.UNAUTHORIZED.getCode()) {
070 throw new ClientAuthenticationException(username);
071 } else {
072 // error presumably unrelated to authentication
073 return response;
074 }
075 } else {
076 return response;
077 }
078 }
079 }