Skip to content

Commit

Permalink
Add properties for the JASPIC modules, plus some cleanups (more prope…
Browse files Browse the repository at this point in the history
…rties will be needed). Patch from Fjodor Vershinin with some changes.

git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@1709787 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
rmaucher committed Oct 21, 2015
1 parent 3baec8e commit 634f7f5
Show file tree
Hide file tree
Showing 10 changed files with 82 additions and 57 deletions.
Expand Up @@ -17,6 +17,8 @@
package org.apache.catalina.authenticator.jaspic; package org.apache.catalina.authenticator.jaspic;


import java.io.IOException; import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;


Expand Down Expand Up @@ -49,8 +51,7 @@ public class JaspicAuthenticator extends AuthenticatorBase {


private Subject serviceSubject; private Subject serviceSubject;


@SuppressWarnings("rawtypes") private Map<String, String> authProperties = new HashMap<>();
private Map authProperties = null;


private JaspicCallbackHandler callbackHandler; private JaspicCallbackHandler callbackHandler;


Expand Down Expand Up @@ -157,4 +158,15 @@ private JaspicCallbackHandler getJaspicCallbackHandler() {
protected String getAuthMethod() { protected String getAuthMethod() {
return context.getLoginConfig().getAuthMethod(); return context.getLoginConfig().getAuthMethod();
} }


public void setProperty(String key, String value) {
this.authProperties.put(key, value);
}


public Map<String, String> getAuthProperties() {
return Collections.unmodifiableMap(authProperties);
}

} }
Expand Up @@ -46,16 +46,18 @@ public class TomcatAuthConfig implements ServerAuthConfig {
private Context context; private Context context;
private LoginConfig loginConfig; private LoginConfig loginConfig;
private Realm realm; private Realm realm;

private Map<String, String> properties;


public TomcatAuthConfig(String layer, String appContext, CallbackHandler callbackHandler, public TomcatAuthConfig(String layer, String appContext, CallbackHandler callbackHandler,
Context context) { Context context, Map<String, String> properties) throws AuthException {
this.messageLayer = layer; this.messageLayer = layer;
this.appContext = appContext; this.appContext = appContext;
this.handler = callbackHandler; this.handler = callbackHandler;
this.context = context; this.context = context;
this.properties = properties;
this.realm = context.getRealm(); this.realm = context.getRealm();
this.loginConfig = context.getLoginConfig(); this.loginConfig = context.getLoginConfig();
initializeAuthContext(properties);
} }




Expand Down Expand Up @@ -90,21 +92,31 @@ public boolean isProtected() {




@Override @Override
@SuppressWarnings("rawtypes") @SuppressWarnings({ "rawtypes", "unchecked" })
public synchronized ServerAuthContext getAuthContext(String authContextID, public synchronized ServerAuthContext getAuthContext(String authContextID,
Subject serviceSubject, Map properties) throws AuthException { Subject serviceSubject, Map properties) throws AuthException {
if (this.tomcatServerAuthContext == null) { if (this.tomcatServerAuthContext == null) {
this.tomcatServerAuthContext = new TomcatServerAuthContext(handler, getModule(), initializeAuthContext(properties);
getOptions());
} }
return tomcatServerAuthContext; return tomcatServerAuthContext;
} }




private Map<String, String> getOptions() { private void initializeAuthContext(Map<String, String> properties) throws AuthException {
Map<String, String> options = new HashMap<>(); TomcatAuthModule module = getModule();
options.put(TomcatAuthModule.REALM_NAME, getRealmName()); module.initialize(null, null, handler, getMergedProperties(properties));
return options; this.tomcatServerAuthContext = new TomcatServerAuthContext(module);
}


@SuppressWarnings({ "rawtypes", "unchecked" })
private Map<String, String> getMergedProperties(Map properties) {
Map<String, String> mergedProperties = new HashMap<>(this.properties);
mergedProperties.put(TomcatAuthModule.REALM_NAME, getRealmName());
if (properties != null) {
mergedProperties.putAll(properties);
}
return mergedProperties;
} }




Expand Down
Expand Up @@ -38,8 +38,9 @@ public class TomcatAuthConfigProvider implements AuthConfigProvider {
private Context context; private Context context;




public TomcatAuthConfigProvider(Context context) { public TomcatAuthConfigProvider(Context context, Map<String, String> properties) {
this.context = context; this.context = context;
this.providerProperties = properties;
} }




Expand All @@ -62,7 +63,7 @@ public ClientAuthConfig getClientAuthConfig(String layer, String appContext,
public synchronized ServerAuthConfig getServerAuthConfig(String layer, String appContext, public synchronized ServerAuthConfig getServerAuthConfig(String layer, String appContext,
CallbackHandler handler) throws AuthException { CallbackHandler handler) throws AuthException {
if (this.serverAuthConfig == null) { if (this.serverAuthConfig == null) {
this.serverAuthConfig = new TomcatAuthConfig(layer, appContext, handler, context); this.serverAuthConfig = new TomcatAuthConfig(layer, appContext, handler, context, providerProperties);
} }
return this.serverAuthConfig; return this.serverAuthConfig;
} }
Expand Down
Expand Up @@ -16,10 +16,7 @@
*/ */
package org.apache.catalina.authenticator.jaspic.provider; package org.apache.catalina.authenticator.jaspic.provider;


import java.util.Map;

import javax.security.auth.Subject; import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.message.AuthException; import javax.security.auth.message.AuthException;
import javax.security.auth.message.AuthStatus; import javax.security.auth.message.AuthStatus;
import javax.security.auth.message.MessageInfo; import javax.security.auth.message.MessageInfo;
Expand All @@ -39,10 +36,8 @@ public class TomcatServerAuthContext implements ServerAuthContext {
private ServerAuthModule module; private ServerAuthModule module;




public TomcatServerAuthContext(CallbackHandler handler, ServerAuthModule module, public TomcatServerAuthContext(ServerAuthModule module) {
Map<String, String> options) throws AuthException {
this.module = module; this.module = module;
this.module.initialize(null, null, handler, options);
} }




Expand Down
Expand Up @@ -70,8 +70,6 @@ public class FormAuthModule extends TomcatAuthModule {
private Realm realm; private Realm realm;
private LoginConfig loginConfig; private LoginConfig loginConfig;


private boolean changeSessionIdOnAuthenication = true;



public FormAuthModule(Context context) { public FormAuthModule(Context context) {
super(context); super(context);
Expand All @@ -80,10 +78,11 @@ public FormAuthModule(Context context) {
} }




@SuppressWarnings("rawtypes")
@Override @Override
public void initializeModule(MessagePolicy requestPolicy, MessagePolicy responsePolicy, public void initializeModule(MessagePolicy requestPolicy, MessagePolicy responsePolicy,
CallbackHandler handler, Map options) throws AuthException { CallbackHandler handler, Map<String, String> options) throws AuthException {
this.characterEncoding = options.get("characterEncoding");
this.landingPage = options.get("landingPage");
} }




Expand All @@ -106,7 +105,7 @@ private AuthStatus validate(MessageInfo messageInfo, Subject clientSubject) thro
Request request = (Request) messageInfo.getRequestMessage(); Request request = (Request) messageInfo.getRequestMessage();
HttpServletResponse response = (HttpServletResponse) messageInfo.getResponseMessage(); HttpServletResponse response = (HttpServletResponse) messageInfo.getResponseMessage();


if (!cachePrincipalsInSession && isUserAuthenicatedBefore(request)) { if (!cache && isUserAuthenticatedBefore(request)) {
return handleSavedCredentials(clientSubject, request, response); return handleSavedCredentials(clientSubject, request, response);
} }


Expand All @@ -118,13 +117,14 @@ private AuthStatus validate(MessageInfo messageInfo, Subject clientSubject) thro
} }


if (!isLoginActionRequest(request)) { if (!isLoginActionRequest(request)) {
return handleNoLoginAction(request, response); return handleRedirectToLoginPage(request, response);
} }


return handleLoginAction(request, response); return handleLoginFormAction(request, response);
} }




// TODO Extract common patterns in processing cached principal and cached credentials
private AuthStatus handleSavedCredentials(Subject clientSubject, Request request, private AuthStatus handleSavedCredentials(Subject clientSubject, Request request,
HttpServletResponse response) throws IOException, UnsupportedCallbackException { HttpServletResponse response) throws IOException, UnsupportedCallbackException {
Session session = request.getSessionInternal(true); Session session = request.getSessionInternal(true);
Expand Down Expand Up @@ -154,7 +154,7 @@ private AuthStatus handleSavedCredentials(Subject clientSubject, Request request
} }




private boolean isUserAuthenicatedBefore(Request request) { private boolean isUserAuthenticatedBefore(Request request) {
Session session = request.getSessionInternal(true); Session session = request.getSessionInternal(true);
String username = (String) session.getNote(Constants.SESS_USERNAME_NOTE); String username = (String) session.getNote(Constants.SESS_USERNAME_NOTE);
String password = (String) session.getNote(Constants.SESS_PASSWORD_NOTE); String password = (String) session.getNote(Constants.SESS_PASSWORD_NOTE);
Expand All @@ -174,7 +174,7 @@ private AuthStatus submitSavedRequest(Subject clientSubject, Request request,
// If we're caching principals we no longer need getPrincipal the // If we're caching principals we no longer need getPrincipal the
// username // username
// and password in the session, so remove them // and password in the session, so remove them
if (cachePrincipalsInSession) { if (cache) {
session.removeNote(Constants.SESS_USERNAME_NOTE); session.removeNote(Constants.SESS_USERNAME_NOTE);
session.removeNote(Constants.SESS_PASSWORD_NOTE); session.removeNote(Constants.SESS_PASSWORD_NOTE);
} }
Expand All @@ -201,7 +201,7 @@ private AuthStatus submitSavedRequest(Subject clientSubject, Request request,
* @return * @return
* @throws IOException * @throws IOException
*/ */
private AuthStatus handleNoLoginAction(Request request, HttpServletResponse response) private AuthStatus handleRedirectToLoginPage(Request request, HttpServletResponse response)
throws IOException { throws IOException {
Session session = request.getSessionInternal(true); Session session = request.getSessionInternal(true);
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
Expand Down Expand Up @@ -230,7 +230,7 @@ private AuthStatus handleNoLoginAction(Request request, HttpServletResponse resp
* @return * @return
* @throws IOException * @throws IOException
*/ */
private AuthStatus handleLoginAction(Request request, HttpServletResponse response) private AuthStatus handleLoginFormAction(Request request, HttpServletResponse response)
throws IOException { throws IOException {


request.getResponse().sendAcknowledgement(); request.getResponse().sendAcknowledgement();
Expand Down Expand Up @@ -374,7 +374,7 @@ protected void forwardToLoginPage(Request request, HttpServletResponse response)
return; return;
} }


if (getChangeSessionIdOnAuthentication()) { if (changeSessionIdOnAuthentication) {
Session session = request.getSessionInternal(false); Session session = request.getSessionInternal(false);
if (session != null) { if (session != null) {
Manager manager = request.getContext().getManager(); Manager manager = request.getContext().getManager();
Expand Down Expand Up @@ -406,11 +406,6 @@ protected void forwardToLoginPage(Request request, HttpServletResponse response)
} }




private boolean getChangeSessionIdOnAuthentication() {
return changeSessionIdOnAuthenication ;
}


/** /**
* Called to forward to the error page * Called to forward to the error page
* *
Expand Down
Expand Up @@ -57,7 +57,8 @@ public abstract class TomcatAuthModule implements ServerAuthModule {


protected Context context; protected Context context;


protected boolean cachePrincipalsInSession = true; protected boolean cache = true;
protected boolean changeSessionIdOnAuthentication = true;




public TomcatAuthModule(Context context) { public TomcatAuthModule(Context context) {
Expand All @@ -71,11 +72,13 @@ protected boolean isMandatory(MessageInfo messageInfo) {
} }




@SuppressWarnings("rawtypes") @SuppressWarnings({ "rawtypes", "unchecked" })
@Override @Override
public final void initialize(MessagePolicy requestPolicy, MessagePolicy responsePolicy, public final void initialize(MessagePolicy requestPolicy, MessagePolicy responsePolicy,
CallbackHandler handler, Map options) throws AuthException { CallbackHandler handler, Map options) throws AuthException {
this.handler = handler; this.handler = handler;
this.cache = (Boolean.parseBoolean((String) options.get("cache")));
this.changeSessionIdOnAuthentication = Boolean.parseBoolean((String) options.get("changeSessionIdOnAuthentication"));
String name = (String) options.get(REALM_NAME); String name = (String) options.get(REALM_NAME);
if (name != null) { if (name != null) {
this.realmName = name; this.realmName = name;
Expand All @@ -99,9 +102,8 @@ public String getRealmName() {
* @param options * @param options
* @throws AuthException * @throws AuthException
*/ */
@SuppressWarnings("rawtypes")
public abstract void initializeModule(MessagePolicy requestPolicy, public abstract void initializeModule(MessagePolicy requestPolicy,
MessagePolicy responsePolicy, CallbackHandler handler, Map options) MessagePolicy responsePolicy, CallbackHandler handler, Map<String, String> options)
throws AuthException; throws AuthException;




Expand Down
22 changes: 13 additions & 9 deletions java/org/apache/catalina/startup/ContextConfig.java
Expand Up @@ -395,8 +395,7 @@ protected void authenticatorConfig() {
if (authenticator == null) { if (authenticator == null) {
String authMethod = loginConfig.getAuthMethod(); String authMethod = loginConfig.getAuthMethod();
if (authMethod != null && authMethod.contains("JASPIC")) { if (authMethod != null && authMethod.contains("JASPIC")) {
//TODO temporary workaround, Jaspic should be enabled by default authenticator = new JaspicAuthenticator();
authenticator = configureDefaultJaspicAuthModules();
} }
} }


Expand All @@ -408,9 +407,7 @@ protected void authenticatorConfig() {
} }


// Identify the class name of the Valve we should configure // Identify the class name of the Valve we should configure
String authenticatorName = null; String authenticatorName = authenticators.getProperty(loginConfig.getAuthMethod());
authenticatorName =
authenticators.getProperty(loginConfig.getAuthMethod());
if (authenticatorName == null) { if (authenticatorName == null) {
log.error(sm.getString("contextConfig.authenticatorMissing", log.error(sm.getString("contextConfig.authenticatorMissing",
loginConfig.getAuthMethod())); loginConfig.getAuthMethod()));
Expand Down Expand Up @@ -448,14 +445,20 @@ protected void authenticatorConfig() {


/** /**
* Configure and register default JASPIC modules * Configure and register default JASPIC modules
* @return
*/ */
private JaspicAuthenticator configureDefaultJaspicAuthModules() { private void configureDefaultJaspicAuthModules() {
if (!(context.getAuthenticator() instanceof JaspicAuthenticator)) {
return;
}
// TODO currently we setup default provider if we have
// JaspicAuthenicator registred.
// we need to find a better way to decide, if we want embedded provider
// or not
JaspicAuthenticator authenticator = (JaspicAuthenticator) context.getAuthenticator();
AuthConfigFactory authConfigFactory = AuthConfigFactory.getFactory(); AuthConfigFactory authConfigFactory = AuthConfigFactory.getFactory();
TomcatAuthConfigProvider provider = new TomcatAuthConfigProvider(context); TomcatAuthConfigProvider provider = new TomcatAuthConfigProvider(context, authenticator.getAuthProperties());
authConfigFactory.registerConfigProvider(provider, JaspicAuthenticator.MESSAGE_LAYER, authConfigFactory.registerConfigProvider(provider, JaspicAuthenticator.MESSAGE_LAYER,
getJaspicAppContext(), "Tomcat Jaspic"); getJaspicAppContext(), "Tomcat Jaspic");
return new JaspicAuthenticator();
} }


private String getJaspicAppContext() { private String getJaspicAppContext() {
Expand Down Expand Up @@ -807,6 +810,7 @@ protected synchronized void configureStart() {
// Configure an authenticator if we need one // Configure an authenticator if we need one
if (ok) { if (ok) {
authenticatorConfig(); authenticatorConfig();
configureDefaultJaspicAuthModules();
} }


// Dump the contents of this pipeline if requested // Dump the contents of this pipeline if requested
Expand Down
Expand Up @@ -87,11 +87,12 @@ public void setUp() throws Exception {
lc.setRealmName(REALM); lc.setRealmName(REALM);
ctxt.setLoginConfig(lc); ctxt.setLoginConfig(lc);


JaspicAuthenticator authenticator = new JaspicAuthenticator();
ctxt.getPipeline().addValve(authenticator);
AuthConfigFactory authConfigFactory = AuthConfigFactory.getFactory(); AuthConfigFactory authConfigFactory = AuthConfigFactory.getFactory();
TomcatAuthConfigProvider provider = new TomcatAuthConfigProvider(ctxt); TomcatAuthConfigProvider provider = new TomcatAuthConfigProvider(ctxt, authenticator.getAuthProperties());
authConfigFactory.registerConfigProvider(provider, JaspicAuthenticator.MESSAGE_LAYER, null, authConfigFactory.registerConfigProvider(provider, JaspicAuthenticator.MESSAGE_LAYER, null,
"Tomcat Jaspic"); "Tomcat Jaspic");
ctxt.getPipeline().addValve(new JaspicAuthenticator());


tomcat.start(); tomcat.start();
} }
Expand Down
Expand Up @@ -299,11 +299,12 @@ public void setUp() throws Exception {
lc.setRealmName(REALM); lc.setRealmName(REALM);
ctxt.setLoginConfig(lc); ctxt.setLoginConfig(lc);


JaspicAuthenticator authenticator = new JaspicAuthenticator();
ctxt.getPipeline().addValve(authenticator);
AuthConfigFactory authConfigFactory = AuthConfigFactory.getFactory(); AuthConfigFactory authConfigFactory = AuthConfigFactory.getFactory();
TomcatAuthConfigProvider provider = new TomcatAuthConfigProvider(ctxt); TomcatAuthConfigProvider provider = new TomcatAuthConfigProvider(ctxt, authenticator.getAuthProperties());
authConfigFactory.registerConfigProvider(provider, JaspicAuthenticator.MESSAGE_LAYER, authConfigFactory.registerConfigProvider(provider, JaspicAuthenticator.MESSAGE_LAYER,
null, "Tomcat Jaspic"); null, "Tomcat Jaspic");
ctxt.getPipeline().addValve(new JaspicAuthenticator());
} }




Expand Down
Expand Up @@ -636,11 +636,12 @@ private FormAuthClient(boolean clientShouldUseCookies, boolean clientShouldUseHt
realm.addUserRole("tomcat", "tomcat"); realm.addUserRole("tomcat", "tomcat");
ctx.setRealm(realm); ctx.setRealm(realm);


JaspicAuthenticator jaspicAuthenticator = new JaspicAuthenticator();
ctx.getPipeline().addValve(jaspicAuthenticator);
AuthConfigFactory authConfigFactory = AuthConfigFactory.getFactory(); AuthConfigFactory authConfigFactory = AuthConfigFactory.getFactory();
TomcatAuthConfigProvider provider = new TomcatAuthConfigProvider(ctx); TomcatAuthConfigProvider provider = new TomcatAuthConfigProvider(ctx, jaspicAuthenticator.getAuthProperties());
authConfigFactory.registerConfigProvider(provider, JaspicAuthenticator.MESSAGE_LAYER, authConfigFactory.registerConfigProvider(provider, JaspicAuthenticator.MESSAGE_LAYER,
null, "Tomcat Jaspic"); null, "Tomcat Jaspic");
ctx.getPipeline().addValve(new JaspicAuthenticator());


tomcat.start(); tomcat.start();


Expand Down Expand Up @@ -704,11 +705,12 @@ private FormAuthClientSelectedMethods(boolean clientShouldUseCookies,
realm.addUserRole("tomcat", "tomcat"); realm.addUserRole("tomcat", "tomcat");
ctx.setRealm(realm); ctx.setRealm(realm);


JaspicAuthenticator authenticator = new JaspicAuthenticator();
ctx.getPipeline().addValve(authenticator);
AuthConfigFactory authConfigFactory = AuthConfigFactory.getFactory(); AuthConfigFactory authConfigFactory = AuthConfigFactory.getFactory();
TomcatAuthConfigProvider provider = new TomcatAuthConfigProvider(ctx); TomcatAuthConfigProvider provider = new TomcatAuthConfigProvider(ctx, authenticator.getAuthProperties());
authConfigFactory.registerConfigProvider(provider, JaspicAuthenticator.MESSAGE_LAYER, authConfigFactory.registerConfigProvider(provider, JaspicAuthenticator.MESSAGE_LAYER,
null, "Tomcat Jaspic"); null, "Tomcat Jaspic");
ctx.getPipeline().addValve(new JaspicAuthenticator());


tomcat.start(); tomcat.start();


Expand Down

0 comments on commit 634f7f5

Please sign in to comment.