Ответ 1
Это работает как ожидалось для меня с Apache HttpClient 4.2
Примечание. Хотя он компилируется и выполняется с помощью httpclient 4.5, его выполнение попадает в цикл навсегда.
MyAuthScheme.java
public class MyAuthScheme implements ContextAwareAuthScheme {
public static final String NAME = "myscheme";
private static final String REQUEST_BODY = "{\"login\":\"%s\",\"password\":\"%s\"}";
private final URI loginUri;
public MyAuthScheme(URI uri) {
loginUri = uri;
}
@Override
public Header authenticate(Credentials credentials,
HttpRequest request,
HttpContext context) throws AuthenticationException {
BasicCookieStore cookieStore = (BasicCookieStore) context.getAttribute(ClientContext.COOKIE_STORE);
DefaultHttpClient client = new DefaultHttpClient();
// authentication cookie is set automatically when
// login response arrived
client.setCookieStore(cookieStore);
HttpPost loginRequest = new HttpPost(loginUri);
String requestBody = String.format(
REQUEST_BODY,
credentials.getUserPrincipal().getName(),
credentials.getPassword());
loginRequest.setHeader("Content-Type", "application/json");
try {
loginRequest.setEntity(new StringEntity(requestBody));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
try {
HttpResponse response = client.execute(loginRequest);
int code = response.getStatusLine().getStatusCode();
EntityUtils.consume(response.getEntity());
if(code != 200) {
throw new IllegalStateException("Authentication problem");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
loginRequest.reset();
}
return null;
}
@Override
public void processChallenge(Header header) throws MalformedChallengeException {}
@Override
public String getSchemeName() {
return NAME;
}
@Override
public String getParameter(String name) {
return null;
}
@Override
public String getRealm() {
return null;
}
@Override
public boolean isConnectionBased() {
return false;
}
@Override
public boolean isComplete() {
return false;
}
@Override
public Header authenticate(Credentials credentials,
HttpRequest request) throws AuthenticationException {
// not implemented
return null;
}
}
MyAuthSchemeFactory.java
public class MyAuthSchemeFactory implements AuthSchemeFactory {
private final URI loginUri;
public MyAuthSchemeFactory(URI uri) {
this.loginUri = uri;
}
@Override
public AuthScheme newInstance(HttpParams params) {
return new MyAuthScheme(loginUri);
}
}
MyAuthStrategy.java
public class MyAuthStrategy implements AuthenticationStrategy {
@Override
public boolean isAuthenticationRequested(HttpHost authhost,
HttpResponse response,
HttpContext context) {
return response.getStatusLine().getStatusCode() == 401;
}
@Override
public Map<String, Header> getChallenges(HttpHost authhost,
HttpResponse response,
HttpContext context) throws MalformedChallengeException {
Map<String, Header> challenges = new HashMap<>();
challenges.put("myscheme", new BasicHeader("WWW-Authenticate", "myscheme"));
return challenges;
}
@Override
public Queue<AuthOption> select(Map<String, Header> challenges,
HttpHost authhost,
HttpResponse response,
HttpContext context) throws MalformedChallengeException {
AuthSchemeRegistry registry = (AuthSchemeRegistry) context.getAttribute(ClientContext.AUTHSCHEME_REGISTRY);
AuthScheme authScheme = registry.getAuthScheme(MyAuthScheme.NAME, new BasicHttpParams());
CredentialsProvider credsProvider = (CredentialsProvider) context.getAttribute(ClientContext.CREDS_PROVIDER);
Credentials credentials = credsProvider.getCredentials(new AuthScope(authhost));
Queue<AuthOption> options = new LinkedList<>();
options.add(new AuthOption(authScheme, credentials));
return options;
}
@Override
public void authSucceeded(HttpHost authhost, AuthScheme authScheme, HttpContext context) {}
@Override
public void authFailed(HttpHost authhost, AuthScheme authScheme, HttpContext context) {}
}
App.java
public class App {
public static void main(String[] args) throws IOException, URISyntaxException {
URI loginUri = new URI("https://example.com/api/v3/users/login");
AuthSchemeRegistry schemeRegistry = new AuthSchemeRegistry();
schemeRegistry.register(MyAuthScheme.NAME, new MyAuthSchemeFactory(loginUri));
BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(
new AuthScope("example.com", 8065),
new UsernamePasswordCredentials("[email protected]", "secret"));
DefaultHttpClient client = new DefaultHttpClient();
client.setCredentialsProvider(credentialsProvider);
client.setTargetAuthenticationStrategy(new MyAuthStrategy());
client.setAuthSchemes(schemeRegistry);
client.setCookieStore(new BasicCookieStore());
String getResourcesUrl = "https://example.com:8065/api/v3/myresources/";
HttpGet getResourcesRequest = new HttpGet(getResourcesUrl);
getResourcesRequest.setHeader("x-requested-with", "XMLHttpRequest");
try {
HttpResponse response = client.execute(getResourcesRequest);
// consume response
} finally {
getResourcesRequest.reset();
}
// further requests won't call MyAuthScheme.authenticate()
HttpGet getResourcesRequest2 = new HttpGet(getResourcesUrl);
getResourcesRequest2.setHeader("x-requested-with", "XMLHttpRequest");
try {
HttpResponse response2 = client.execute(getResourcesRequest);
// consume response
} finally {
getResourcesRequest2.reset();
}
HttpGet getResourcesRequest3 = new HttpGet(getResourcesUrl);
getResourcesRequest3.setHeader("x-requested-with", "XMLHttpRequest");
try {
HttpResponse response3 = client.execute(getResourcesRequest);
// consume response
} finally {
getResourcesRequest3.reset();
}
}
}