blob: a9e46e7a630576d764bef9c35eef8383f34443bc [file]
// Copyright 2011 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.enterprise.adaptor;
import com.google.enterprise.secmgr.http.HttpClientInterface;
import com.google.enterprise.secmgr.modules.SamlClient;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import org.opensaml.xml.security.SecurityHelper;
import org.opensaml.xml.security.credential.Credential;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.security.KeyPair;
/**
* A credentials gatherer that implements authentication by communicating with
* the GSA's security manager via SAML. This class only sends the initial
* request; the response is handled in {@link SamlAssertionConsumerHandler}.
*/
class AuthnHandler implements HttpHandler {
/** Manager that handles keeping track of users attempting to authenticate. */
private final SessionManager<HttpExchange> sessionManager;
/**
* Http client implementation that {@code SamlClient} will use to send
* requests directly to the GSA, for resolving SAML artifacts.
*/
private final HttpClientInterface httpClient;
/** Credentials to use to sign messages. */
private final Credential cred;
/** SAML configuration of endpoints. */
private final SamlMetadata metadata;
/**
* @param fallbackHostname fallback hostname in case we talk to an old HTTP
* client
* @param defaultEncoding encoding to use when sending simple text responses
* @param sessionManager manager for storing session state, like authn results
* @param keyAlias alias in keystore that contains the key for signing
* messages
* @param metadata SAML configuration of endpoints
*/
AuthnHandler(SessionManager<HttpExchange> sessionManager,
SamlMetadata metadata, KeyPair key) {
this(sessionManager, metadata, new HttpClientAdapter(), key);
}
AuthnHandler(SessionManager<HttpExchange> sessionManager,
SamlMetadata metadata, HttpClientInterface httpClient,
KeyPair key) {
if (sessionManager == null || metadata == null || httpClient == null) {
throw new NullPointerException();
}
this.sessionManager = sessionManager;
this.metadata = metadata;
this.httpClient = httpClient;
this.cred = (key == null) ? null
: SecurityHelper.getSimpleCredential(key.getPublic(), key.getPrivate());
}
@Override
public void handle(HttpExchange ex) throws IOException {
String requestMethod = ex.getRequestMethod();
if (!"GET".equals(requestMethod) && !"HEAD".equals(requestMethod)) {
HttpExchanges.cannedRespond(ex, HttpURLConnection.HTTP_BAD_METHOD,
Translation.HTTP_BAD_METHOD);
return;
}
Session session = sessionManager.getSession(ex);
AuthnState authnState = (AuthnState) session.getAttribute(
AuthnState.SESSION_ATTR_NAME);
if (authnState == null) {
authnState = new AuthnState();
session.setAttribute(AuthnState.SESSION_ATTR_NAME, authnState);
}
SamlClient client =
new SamlClient(
metadata.getLocalEntity(),
metadata.getPeerEntity(),
"GSA Adaptor",
cred,
httpClient);
authnState.startAttempt(client, HttpExchanges.getRequestUri(ex));
client.sendAuthnRequest(new HttpExchangeOutTransportAdapter(ex, true));
}
}