import javax.security.auth.login.LoginException;
import org.argeo.api.cms.CmsAuth;
-import org.argeo.api.cms.CmsLog;
-import org.argeo.cms.auth.CurrentUser;
+import org.argeo.cms.CurrentUser;
import org.argeo.cms.auth.RemoteAuthCallbackHandler;
-import org.argeo.cms.auth.SpnegoLoginModule;
+import org.argeo.cms.auth.RemoteAuthRequest;
+import org.argeo.cms.auth.RemoteAuthResponse;
+import org.argeo.cms.auth.RemoteAuthUtils;
import com.sun.net.httpserver.Authenticator;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpPrincipal;
+/** An {@link Authenticator} implementation based on CMS authentication. */
public class CmsAuthenticator extends Authenticator {
- final static String HEADER_AUTHORIZATION = "Authorization";
- final static String HEADER_WWW_AUTHENTICATE = "WWW-Authenticate";
-
- private final static CmsLog log = CmsLog.getLog(CmsAuthenticator.class);
-
// TODO make it configurable
private final String httpAuthRealm = "Argeo";
private final boolean forceBasic = false;
@Override
public Result authenticate(HttpExchange exch) {
-// if (log.isTraceEnabled())
-// HttpUtils.logRequestHeaders(log, request);
- RemoteAuthHttpExchange remoteAuthHttpExchange = new RemoteAuthHttpExchange(exch);
+ RemoteAuthHttpExchange remoteAuthExchange = new RemoteAuthHttpExchange(exch);
ClassLoader currentThreadContextClassLoader = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(CmsAuthenticator.class.getClassLoader());
LoginContext lc;
try {
- lc = CmsAuth.USER
- .newLoginContext(new RemoteAuthCallbackHandler(remoteAuthHttpExchange, remoteAuthHttpExchange));
+ lc = CmsAuth.USER.newLoginContext(new RemoteAuthCallbackHandler(remoteAuthExchange, remoteAuthExchange));
lc.login();
} catch (LoginException e) {
- // FIXME better analyse failure so as not to try endlessly
- if (authIsRequired(exch)) {
- return askForWwwAuth(exch);
+ if (authIsRequired(remoteAuthExchange, remoteAuthExchange)) {
+ int statusCode = RemoteAuthUtils.askForWwwAuth(remoteAuthExchange, remoteAuthExchange, httpAuthRealm,
+ forceBasic);
+ return new Authenticator.Retry(statusCode);
+
} else {
- lc = processUnauthorized(exch);
-// if (log.isTraceEnabled())
-// HttpUtils.logResponseHeaders(log, response);
+ lc = RemoteAuthUtils.anonymousLogin(remoteAuthExchange, remoteAuthExchange);
}
if (lc == null)
return new Authenticator.Failure(403);
Subject subject = lc.getSubject();
-// Subject.doAs(subject, new PrivilegedAction<Void>() {
-//
-// @Override
-// public Void run() {
-// // TODO also set login context in order to log out ?
-// RemoteAuthUtils.configureRequestSecurity(new ServletHttpRequest(request));
-// return null;
-// }
-//
-// });
String username = CurrentUser.getUsername(subject);
HttpPrincipal httpPrincipal = new HttpPrincipal(username, httpAuthRealm);
return new Authenticator.Success(httpPrincipal);
}
- protected boolean authIsRequired(HttpExchange httpExchange) {
- return false;
- }
-
- protected LoginContext processUnauthorized(HttpExchange httpExchange) {
-
- RemoteAuthHttpExchange remoteAuthExchange = new RemoteAuthHttpExchange(httpExchange);
- // anonymous
- ClassLoader currentContextClassLoader = Thread.currentThread().getContextClassLoader();
- try {
- Thread.currentThread().setContextClassLoader(CmsAuthenticator.class.getClassLoader());
- LoginContext lc = CmsAuth.ANONYMOUS
- .newLoginContext(new RemoteAuthCallbackHandler(remoteAuthExchange, remoteAuthExchange));
- lc.login();
- return lc;
- } catch (LoginException e1) {
- if (log.isDebugEnabled())
- log.error("Cannot log in as anonymous", e1);
- return null;
- } finally {
- Thread.currentThread().setContextClassLoader(currentContextClassLoader);
- }
- }
-
- protected Authenticator.Retry askForWwwAuth(HttpExchange httpExchange) {
- // response.setHeader(HttpUtils.HEADER_WWW_AUTHENTICATE, "basic
- // realm=\"" + httpAuthRealm + "\"");
- if (SpnegoLoginModule.hasAcceptorCredentials() && !forceBasic)// SPNEGO
- httpExchange.getResponseHeaders().set(HEADER_WWW_AUTHENTICATE, "Negotiate");
- else
- httpExchange.getResponseHeaders().set(HEADER_WWW_AUTHENTICATE, "Basic realm=\"" + httpAuthRealm + "\"");
-
- // response.setDateHeader("Date", System.currentTimeMillis());
- // response.setDateHeader("Expires", System.currentTimeMillis() + (24 *
- // 60 * 60 * 1000));
- // response.setHeader("Accept-Ranges", "bytes");
- // response.setHeader("Connection", "Keep-Alive");
- // response.setHeader("Keep-Alive", "timeout=5, max=97");
- // response.setContentType("text/html; charset=UTF-8");
-
- return new Authenticator.Retry(401);
+ protected boolean authIsRequired(RemoteAuthRequest remoteAuthRequest, RemoteAuthResponse remoteAuthResponse) {
+ return true;
}
}