/jetty-plus/src/main/java/org/eclipse/jetty/plus/jaas/JAASLoginService.java
Java | 310 lines | 202 code | 36 blank | 72 comment | 14 complexity | bb181379f86b8b3612960fa85c795145 MD5 | raw file
- // ========================================================================
- // Copyright (c) 2003-2009 Mort Bay Consulting Pty. Ltd.
- // ------------------------------------------------------------------------
- // All rights reserved. This program and the accompanying materials
- // are made available under the terms of the Eclipse Public License v1.0
- // and Apache License v2.0 which accompanies this distribution.
- // The Eclipse Public License is available at
- // http://www.eclipse.org/legal/epl-v10.html
- // The Apache License v2.0 is available at
- // http://www.opensource.org/licenses/apache2.0.php
- // You may elect to redistribute this code under either of these licenses.
- // ========================================================================
- package org.eclipse.jetty.plus.jaas;
- import java.io.IOException;
- import java.security.Principal;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.Collection;
- import java.util.LinkedHashSet;
- import java.util.Set;
- 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 org.eclipse.jetty.plus.jaas.callback.ObjectCallback;
- import org.eclipse.jetty.security.DefaultIdentityService;
- import org.eclipse.jetty.security.IdentityService;
- import org.eclipse.jetty.security.LoginService;
- import org.eclipse.jetty.server.UserIdentity;
- import org.eclipse.jetty.util.Loader;
- import org.eclipse.jetty.util.component.AbstractLifeCycle;
- import org.eclipse.jetty.util.log.Log;
- import org.eclipse.jetty.util.log.Logger;
- /* ---------------------------------------------------- */
- /** JAASLoginService
- *
- * @org.apache.xbean.XBean element="jaasUserRealm" description="Creates a UserRealm suitable for use with JAAS"
- */
- public class JAASLoginService extends AbstractLifeCycle implements LoginService
- {
- private static final Logger LOG = Log.getLogger(JAASLoginService.class);
- public static String DEFAULT_ROLE_CLASS_NAME = "org.eclipse.jetty.plus.jaas.JAASRole";
- public static String[] DEFAULT_ROLE_CLASS_NAMES = {DEFAULT_ROLE_CLASS_NAME};
-
- protected String[] _roleClassNames = DEFAULT_ROLE_CLASS_NAMES;
- protected String _callbackHandlerClass;
- protected String _realmName;
- protected String _loginModuleName;
- protected JAASUserPrincipal _defaultUser = new JAASUserPrincipal(null, null, null);
- protected IdentityService _identityService;
-
- /* ---------------------------------------------------- */
- /**
- * Constructor.
- *
- */
- public JAASLoginService()
- {
- }
-
- /* ---------------------------------------------------- */
- /**
- * Constructor.
- *
- * @param name the name of the realm
- */
- public JAASLoginService(String name)
- {
- this();
- _realmName = name;
- _loginModuleName = name;
- }
- /* ---------------------------------------------------- */
- /**
- * Get the name of the realm.
- *
- * @return name or null if not set.
- */
- public String getName()
- {
- return _realmName;
- }
- /* ---------------------------------------------------- */
- /**
- * Set the name of the realm
- *
- * @param name a <code>String</code> value
- */
- public void setName (String name)
- {
- _realmName = name;
- }
- /* ------------------------------------------------------------ */
- /** Get the identityService.
- * @return the identityService
- */
- public IdentityService getIdentityService()
- {
- return _identityService;
- }
- /* ------------------------------------------------------------ */
- /** Set the identityService.
- * @param identityService the identityService to set
- */
- public void setIdentityService(IdentityService identityService)
- {
- _identityService = identityService;
- }
- /* ------------------------------------------------------------ */
- /**
- * Set the name to use to index into the config
- * file of LoginModules.
- *
- * @param name a <code>String</code> value
- */
- public void setLoginModuleName (String name)
- {
- _loginModuleName = name;
- }
- /* ------------------------------------------------------------ */
- public void setCallbackHandlerClass (String classname)
- {
- _callbackHandlerClass = classname;
- }
- /* ------------------------------------------------------------ */
- public void setRoleClassNames (String[] classnames)
- {
- ArrayList<String> tmp = new ArrayList<String>();
-
- if (classnames != null)
- tmp.addAll(Arrays.asList(classnames));
-
- if (!tmp.contains(DEFAULT_ROLE_CLASS_NAME))
- tmp.add(DEFAULT_ROLE_CLASS_NAME);
- _roleClassNames = tmp.toArray(new String[tmp.size()]);
- }
- /* ------------------------------------------------------------ */
- public String[] getRoleClassNames()
- {
- return _roleClassNames;
- }
- /* ------------------------------------------------------------ */
- /**
- * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart()
- */
- protected void doStart() throws Exception
- {
- if (_identityService==null)
- _identityService=new DefaultIdentityService();
- super.doStart();
- }
- /* ------------------------------------------------------------ */
- public UserIdentity login(final String username,final Object credentials)
- {
- try
- {
- CallbackHandler callbackHandler = null;
-
-
- if (_callbackHandlerClass == null)
- {
- callbackHandler = new CallbackHandler()
- {
- public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException
- {
- for (Callback callback: callbacks)
- {
- if (callback instanceof NameCallback)
- {
- ((NameCallback)callback).setName(username);
- }
- else if (callback instanceof PasswordCallback)
- {
- ((PasswordCallback)callback).setPassword((char[]) credentials.toString().toCharArray());
- }
- else if (callback instanceof ObjectCallback)
- {
- ((ObjectCallback)callback).setObject(credentials);
- }
- }
- }
- };
- }
- else
- {
- Class clazz = Loader.loadClass(getClass(), _callbackHandlerClass);
- callbackHandler = (CallbackHandler)clazz.newInstance();
- }
- //set up the login context
- //TODO jaspi requires we provide the Configuration parameter
- Subject subject = new Subject();
- LoginContext loginContext = new LoginContext(_loginModuleName, subject, callbackHandler);
- loginContext.login();
- //login success
- JAASUserPrincipal userPrincipal = new JAASUserPrincipal(getUserName(callbackHandler), subject, loginContext);
- subject.getPrincipals().add(userPrincipal);
-
- return _identityService.newUserIdentity(subject,userPrincipal,getGroups(subject));
- }
- catch (LoginException e)
- {
- LOG.warn(e);
- }
- catch (IOException e)
- {
- LOG.warn(e);
- }
- catch (UnsupportedCallbackException e)
- {
- LOG.warn(e);
- }
- catch (InstantiationException e)
- {
- LOG.warn(e);
- }
- catch (IllegalAccessException e)
- {
- LOG.warn(e);
- }
- catch (ClassNotFoundException e)
- {
- LOG.warn(e);
- }
- return null;
- }
- /* ------------------------------------------------------------ */
- public boolean validate(UserIdentity user)
- {
- // TODO optionally check user is still valid
- return true;
- }
- /* ------------------------------------------------------------ */
- private String getUserName(CallbackHandler callbackHandler) throws IOException, UnsupportedCallbackException
- {
- NameCallback nameCallback = new NameCallback("foo");
- callbackHandler.handle(new Callback[] {nameCallback});
- return nameCallback.getName();
- }
- /* ------------------------------------------------------------ */
- public void logout(UserIdentity user)
- {
- Set<JAASUserPrincipal> userPrincipals = user.getSubject().getPrincipals(JAASUserPrincipal.class);
- LoginContext loginContext = userPrincipals.iterator().next().getLoginContext();
- try
- {
- loginContext.logout();
- }
- catch (LoginException e)
- {
- LOG.warn(e);
- }
- }
- /* ------------------------------------------------------------ */
- @SuppressWarnings({ "unchecked", "rawtypes" })
- private String[] getGroups (Subject subject)
- {
- //get all the roles of the various types
- String[] roleClassNames = getRoleClassNames();
- Collection<String> groups = new LinkedHashSet<String>();
- try
- {
- for (String roleClassName : roleClassNames)
- {
- Class load_class = Thread.currentThread().getContextClassLoader().loadClass(roleClassName);
- Set<Principal> rolesForType = subject.getPrincipals(load_class);
- for (Principal principal : rolesForType)
- {
- groups.add(principal.getName());
- }
- }
-
- return groups.toArray(new String[groups.size()]);
- }
- catch (ClassNotFoundException e)
- {
- throw new RuntimeException(e);
- }
- }
- }