001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *   http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied.  See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019package org.apache.hadoop.hdfs.web.oauth2;
020
021import org.apache.hadoop.classification.InterfaceAudience;
022import org.apache.hadoop.classification.InterfaceStability;
023import org.apache.hadoop.conf.Configuration;
024import org.apache.hadoop.security.authentication.client.ConnectionConfigurator;
025import org.apache.hadoop.util.ReflectionUtils;
026
027import java.io.IOException;
028import java.net.HttpURLConnection;
029
030import static org.apache.hadoop.hdfs.client.HdfsClientConfigKeys.ACCESS_TOKEN_PROVIDER_KEY;
031import static org.apache.hadoop.hdfs.web.oauth2.Utils.notNull;
032
033/**
034 * Configure a connection to use OAuth2 authentication.
035 */
036@InterfaceAudience.Public
037@InterfaceStability.Evolving
038public class OAuth2ConnectionConfigurator implements ConnectionConfigurator {
039
040  public static final String HEADER = "Bearer ";
041
042  private final AccessTokenProvider accessTokenProvider;
043
044  private ConnectionConfigurator sslConfigurator = null;
045
046  public OAuth2ConnectionConfigurator(Configuration conf) {
047    this(conf, null);
048  }
049
050  @SuppressWarnings("unchecked")
051  public OAuth2ConnectionConfigurator(Configuration conf,
052                                      ConnectionConfigurator sslConfigurator) {
053    this.sslConfigurator = sslConfigurator;
054
055    notNull(conf, ACCESS_TOKEN_PROVIDER_KEY);
056
057    Class accessTokenProviderClass = conf.getClass(ACCESS_TOKEN_PROVIDER_KEY,
058        ConfCredentialBasedAccessTokenProvider.class,
059        AccessTokenProvider.class);
060
061    accessTokenProvider = (AccessTokenProvider) ReflectionUtils
062        .newInstance(accessTokenProviderClass, conf);
063    accessTokenProvider.setConf(conf);
064  }
065
066  @Override
067  public HttpURLConnection configure(HttpURLConnection conn)
068      throws IOException {
069    if(sslConfigurator != null) {
070      sslConfigurator.configure(conn);
071    }
072
073    String accessToken = accessTokenProvider.getAccessToken();
074
075    conn.setRequestProperty("AUTHORIZATION", HEADER + accessToken);
076
077    return conn;
078  }
079}