* Issue #2445 Optionally expose request for jaas Signed-off-by: Jan Bartel <janb@webtide.com>
This commit is contained in:
parent
0e971e07d6
commit
44dfa868df
|
@ -377,11 +377,15 @@ The `AbstractLoginModule` does not support any caching, so if you want to cache
|
|||
|
||||
==== Other Goodies
|
||||
|
||||
===== ServletRequestCallback
|
||||
|
||||
This callback gives you access to the ServletRequest that is involved in the authentication, and thus to other features like the current Session. This callback can be configured in your custom LoginModule implementation. Note that none of the LoginModule implementations provided with Jetty currently use this callback.
|
||||
|
||||
===== RequestParameterCallback
|
||||
|
||||
As all servlet containers intercept and process a form submission with action `j_security_check`, it is usually not possible to insert any extra input fields onto a login form with which to perform authentication: you may only pass `j_username` and `j_password`.
|
||||
For those rare occasions when this is not good enough, and you require more information from the user in order to authenticate them, you can use the JAAS callback handler `org.eclipse.jetty.jaas.callback.RequestParameterCallback`.
|
||||
This callback handler gives you access to all parameters that were passed in the form submission.
|
||||
This callback gives you access to all parameters that were passed in the form submission.
|
||||
To use it, in the `login()` method of your custom login module, add the `RequestParameterCallback` to the list of callback handlers the login module uses, tell it which params you are interested in, and then get the value of the parameter back.
|
||||
Here is an example:
|
||||
|
||||
|
|
|
@ -31,15 +31,19 @@ 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.Configuration;
|
||||
import javax.security.auth.login.LoginContext;
|
||||
import javax.security.auth.login.LoginException;
|
||||
import javax.servlet.ServletRequest;
|
||||
|
||||
import org.eclipse.jetty.jaas.callback.ServletRequestCallback;
|
||||
import org.eclipse.jetty.jaas.callback.DefaultCallbackHandler;
|
||||
import org.eclipse.jetty.jaas.callback.ObjectCallback;
|
||||
import org.eclipse.jetty.jaas.callback.RequestParameterCallback;
|
||||
import org.eclipse.jetty.security.DefaultIdentityService;
|
||||
import org.eclipse.jetty.security.IdentityService;
|
||||
import org.eclipse.jetty.security.LoginService;
|
||||
import org.eclipse.jetty.server.Request;
|
||||
import org.eclipse.jetty.server.UserIdentity;
|
||||
import org.eclipse.jetty.util.ArrayUtil;
|
||||
import org.eclipse.jetty.util.Loader;
|
||||
|
@ -69,11 +73,10 @@ public class JAASLoginService extends AbstractLifeCycle implements LoginService
|
|||
protected String _loginModuleName;
|
||||
protected JAASUserPrincipal _defaultUser = new JAASUserPrincipal(null, null, null);
|
||||
protected IdentityService _identityService;
|
||||
protected Configuration _configuration;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public JAASLoginService()
|
||||
{
|
||||
}
|
||||
|
@ -117,7 +120,28 @@ public class JAASLoginService extends AbstractLifeCycle implements LoginService
|
|||
}
|
||||
|
||||
|
||||
/** Get the identityService.
|
||||
/**
|
||||
* @return the configuration
|
||||
*/
|
||||
public Configuration getConfiguration()
|
||||
{
|
||||
return _configuration;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param configuration the configuration to set
|
||||
*/
|
||||
public void setConfiguration(Configuration configuration)
|
||||
{
|
||||
_configuration = configuration;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get the identityService.
|
||||
* @return the identityService
|
||||
*/
|
||||
@Override
|
||||
|
@ -127,7 +151,8 @@ public class JAASLoginService extends AbstractLifeCycle implements LoginService
|
|||
}
|
||||
|
||||
|
||||
/** Set the identityService.
|
||||
/**
|
||||
* Set the identityService.
|
||||
* @param identityService the identityService to set
|
||||
*/
|
||||
@Override
|
||||
|
@ -189,8 +214,6 @@ public class JAASLoginService extends AbstractLifeCycle implements LoginService
|
|||
try
|
||||
{
|
||||
CallbackHandler callbackHandler = null;
|
||||
|
||||
|
||||
if (_callbackHandlerClass == null)
|
||||
{
|
||||
callbackHandler = new CallbackHandler()
|
||||
|
@ -218,6 +241,10 @@ public class JAASLoginService extends AbstractLifeCycle implements LoginService
|
|||
if (request!=null)
|
||||
rpc.setParameterValues(Arrays.asList(request.getParameterValues(rpc.getParameterName())));
|
||||
}
|
||||
else if (callback instanceof ServletRequestCallback)
|
||||
{
|
||||
((ServletRequestCallback)callback).setRequest(request);
|
||||
}
|
||||
else
|
||||
throw new UnsupportedCallbackException(callback);
|
||||
}
|
||||
|
@ -228,11 +255,20 @@ public class JAASLoginService extends AbstractLifeCycle implements LoginService
|
|||
{
|
||||
Class<?> clazz = Loader.loadClass(_callbackHandlerClass);
|
||||
callbackHandler = (CallbackHandler)clazz.getDeclaredConstructor().newInstance();
|
||||
if (DefaultCallbackHandler.class.isAssignableFrom(clazz))
|
||||
{
|
||||
DefaultCallbackHandler dch = (DefaultCallbackHandler)callbackHandler;
|
||||
if (request instanceof Request)
|
||||
dch.setRequest((Request)request);
|
||||
dch.setCredential(credentials);
|
||||
dch.setUserName(username);
|
||||
}
|
||||
}
|
||||
|
||||
//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 loginContext = (_configuration==null?new LoginContext(_loginModuleName, subject, callbackHandler)
|
||||
:new LoginContext(_loginModuleName, subject, callbackHandler, _configuration));
|
||||
|
||||
loginContext.login();
|
||||
|
||||
|
|
|
@ -30,7 +30,10 @@ import org.eclipse.jetty.server.Request;
|
|||
import org.eclipse.jetty.util.security.Password;
|
||||
|
||||
/**
|
||||
* DefaultUsernameCredentialCallbackHandler
|
||||
* DefaultCallbackHandler
|
||||
*
|
||||
* An implementation of the JAAS CallbackHandler. Users can provide
|
||||
* their own implementation instead and set the name of its class on the JAASLoginService.
|
||||
*/
|
||||
public class DefaultCallbackHandler extends AbstractCallbackHandler
|
||||
{
|
||||
|
@ -38,7 +41,7 @@ public class DefaultCallbackHandler extends AbstractCallbackHandler
|
|||
|
||||
public void setRequest (Request request)
|
||||
{
|
||||
this._request = request;
|
||||
_request = request;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -71,6 +74,10 @@ public class DefaultCallbackHandler extends AbstractCallbackHandler
|
|||
RequestParameterCallback callback = (RequestParameterCallback)callbacks[i];
|
||||
callback.setParameterValues(Arrays.asList(_request.getParameterValues(callback.getParameterName())));
|
||||
}
|
||||
else if (callbacks[i] instanceof ServletRequestCallback)
|
||||
{
|
||||
((ServletRequestCallback)callbacks[i]).setRequest(_request);
|
||||
}
|
||||
else
|
||||
throw new UnsupportedCallbackException(callbacks[i]);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2018 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.jaas.callback;
|
||||
|
||||
import javax.security.auth.callback.Callback;
|
||||
import javax.servlet.ServletRequest;
|
||||
|
||||
|
||||
/**
|
||||
* ServletRequestCallback
|
||||
*
|
||||
* Provides access to the request associated with the authentication.
|
||||
*/
|
||||
public class ServletRequestCallback implements Callback
|
||||
{
|
||||
protected ServletRequest _request;
|
||||
|
||||
public void setRequest (ServletRequest request)
|
||||
{
|
||||
_request = request;
|
||||
}
|
||||
|
||||
public ServletRequest getRequest ()
|
||||
{
|
||||
return _request;
|
||||
}
|
||||
}
|
|
@ -115,6 +115,12 @@ public abstract class AbstractLoginModule implements LoginModule
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public abstract UserInfo getUserInfo (String username) throws Exception;
|
||||
|
||||
|
||||
|
||||
public Subject getSubject ()
|
||||
{
|
||||
return this.subject;
|
||||
|
@ -198,7 +204,6 @@ public abstract class AbstractLoginModule implements LoginModule
|
|||
|
||||
public Callback[] configureCallbacks ()
|
||||
{
|
||||
|
||||
Callback[] callbacks = new Callback[3];
|
||||
callbacks[0] = new NameCallback("Enter user name");
|
||||
callbacks[1] = new ObjectCallback();
|
||||
|
@ -211,9 +216,7 @@ public abstract class AbstractLoginModule implements LoginModule
|
|||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public abstract UserInfo getUserInfo (String username) throws Exception;
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -23,9 +23,15 @@ import static org.junit.Assert.assertEquals;
|
|||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.security.Principal;
|
||||
import java.util.Collections;
|
||||
|
||||
import javax.security.auth.Subject;
|
||||
import javax.security.auth.login.AppConfigurationEntry;
|
||||
import javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag;
|
||||
import javax.security.auth.login.Configuration;
|
||||
|
||||
import org.eclipse.jetty.security.DefaultIdentityService;
|
||||
import org.eclipse.jetty.server.Request;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
|
@ -35,6 +41,19 @@ import org.junit.Test;
|
|||
*/
|
||||
public class JAASLoginServiceTest
|
||||
{
|
||||
public static class TestConfiguration extends Configuration
|
||||
{
|
||||
AppConfigurationEntry _entry = new AppConfigurationEntry(TestLoginModule.class.getCanonicalName(), LoginModuleControlFlag.REQUIRED, Collections.emptyMap());
|
||||
|
||||
@Override
|
||||
public AppConfigurationEntry[] getAppConfigurationEntry(String name)
|
||||
{
|
||||
return new AppConfigurationEntry[] {_entry};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
interface SomeRole
|
||||
{
|
||||
|
||||
|
@ -79,7 +98,24 @@ public class JAASLoginServiceTest
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testServletRequestCallback () throws Exception
|
||||
{
|
||||
//Test with the DefaultCallbackHandler
|
||||
JAASLoginService ls = new JAASLoginService("foo");
|
||||
ls.setCallbackHandlerClass("org.eclipse.jetty.jaas.callback.DefaultCallbackHandler");
|
||||
ls.setIdentityService(new DefaultIdentityService());
|
||||
ls.setConfiguration(new TestConfiguration());
|
||||
Request request = new Request(null, null);
|
||||
ls.login("aaardvaark", "aaa", request);
|
||||
|
||||
//Test with the fallback CallbackHandler
|
||||
ls = new JAASLoginService("foo");
|
||||
ls.setIdentityService(new DefaultIdentityService());
|
||||
ls.setConfiguration(new TestConfiguration());
|
||||
ls.login("aaardvaark", "aaa", request);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoginServiceRoles () throws Exception
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2018 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.jaas;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import javax.security.auth.callback.Callback;
|
||||
import javax.security.auth.login.LoginException;
|
||||
|
||||
import org.eclipse.jetty.jaas.callback.ServletRequestCallback;
|
||||
import org.eclipse.jetty.jaas.spi.AbstractLoginModule;
|
||||
import org.eclipse.jetty.jaas.spi.UserInfo;
|
||||
import org.eclipse.jetty.util.ArrayUtil;
|
||||
import org.eclipse.jetty.util.security.Password;
|
||||
|
||||
|
||||
public class TestLoginModule extends AbstractLoginModule
|
||||
{
|
||||
public ServletRequestCallback _callback = new ServletRequestCallback();
|
||||
|
||||
@Override
|
||||
public UserInfo getUserInfo(String username) throws Exception
|
||||
{
|
||||
return new UserInfo(username, new Password("aaa"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Callback[] configureCallbacks()
|
||||
{
|
||||
return ArrayUtil.addToArray(super.configureCallbacks(), _callback, Callback.class);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean login() throws LoginException
|
||||
{
|
||||
boolean result = super.login();
|
||||
assertNotNull(_callback.getRequest());
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue