1 package org
.argeo
.cms
.internal
.http
;
3 import java
.io
.IOException
;
6 import javax
.security
.auth
.login
.LoginContext
;
7 import javax
.security
.auth
.login
.LoginException
;
8 import javax
.servlet
.http
.HttpServletRequest
;
9 import javax
.servlet
.http
.HttpServletResponse
;
11 import org
.apache
.commons
.logging
.Log
;
12 import org
.apache
.commons
.logging
.LogFactory
;
13 import org
.argeo
.cms
.auth
.HttpRequestCallbackHandler
;
14 import org
.argeo
.node
.NodeConstants
;
15 import org
.osgi
.framework
.BundleContext
;
16 import org
.osgi
.framework
.FrameworkUtil
;
17 import org
.osgi
.service
.http
.HttpContext
;
19 class DataHttpContext
implements HttpContext
{
20 private final static Log log
= LogFactory
.getLog(DataHttpContext
.class);
22 private final BundleContext bc
= FrameworkUtil
.getBundle(getClass()).getBundleContext();
24 // FIXME Make it more unique
25 private final String httpAuthRealm
;
26 private final boolean forceBasic
;
28 public DataHttpContext(String httpAuthrealm
, boolean forceBasic
) {
29 this.httpAuthRealm
= httpAuthrealm
;
30 this.forceBasic
= forceBasic
;
33 public DataHttpContext(String httpAuthrealm
) {
34 this(httpAuthrealm
, false);
38 public boolean handleSecurity(final HttpServletRequest request
, HttpServletResponse response
) throws IOException
{
40 if (log
.isTraceEnabled())
41 HttpUtils
.logRequestHeaders(log
, request
);
44 lc
= new LoginContext(NodeConstants
.LOGIN_CONTEXT_USER
, new HttpRequestCallbackHandler(request
, response
));
47 } catch (LoginException e
) {
48 // CallbackHandler token = extractHttpAuth(request, response);
49 // String token = request.getHeader(HttpUtils.HEADER_AUTHORIZATION);
50 // if (token != null) {
52 // lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER);
54 // } catch (LoginException e1) {
55 // throw new CmsException("Could not login", e1);
58 lc
= processUnauthorized(request
, response
);
64 // still required by open session in view
66 request
.setAttribute(NodeConstants
.LOGIN_CONTEXT_USER
, lc
);
71 public URL
getResource(String name
) {
72 return bc
.getBundle().getResource(name
);
76 public String
getMimeType(String name
) {
80 protected LoginContext
processUnauthorized(HttpServletRequest request
, HttpServletResponse response
) {
83 LoginContext lc
= new LoginContext(NodeConstants
.LOGIN_CONTEXT_USER
);
86 } catch (LoginException e1
) {
87 if (log
.isDebugEnabled())
88 log
.error("Cannot log in as anonymous", e1
);
93 // protected CallbackHandler extractHttpAuth(final HttpServletRequest
94 // httpRequest, HttpServletResponse httpResponse) {
95 // String authHeader =
96 // httpRequest.getHeader(HttpUtils.HEADER_AUTHORIZATION);
97 // if (authHeader != null) {
98 // StringTokenizer st = new StringTokenizer(authHeader);
99 // if (st.hasMoreTokens()) {
100 // String basic = st.nextToken();
101 // if (basic.equalsIgnoreCase("Basic")) {
103 // // TODO manipulate char[]
104 // String credentials = new String(Base64.decodeBase64(st.nextToken()),
106 // // log.debug("Credentials: " + credentials);
107 // int p = credentials.indexOf(":");
109 // final String login = credentials.substring(0, p).trim();
110 // final char[] password = credentials.substring(p +
111 // 1).trim().toCharArray();
112 // return new CallbackHandler() {
113 // public void handle(Callback[] callbacks) {
114 // for (Callback cb : callbacks) {
115 // if (cb instanceof NameCallback)
116 // ((NameCallback) cb).setName(login);
117 // else if (cb instanceof PasswordCallback)
118 // ((PasswordCallback) cb).setPassword(password);
119 // else if (cb instanceof HttpRequestCallback) {
120 // ((HttpRequestCallback) cb).setRequest(httpRequest);
121 // ((HttpRequestCallback) cb).setResponse(httpResponse);
127 // throw new CmsException("Invalid authentication token");
129 // } catch (Exception e) {
130 // throw new CmsException("Couldn't retrieve authentication", e);
132 // } else if (basic.equalsIgnoreCase("Negotiate")) {
133 // // FIXME generalise
134 // String _targetName;
136 // _targetName = NodeHttp.DEFAULT_SERVICE + "@"
137 // + InetAddress.getLocalHost().getCanonicalHostName();
138 // } catch (UnknownHostException e) {
139 // throw new CmsException("Cannot determins target name", e);
141 // String spnegoToken = st.nextToken();
142 // byte[] authToken = Base64.decodeBase64(spnegoToken);
143 // GSSManager manager = GSSManager.getInstance();
145 //// Oid krb5Oid = new Oid("1.3.6.1.5.5.2"); //
146 // http://java.sun.com/javase/6/docs/technotes/guides/security/jgss/jgss-features.html
147 //// GSSName gssName = manager.createName(_targetName,
148 // GSSName.NT_HOSTBASED_SERVICE, krb5Oid);
149 //// GSSCredential serverCreds = manager.createCredential(gssName,
150 // GSSCredential.INDEFINITE_LIFETIME,
151 //// krb5Oid, GSSCredential.ACCEPT_ONLY);
152 // GSSCredential serverCreds = Activator.getAcceptorCredentials();
153 // if(serverCreds==null)
154 // throw new CmsException("No GSS server credentials available");
155 // GSSContext gContext = manager.createContext(serverCreds);
157 // if (gContext == null) {
158 // log.debug("SpnegoUserRealm: failed to establish GSSContext");
160 // while (!gContext.isEstablished()) {
161 // byte[] outToken = gContext.acceptSecContext(authToken, 0,
162 // authToken.length);
163 // String outTokenStr = Base64.encodeBase64String(outToken);
164 // httpResponse.setHeader("WWW-Authenticate", "Negotiate " + outTokenStr);
166 // if (gContext.isEstablished()) {
167 // String clientName = gContext.getSrcName().toString();
168 // String role = clientName.substring(clientName.indexOf('@') + 1);
170 // log.debug("SpnegoUserRealm: established a security context");
171 // log.debug("Client Principal is: " + gContext.getSrcName());
172 // log.debug("Server Principal is: " + gContext.getTargName());
173 // log.debug("Client Default Role: " + role);
179 // } catch (GSSException gsse) {
180 // log.warn(gsse, gsse);
189 protected void askForWwwAuth(HttpServletRequest request
, HttpServletResponse response
) {
190 response
.setStatus(401);
191 // response.setHeader(HttpUtils.HEADER_WWW_AUTHENTICATE, "basic
192 // realm=\"" + httpAuthRealm + "\"");
193 if (org
.argeo
.cms
.internal
.kernel
.Activator
.getAcceptorCredentials() != null && !forceBasic
)// SPNEGO
194 response
.setHeader(HttpUtils
.HEADER_WWW_AUTHENTICATE
, "Negotiate");
196 response
.setHeader(HttpUtils
.HEADER_WWW_AUTHENTICATE
, "Basic realm=\"" + httpAuthRealm
+ "\"");
198 // response.setDateHeader("Date", System.currentTimeMillis());
199 // response.setDateHeader("Expires", System.currentTimeMillis() + (24 *
201 // response.setHeader("Accept-Ranges", "bytes");
202 // response.setHeader("Connection", "Keep-Alive");
203 // response.setHeader("Keep-Alive", "timeout=5, max=97");
204 // response.setContentType("text/html; charset=UTF-8");