]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.cms/src/org/argeo/cms/internal/http/CmsAuthenticator.java
Move CMS file utilities to a dedicated package
[lgpl/argeo-commons.git] / org.argeo.cms / src / org / argeo / cms / internal / http / CmsAuthenticator.java
1 package org.argeo.cms.internal.http;
2
3 import javax.security.auth.Subject;
4 import javax.security.auth.login.LoginContext;
5 import javax.security.auth.login.LoginException;
6
7 import org.argeo.api.cms.CmsAuth;
8 import org.argeo.api.cms.CmsLog;
9 import org.argeo.cms.auth.CurrentUser;
10 import org.argeo.cms.auth.RemoteAuthCallbackHandler;
11 import org.argeo.cms.auth.RemoteAuthRequest;
12 import org.argeo.cms.auth.RemoteAuthResponse;
13 import org.argeo.cms.auth.RemoteAuthUtils;
14 import org.argeo.util.CurrentSubject;
15
16 import com.sun.net.httpserver.Authenticator;
17 import com.sun.net.httpserver.HttpExchange;
18 import com.sun.net.httpserver.HttpPrincipal;
19
20 public class CmsAuthenticator extends Authenticator {
21 // final static String HEADER_AUTHORIZATION = "Authorization";
22 // final static String HEADER_WWW_AUTHENTICATE = "WWW-Authenticate";
23
24 private final static CmsLog log = CmsLog.getLog(CmsAuthenticator.class);
25
26 // TODO make it configurable
27 private final String httpAuthRealm = "Argeo";
28 private final boolean forceBasic = false;
29
30 @Override
31 public Result authenticate(HttpExchange exch) {
32 // if (log.isTraceEnabled())
33 // HttpUtils.logRequestHeaders(log, request);
34 RemoteAuthHttpExchange remoteAuthExchange = new RemoteAuthHttpExchange(exch);
35 ClassLoader currentThreadContextClassLoader = Thread.currentThread().getContextClassLoader();
36 Thread.currentThread().setContextClassLoader(CmsAuthenticator.class.getClassLoader());
37 LoginContext lc;
38 try {
39 lc = CmsAuth.USER.newLoginContext(new RemoteAuthCallbackHandler(remoteAuthExchange, remoteAuthExchange));
40 lc.login();
41 } catch (LoginException e) {
42 // FIXME better analyse failure so as not to try endlessly
43 if (authIsRequired(remoteAuthExchange,remoteAuthExchange)) {
44 int statusCode = RemoteAuthUtils.askForWwwAuth(remoteAuthExchange, httpAuthRealm, forceBasic);
45 return new Authenticator.Retry(statusCode);
46
47 } else {
48 lc = RemoteAuthUtils.anonymousLogin(remoteAuthExchange, remoteAuthExchange);
49 }
50 if (lc == null)
51 return new Authenticator.Failure(403);
52 } finally {
53 Thread.currentThread().setContextClassLoader(currentThreadContextClassLoader);
54 }
55
56 Subject subject = lc.getSubject();
57
58 CurrentSubject.callAs(subject, () -> {
59 RemoteAuthUtils.configureRequestSecurity(remoteAuthExchange);
60 return null;
61 });
62 // Subject.doAs(subject, new PrivilegedAction<Void>() {
63 //
64 // @Override
65 // public Void run() {
66 // // TODO also set login context in order to log out ?
67 // RemoteAuthUtils.configureRequestSecurity(new ServletHttpRequest(request));
68 // return null;
69 // }
70 //
71 // });
72 String username = CurrentUser.getUsername(subject);
73 HttpPrincipal httpPrincipal = new HttpPrincipal(username, httpAuthRealm);
74 return new Authenticator.Success(httpPrincipal);
75 }
76
77 protected boolean authIsRequired(RemoteAuthRequest remoteAuthRequest,
78 RemoteAuthResponse remoteAuthResponse) {
79 return true;
80 }
81
82 }