X-Git-Url: https://git.argeo.org/?a=blobdiff_plain;f=org.argeo.cms%2Fsrc%2Forg%2Fargeo%2Fcms%2Fauth%2FRemoteAuthUtils.java;h=4a8f18fcd811a11b516597e827d173542a441c50;hb=54df376a9c2dd458a82eaa09bfbb718fe699dd0d;hp=757bf73bfc43513fab8c004aaa3eb363a005f22a;hpb=8c6e16aa43d9523e1ec57a41a06b3ceba7d23fdb;p=lgpl%2Fargeo-commons.git diff --git a/org.argeo.cms/src/org/argeo/cms/auth/RemoteAuthUtils.java b/org.argeo.cms/src/org/argeo/cms/auth/RemoteAuthUtils.java index 757bf73bf..4a8f18fcd 100644 --- a/org.argeo.cms/src/org/argeo/cms/auth/RemoteAuthUtils.java +++ b/org.argeo.cms/src/org/argeo/cms/auth/RemoteAuthUtils.java @@ -1,7 +1,5 @@ package org.argeo.cms.auth; -import java.security.AccessControlContext; -import java.security.AccessController; import java.security.PrivilegedAction; import java.util.Base64; import java.util.function.Supplier; @@ -14,8 +12,10 @@ import javax.security.auth.login.LoginException; import org.argeo.api.cms.CmsAuth; import org.argeo.api.cms.CmsLog; import org.argeo.api.cms.CmsSession; +import org.argeo.cms.http.HttpHeader; +import org.argeo.cms.http.HttpStatus; import org.argeo.cms.internal.runtime.CmsContextImpl; -import org.argeo.util.http.HttpHeader; +import org.argeo.cms.util.CurrentSubject; import org.ietf.jgss.GSSContext; import org.ietf.jgss.GSSException; import org.ietf.jgss.GSSManager; @@ -44,47 +44,49 @@ public class RemoteAuthUtils { * Useful to log in to JCR. */ public final static T doAs(Supplier supplier, RemoteAuthRequest req) { - ClassLoader currentContextCl = Thread.currentThread().getContextClassLoader(); - Thread.currentThread().setContextClassLoader(RemoteAuthUtils.class.getClassLoader()); - try { - return Subject.doAs( - Subject.getSubject((AccessControlContext) req.getAttribute(AccessControlContext.class.getName())), - new PrivilegedAction() { - - @Override - public T run() { - return supplier.get(); - } - - }); - } finally { - Thread.currentThread().setContextClassLoader(currentContextCl); - } + CmsSession cmsSession = getCmsSession(req); + return CurrentSubject.callAs(cmsSession.getSubject(), () -> supplier.get()); +// ClassLoader currentContextCl = Thread.currentThread().getContextClassLoader(); +// Thread.currentThread().setContextClassLoader(RemoteAuthUtils.class.getClassLoader()); +// try { +// return Subject.doAs( +// Subject.getSubject((AccessControlContext) req.getAttribute(AccessControlContext.class.getName())), +// new PrivilegedAction() { +// +// @Override +// public T run() { +// return supplier.get(); +// } +// +// }); +// } finally { +// Thread.currentThread().setContextClassLoader(currentContextCl); +// } } - public final static void configureRequestSecurity(RemoteAuthRequest req) { - if (req.getAttribute(AccessControlContext.class.getName()) != null) - throw new IllegalStateException("Request already authenticated."); - AccessControlContext acc = AccessController.getContext(); - req.setAttribute(REMOTE_USER, CurrentUser.getUsername()); - req.setAttribute(AccessControlContext.class.getName(), acc); - } - - public final static void clearRequestSecurity(RemoteAuthRequest req) { - if (req.getAttribute(AccessControlContext.class.getName()) == null) - throw new IllegalStateException("Cannot clear non-authenticated request."); - req.setAttribute(REMOTE_USER, null); - req.setAttribute(AccessControlContext.class.getName(), null); - } +// public final static void configureRequestSecurity(RemoteAuthRequest req) { +// if (req.getAttribute(AccessControlContext.class.getName()) != null) +// throw new IllegalStateException("Request already authenticated."); +// AccessControlContext acc = AccessController.getContext(); +// req.setAttribute(REMOTE_USER, CurrentUser.getUsername()); +// req.setAttribute(AccessControlContext.class.getName(), acc); +// } +// +// public final static void clearRequestSecurity(RemoteAuthRequest req) { +// if (req.getAttribute(AccessControlContext.class.getName()) == null) +// throw new IllegalStateException("Cannot clear non-authenticated request."); +// req.setAttribute(REMOTE_USER, null); +// req.setAttribute(AccessControlContext.class.getName(), null); +// } public static CmsSession getCmsSession(RemoteAuthRequest req) { - Subject subject = Subject - .getSubject((AccessControlContext) req.getAttribute(AccessControlContext.class.getName())); - CmsSession cmsSession = CmsContextImpl.getCmsContext().getCmsSession(subject); + CmsSession cmsSession = (CmsSession) req.getAttribute(CmsSession.class.getName()); + if (cmsSession == null) + throw new IllegalStateException("Request must have a CMS session attribute"); return cmsSession; } - public static String getGssToken(Subject subject, String service, String server) { + public static String createGssToken(Subject subject, String service, String server) { if (subject.getPrivateCredentials(KerberosTicket.class).isEmpty()) throw new IllegalArgumentException("Subject " + subject + " is not GSS authenticated."); return Subject.doAs(subject, (PrivilegedAction) () -> { @@ -144,13 +146,25 @@ public class RemoteAuthUtils { } } - public static int askForWwwAuth(RemoteAuthResponse remoteAuthResponse, String realm, boolean forceBasic) { + public static int askForWwwAuth(RemoteAuthRequest remoteAuthRequest, RemoteAuthResponse remoteAuthResponse, + String realm, boolean forceBasic) { + boolean negotiateFailed = false; + if (remoteAuthRequest.getHeader(HttpHeader.AUTHORIZATION.getHeaderName()) != null) { + // we already tried, so we give up in order not too loop endlessly + if (remoteAuthRequest.getHeader(HttpHeader.AUTHORIZATION.getHeaderName()) + .startsWith(HttpHeader.NEGOTIATE)) { + negotiateFailed = true; + } else { + return HttpStatus.FORBIDDEN.getCode(); + } + } + // response.setHeader(HttpUtils.HEADER_WWW_AUTHENTICATE, "basic // realm=\"" + httpAuthRealm + "\""); - if (hasAcceptorCredentials() && !forceBasic)// SPNEGO - remoteAuthResponse.setHeader(HttpHeader.WWW_AUTHENTICATE.getName(), HttpHeader.NEGOTIATE); + if (hasAcceptorCredentials() && !forceBasic && !negotiateFailed)// SPNEGO + remoteAuthResponse.setHeader(HttpHeader.WWW_AUTHENTICATE.getHeaderName(), HttpHeader.NEGOTIATE); else - remoteAuthResponse.setHeader(HttpHeader.WWW_AUTHENTICATE.getName(), + remoteAuthResponse.setHeader(HttpHeader.WWW_AUTHENTICATE.getHeaderName(), HttpHeader.BASIC + " " + HttpHeader.REALM + "=\"" + realm + "\""); // response.setDateHeader("Date", System.currentTimeMillis()); @@ -161,7 +175,7 @@ public class RemoteAuthUtils { // response.setHeader("Keep-Alive", "timeout=5, max=97"); // response.setContentType("text/html; charset=UTF-8"); - return 401; + return HttpStatus.UNAUTHORIZED.getCode(); } private static boolean hasAcceptorCredentials() {