001/* 002 * ==================================================================== 003 * Licensed to the Apache Software Foundation (ASF) under one 004 * or more contributor license agreements. See the NOTICE file 005 * distributed with this work for additional information 006 * regarding copyright ownership. The ASF licenses this file 007 * to you under the Apache License, Version 2.0 (the 008 * "License"); you may not use this file except in compliance 009 * with the License. You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, 014 * software distributed under the License is distributed on an 015 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 016 * KIND, either express or implied. See the License for the 017 * specific language governing permissions and limitations 018 * under the License. 019 * ==================================================================== 020 * 021 * This software consists of voluntary contributions made by many 022 * individuals on behalf of the Apache Software Foundation. For more 023 * information on the Apache Software Foundation, please see 024 * <http://www.apache.org/>. 025 * 026 */ 027package org.apache.http.impl.client; 028 029import java.net.Authenticator; 030import java.net.PasswordAuthentication; 031import java.util.Locale; 032import java.util.Map; 033import java.util.concurrent.ConcurrentHashMap; 034 035import org.apache.http.HttpHost; 036import org.apache.http.annotation.Contract; 037import org.apache.http.annotation.ThreadingBehavior; 038import org.apache.http.auth.AuthScope; 039import org.apache.http.auth.Credentials; 040import org.apache.http.auth.NTCredentials; 041import org.apache.http.auth.UsernamePasswordCredentials; 042import org.apache.http.client.CredentialsProvider; 043import org.apache.http.client.config.AuthSchemes; 044import org.apache.http.util.Args; 045 046/** 047 * Implementation of {@link CredentialsProvider} backed by standard 048 * JRE {@link Authenticator}. 049 * 050 * @since 4.3 051 */ 052@Contract(threading = ThreadingBehavior.SAFE) 053public class SystemDefaultCredentialsProvider implements CredentialsProvider { 054 055 private static final Map<String, String> SCHEME_MAP; 056 057 static { 058 SCHEME_MAP = new ConcurrentHashMap<String, String>(); 059 SCHEME_MAP.put(AuthSchemes.BASIC.toUpperCase(Locale.ROOT), "Basic"); 060 SCHEME_MAP.put(AuthSchemes.DIGEST.toUpperCase(Locale.ROOT), "Digest"); 061 SCHEME_MAP.put(AuthSchemes.NTLM.toUpperCase(Locale.ROOT), "NTLM"); 062 SCHEME_MAP.put(AuthSchemes.SPNEGO.toUpperCase(Locale.ROOT), "SPNEGO"); 063 SCHEME_MAP.put(AuthSchemes.KERBEROS.toUpperCase(Locale.ROOT), "Kerberos"); 064 } 065 066 private static String translateScheme(final String key) { 067 if (key == null) { 068 return null; 069 } 070 final String s = SCHEME_MAP.get(key); 071 return s != null ? s : key; 072 } 073 074 private final BasicCredentialsProvider internal; 075 076 /** 077 * Default constructor. 078 */ 079 public SystemDefaultCredentialsProvider() { 080 super(); 081 this.internal = new BasicCredentialsProvider(); 082 } 083 084 @Override 085 public void setCredentials(final AuthScope authscope, final Credentials credentials) { 086 internal.setCredentials(authscope, credentials); 087 } 088 089 private static PasswordAuthentication getSystemCreds( 090 final AuthScope authscope, 091 final Authenticator.RequestorType requestorType) { 092 final String hostname = authscope.getHost(); 093 final int port = authscope.getPort(); 094 final HttpHost origin = authscope.getOrigin(); 095 final String protocol = origin != null ? origin.getSchemeName() : 096 (port == 443 ? "https" : "http"); 097 return Authenticator.requestPasswordAuthentication( 098 hostname, 099 null, 100 port, 101 protocol, 102 null, 103 translateScheme(authscope.getScheme()), 104 null, 105 requestorType); 106 } 107 108 @Override 109 public Credentials getCredentials(final AuthScope authscope) { 110 Args.notNull(authscope, "Auth scope"); 111 final Credentials localcreds = internal.getCredentials(authscope); 112 if (localcreds != null) { 113 return localcreds; 114 } 115 final String host = authscope.getHost(); 116 if (host != null) { 117 PasswordAuthentication systemcreds = getSystemCreds(authscope, Authenticator.RequestorType.SERVER); 118 if (systemcreds == null) { 119 systemcreds = getSystemCreds(authscope, Authenticator.RequestorType.PROXY); 120 } 121 if (systemcreds == null) { 122 final String proxyHost = System.getProperty("http.proxyHost"); 123 if (proxyHost != null) { 124 final String proxyPort = System.getProperty("http.proxyPort"); 125 if (proxyPort != null) { 126 try { 127 final AuthScope systemScope = new AuthScope(proxyHost, Integer.parseInt(proxyPort)); 128 if (authscope.match(systemScope) >= 0) { 129 final String proxyUser = System.getProperty("http.proxyUser"); 130 if (proxyUser != null) { 131 final String proxyPassword = System.getProperty("http.proxyPassword"); 132 systemcreds = new PasswordAuthentication(proxyUser, proxyPassword != null ? proxyPassword.toCharArray() : new char[] {}); 133 } 134 } 135 } catch (NumberFormatException ex) { 136 } 137 } 138 } 139 } 140 if (systemcreds != null) { 141 final String domain = System.getProperty("http.auth.ntlm.domain"); 142 if (domain != null) { 143 return new NTCredentials( 144 systemcreds.getUserName(), 145 new String(systemcreds.getPassword()), 146 null, domain); 147 } else { 148 if (AuthSchemes.NTLM.equalsIgnoreCase(authscope.getScheme())) { 149 // Domain may be specified in a fully qualified user name 150 return new NTCredentials( 151 systemcreds.getUserName(), 152 new String(systemcreds.getPassword()), 153 null, null); 154 } else { 155 return new UsernamePasswordCredentials( 156 systemcreds.getUserName(), 157 new String(systemcreds.getPassword())); 158 } 159 } 160 } 161 } 162 return null; 163 } 164 165 @Override 166 public void clear() { 167 internal.clear(); 168 } 169 170}