/******************************************************************************* * Copyright (c) 2008, 2011 VMware Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VMware Inc. - initial contribution *******************************************************************************/ package org.eclipse.virgo.management.console.internal; import java.io.IOException; import java.net.URL; import java.util.StringTokenizer; import javax.security.auth.Subject; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.NameCallback; import javax.security.auth.callback.PasswordCallback; import javax.security.auth.callback.UnsupportedCallbackException; import javax.security.auth.login.LoginContext; import javax.security.auth.login.LoginException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.eclipse.osgi.internal.signedcontent.Base64; import org.osgi.framework.Bundle; import org.osgi.service.http.HttpContext; /** * * */ public class AdminHttpContext implements HttpContext { private static final String REALM = "Virgo Admin Console"; private final Bundle bundle; public AdminHttpContext(Bundle bundle) { this.bundle = bundle; } @Override public boolean handleSecurity(HttpServletRequest request, HttpServletResponse response) throws IOException { String auth = request.getHeader("Authorization"); if (auth == null) { return reject(request, response); } StringTokenizer tokens = new StringTokenizer(auth); String authscheme = tokens.nextToken(); if (!authscheme.equals("Basic")) { return reject(request, response); } String base64credentials = tokens.nextToken(); String credentials = new String(Base64.decode(base64credentials.getBytes())); int colon = credentials.indexOf(':'); String userid = credentials.substring(0, colon); String password = credentials.substring(colon + 1); try { Subject subject = login(request.getSession(true), userid, password); if(subject == null){ return reject(request, response); } request.setAttribute(HttpContext.REMOTE_USER, userid); request.setAttribute(HttpContext.AUTHENTICATION_TYPE, authscheme); request.setAttribute(HttpContext.AUTHORIZATION, subject); return true; } catch (LoginException e) { return reject(request, response); } } @Override public URL getResource(final String name) { return bundle.getEntry(name); } @Override public String getMimeType(String name) { return null; } @SuppressWarnings("deprecation") private Subject login(final HttpSession session, final String userid, final String password) throws LoginException { if (session == null){ return null; } LoginContext context = (LoginContext) session.getValue("securitycontext"); if (context != null){ return context.getSubject(); } context = new LoginContext("virgo-kernel", new CallbackHandler() { public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { for (int i = 0; i < callbacks.length; i++) { if (callbacks[i] instanceof NameCallback){ ((NameCallback) callbacks[i]).setName(userid); } else if (callbacks[i] instanceof PasswordCallback){ ((PasswordCallback) callbacks[i]).setPassword(password.toCharArray()); } else { throw new UnsupportedCallbackException(callbacks[i]); } } } }); context.login(); Subject result = context.getSubject(); if(result == null){ return null; } session.putValue("securitycontext", context); return result; } private boolean reject(HttpServletRequest request, HttpServletResponse response) { request.getSession(true); response.setHeader("WWW-Authenticate", "Basic realm=\"" + REALM + "\""); try { response.sendError(HttpServletResponse.SC_UNAUTHORIZED); } catch (IOException e) { // no-op } return false; } }