Author: markt Date: Wed Mar 18 13:31:00 2015 New Revision: 1667546 URL: http://svn.apache.org/r1667546 Log: Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=57708 Implement a new feature for AJP connectors - Tomcat Authorization If configured (it is disabled by default) Tomcat will take an authenticated user name from the AJP protocol and use the appropriate Realm for the request to authorize (i.e. add roles) to that user.
Modified: tomcat/trunk/java/org/apache/catalina/Realm.java tomcat/trunk/java/org/apache/catalina/authenticator/AuthenticatorBase.java tomcat/trunk/java/org/apache/catalina/authenticator/BasicAuthenticator.java tomcat/trunk/java/org/apache/catalina/authenticator/DigestAuthenticator.java tomcat/trunk/java/org/apache/catalina/authenticator/FormAuthenticator.java tomcat/trunk/java/org/apache/catalina/authenticator/LocalStrings.properties tomcat/trunk/java/org/apache/catalina/authenticator/NonLoginAuthenticator.java tomcat/trunk/java/org/apache/catalina/authenticator/SSLAuthenticator.java tomcat/trunk/java/org/apache/catalina/authenticator/SpnegoAuthenticator.java tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java tomcat/trunk/java/org/apache/catalina/connector/LocalStrings.properties tomcat/trunk/java/org/apache/catalina/realm/CombinedRealm.java tomcat/trunk/java/org/apache/catalina/realm/RealmBase.java tomcat/trunk/java/org/apache/coyote/Request.java tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProtocol.java tomcat/trunk/java/org/apache/coyote/ajp/AjpProcessor.java tomcat/trunk/webapps/docs/config/ajp.xml tomcat/trunk/webapps/docs/security-howto.xml tomcat/trunk/webapps/docs/windows-auth-howto.xml Modified: tomcat/trunk/java/org/apache/catalina/Realm.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/Realm.java?rev=1667546&r1=1667545&r2=1667546&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/Realm.java (original) +++ tomcat/trunk/java/org/apache/catalina/Realm.java Wed Mar 18 13:31:00 2015 @@ -76,6 +76,15 @@ public interface Realm { /** + * Return the Principal associated with the specified username, if there + * is one; otherwise return <code>null</code>. + * + * @param username Username of the Principal to look up + */ + public Principal authenticate(String username); + + + /** * Return the Principal associated with the specified username and * credentials, if there is one; otherwise return <code>null</code>. * Modified: tomcat/trunk/java/org/apache/catalina/authenticator/AuthenticatorBase.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/authenticator/AuthenticatorBase.java?rev=1667546&r1=1667545&r2=1667546&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/authenticator/AuthenticatorBase.java (original) +++ tomcat/trunk/java/org/apache/catalina/authenticator/AuthenticatorBase.java Wed Mar 18 13:31:00 2015 @@ -40,6 +40,7 @@ import org.apache.catalina.Valve; import org.apache.catalina.Wrapper; import org.apache.catalina.connector.Request; import org.apache.catalina.connector.Response; +import org.apache.catalina.realm.GenericPrincipal; import org.apache.catalina.util.SessionIdGeneratorBase; import org.apache.catalina.util.StandardSessionIdGenerator; import org.apache.catalina.valves.ValveBase; @@ -691,20 +692,22 @@ public abstract class AuthenticatorBase * authenticate the user without requiring further user interaction. * * @param request The current request + * @param response The current response * @param useSSO Should information available from SSO be used to attempt * to authenticate the current user? * * @return <code>true</code> if the user was authenticated via the cache, * otherwise <code>false</code> */ - protected boolean checkForCachedAuthentication(Request request, boolean useSSO) { + protected boolean checkForCachedAuthentication(Request request, + HttpServletResponse response, boolean useSSO) { // Has the user already been authenticated? Principal principal = request.getUserPrincipal(); String ssoId = (String) request.getNote(Constants.REQ_SSOID_NOTE); if (principal != null) { if (log.isDebugEnabled()) { - log.debug("Already authenticated '" + principal.getName() + "'"); + log.debug(sm.getString("authenticator.check.found", principal.getName())); } // Associate the session with any existing SSO session. Even if // useSSO is false, this will ensure coordinated session @@ -718,8 +721,7 @@ public abstract class AuthenticatorBase // Is there an SSO session against which we can try to reauthenticate? if (useSSO && ssoId != null) { if (log.isDebugEnabled()) { - log.debug("SSO Id " + ssoId + " set; attempting " + - "reauthentication"); + log.debug(sm.getString("authenticator.check.sso", ssoId)); } /* Try to reauthenticate using data cached by SSO. If this fails, either the original SSO logon was of DIGEST or SSL (which @@ -732,6 +734,31 @@ public abstract class AuthenticatorBase } } + // Has the Connector provided a pre-authenticated Principal that now + // needs to be authorized? + if (request.getCoyoteRequest().getRemoteUserNeedsAuthorization()) { + String username = request.getCoyoteRequest().getRemoteUser().toString(); + if (username != null) { + if (log.isDebugEnabled()) { + log.debug(sm.getString("authenticator.check.authorize", username)); + } + Principal authorized = context.getRealm().authenticate(username); + if (authorized == null) { + // Realm doesn't recognise user. Create a user with no roles + // from the authenticated user name + if (log.isDebugEnabled()) { + log.debug(sm.getString("authenticator.check.authorizeFail", username)); + } + authorized = new GenericPrincipal(username, null, null); + } + String authType = request.getAuthType(); + if (authType == null || authType.length() == 0) { + authType = getAuthMethod(); + } + register(request, response, authorized, authType, username, null); + return true; + } + } return false; } Modified: tomcat/trunk/java/org/apache/catalina/authenticator/BasicAuthenticator.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/authenticator/BasicAuthenticator.java?rev=1667546&r1=1667545&r2=1667546&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/authenticator/BasicAuthenticator.java (original) +++ tomcat/trunk/java/org/apache/catalina/authenticator/BasicAuthenticator.java Wed Mar 18 13:31:00 2015 @@ -63,7 +63,7 @@ public class BasicAuthenticator extends public boolean authenticate(Request request, HttpServletResponse response) throws IOException { - if (checkForCachedAuthentication(request, true)) { + if (checkForCachedAuthentication(request, response, true)) { return true; } Modified: tomcat/trunk/java/org/apache/catalina/authenticator/DigestAuthenticator.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/authenticator/DigestAuthenticator.java?rev=1667546&r1=1667545&r2=1667546&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/authenticator/DigestAuthenticator.java (original) +++ tomcat/trunk/java/org/apache/catalina/authenticator/DigestAuthenticator.java Wed Mar 18 13:31:00 2015 @@ -205,7 +205,7 @@ public class DigestAuthenticator extends // Change to true below to allow previous FORM or BASIC authentications // to authenticate users for this webapp // TODO make this a configurable attribute (in SingleSignOn??) - if (checkForCachedAuthentication(request, false)) { + if (checkForCachedAuthentication(request, response, false)) { return true; } Modified: tomcat/trunk/java/org/apache/catalina/authenticator/FormAuthenticator.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/authenticator/FormAuthenticator.java?rev=1667546&r1=1667545&r2=1667546&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/authenticator/FormAuthenticator.java (original) +++ tomcat/trunk/java/org/apache/catalina/authenticator/FormAuthenticator.java Wed Mar 18 13:31:00 2015 @@ -134,7 +134,7 @@ public class FormAuthenticator public boolean authenticate(Request request, HttpServletResponse response) throws IOException { - if (checkForCachedAuthentication(request, true)) { + if (checkForCachedAuthentication(request, response, true)) { return true; } Modified: tomcat/trunk/java/org/apache/catalina/authenticator/LocalStrings.properties URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/authenticator/LocalStrings.properties?rev=1667546&r1=1667545&r2=1667546&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/authenticator/LocalStrings.properties (original) +++ tomcat/trunk/java/org/apache/catalina/authenticator/LocalStrings.properties Wed Mar 18 13:31:00 2015 @@ -15,6 +15,10 @@ authenticator.certificates=No client certificate chain in this request authenticator.changeSessionId=Session ID changed on authentication from [{0}] to [{1}] +authenticator.check.authorize=Authorizing connector provided user [{0}] via Tomcat Realm +authenticator.check.authorizeFail=Realm did not recognise user [{0}]. Creating a Principal with that name and no roles. +authenticator.check.found=Already authenticated [{0}] +authenticator.check.sso=Not authenticated but SSO session ID [{0}] found. Attempting re-authentication. authenticator.formlogin=Invalid direct reference to form login page authenticator.loginFail=Login failed authenticator.manager=Exception initializing trust managers @@ -23,6 +27,7 @@ authenticator.notContext=Configuration e authenticator.requestBodyTooBig=The request body was too large to be cached during the authentication process authenticator.sessionExpired=The time allowed for the login process has been exceeded. If you wish to continue you must either click back twice and re-click the link you requested or close and re-open your browser authenticator.unauthorized=Cannot authenticate with the provided credentials + digestAuthenticator.cacheRemove=A valid entry has been removed from client nonce cache to make room for new entries. A replay attack is now possible. To prevent the possibility of replay attacks, reduce nonceValidity or increase cnonceCacheSize. Further warnings of this type will be suppressed for 5 minutes. formAuthenticator.forwardErrorFail=Unexpected error forwarding to error page Modified: tomcat/trunk/java/org/apache/catalina/authenticator/NonLoginAuthenticator.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/authenticator/NonLoginAuthenticator.java?rev=1667546&r1=1667545&r2=1667546&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/authenticator/NonLoginAuthenticator.java (original) +++ tomcat/trunk/java/org/apache/catalina/authenticator/NonLoginAuthenticator.java Wed Mar 18 13:31:00 2015 @@ -79,7 +79,7 @@ public final class NonLoginAuthenticator // Don't try and use SSO to authenticate since there is no auth // configured for this web application - if (checkForCachedAuthentication(request, true)) { + if (checkForCachedAuthentication(request, response, true)) { return true; } Modified: tomcat/trunk/java/org/apache/catalina/authenticator/SSLAuthenticator.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/authenticator/SSLAuthenticator.java?rev=1667546&r1=1667545&r2=1667546&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/authenticator/SSLAuthenticator.java (original) +++ tomcat/trunk/java/org/apache/catalina/authenticator/SSLAuthenticator.java Wed Mar 18 13:31:00 2015 @@ -57,7 +57,7 @@ public class SSLAuthenticator extends Au // Change to true below to allow previous FORM or BASIC authentications // to authenticate users for this webapp // TODO make this a configurable attribute (in SingleSignOn??) - if (checkForCachedAuthentication(request, false)) { + if (checkForCachedAuthentication(request, response, false)) { return true; } Modified: tomcat/trunk/java/org/apache/catalina/authenticator/SpnegoAuthenticator.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/authenticator/SpnegoAuthenticator.java?rev=1667546&r1=1667545&r2=1667546&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/authenticator/SpnegoAuthenticator.java (original) +++ tomcat/trunk/java/org/apache/catalina/authenticator/SpnegoAuthenticator.java Wed Mar 18 13:31:00 2015 @@ -128,7 +128,7 @@ public class SpnegoAuthenticator extends public boolean authenticate(Request request, HttpServletResponse response) throws IOException { - if (checkForCachedAuthentication(request, true)) { + if (checkForCachedAuthentication(request, response, true)) { return true; } Modified: tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java?rev=1667546&r1=1667545&r2=1667546&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java (original) +++ tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java Wed Mar 18 13:31:00 2015 @@ -29,9 +29,11 @@ import javax.servlet.SessionTrackingMode import javax.servlet.WriteListener; import javax.servlet.http.HttpServletResponse; +import org.apache.catalina.Authenticator; import org.apache.catalina.Context; import org.apache.catalina.Host; import org.apache.catalina.Wrapper; +import org.apache.catalina.authenticator.AuthenticatorBase; import org.apache.catalina.core.AsyncContextImpl; import org.apache.catalina.util.ServerInfo; import org.apache.catalina.util.SessionConfig; @@ -841,17 +843,44 @@ public class CoyoteAdapter implements Ad return false; } - doConnectorAuthentication(req, request); + doConnectorAuthenticationAuthorization(req, request); return true; } - private void doConnectorAuthentication(org.apache.coyote.Request req, Request request) { + private void doConnectorAuthenticationAuthorization(org.apache.coyote.Request req, Request request) { // Set the remote principal - String principal = req.getRemoteUser().toString(); - if (principal != null) { - request.setUserPrincipal(new CoyotePrincipal(principal)); + String username = req.getRemoteUser().toString(); + if (username != null) { + if (log.isDebugEnabled()) { + log.debug(sm.getString("coyoteAdapter.authenticate", username)); + } + if (req.getRemoteUserNeedsAuthorization()) { + Authenticator authenticator = request.getContext().getAuthenticator(); + if (authenticator == null) { + // No security constraints configured for the application so + // no need to authorize the user. Use the CoyotePrincipal to + // provide the authenticated user. + request.setUserPrincipal(new CoyotePrincipal(username)); + } else if (!(authenticator instanceof AuthenticatorBase)) { + if (log.isDebugEnabled()) { + log.debug(sm.getString("coyoteAdapter.authorize", username)); + } + // Custom authenticator that may not trigger authorization. + // Do the authorization here to make sure it is done. + request.setUserPrincipal( + request.getContext().getRealm().authenticate(username)); + } + // If the Authenticator is an instance of AuthenticatorBase then + // it will check req.getRemoteUserNeedsAuthorization() and + // trigger authorization as necessary. It will also cache the + // result preventing excessive calls to the Realm. + } else { + // The connector isn't configured for authorization. Create a + // user without any roles using the supplied user name. + request.setUserPrincipal(new CoyotePrincipal(username)); + } } // Set the authorization type Modified: tomcat/trunk/java/org/apache/catalina/connector/LocalStrings.properties URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/LocalStrings.properties?rev=1667546&r1=1667545&r2=1667546&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/connector/LocalStrings.properties (original) +++ tomcat/trunk/java/org/apache/catalina/connector/LocalStrings.properties Wed Mar 18 13:31:00 2015 @@ -14,6 +14,8 @@ # limitations under the License. coyoteAdapter.accesslogFail=Exception while attempting to add an entry to the access log coyoteAdapter.asyncDispatch=Exception while processing an asynchronous request +coyoteAdapter.authenticate=Authenticated user [{0}] provided by connector +coyoteAdapter.authorize=Authorizing user [{0}] using Tomcat's Realm coyoteAdapter.checkRecycled.request=Encountered a non-recycled request and recycled it forcedly. coyoteAdapter.checkRecycled.response=Encountered a non-recycled response and recycled it forcedly. coyoteAdapter.debug=The variable [{0}] has value [{1}] Modified: tomcat/trunk/java/org/apache/catalina/realm/CombinedRealm.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/realm/CombinedRealm.java?rev=1667546&r1=1667545&r2=1667546&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/realm/CombinedRealm.java (original) +++ tomcat/trunk/java/org/apache/catalina/realm/CombinedRealm.java Wed Mar 18 13:31:00 2015 @@ -137,6 +137,41 @@ public class CombinedRealm extends Realm /** + * Return the Principal associated with the specified user name otherwise + * return <code>null</code>. + * + * @param username User name of the Principal to look up + */ + @Override + public Principal authenticate(String username) { + Principal authenticatedUser = null; + + for (Realm realm : realms) { + if (log.isDebugEnabled()) { + log.debug(sm.getString("combinedRealm.authStart", username, + realm.getClass().getName())); + } + + authenticatedUser = realm.authenticate(username); + + if (authenticatedUser == null) { + if (log.isDebugEnabled()) { + log.debug(sm.getString("combinedRealm.authFail", username, + realm.getClass().getName())); + } + } else { + if (log.isDebugEnabled()) { + log.debug(sm.getString("combinedRealm.authSuccess", + username, realm.getClass().getName())); + } + break; + } + } + return authenticatedUser; + } + + + /** * Return the Principal associated with the specified username and * credentials, if there is one; otherwise return <code>null</code>. * Modified: tomcat/trunk/java/org/apache/catalina/realm/RealmBase.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/realm/RealmBase.java?rev=1667546&r1=1667545&r2=1667546&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/realm/RealmBase.java (original) +++ tomcat/trunk/java/org/apache/catalina/realm/RealmBase.java Wed Mar 18 13:31:00 2015 @@ -416,6 +416,27 @@ public abstract class RealmBase extends /** + * Return the Principal associated with the specified username, if there + * is one; otherwise return <code>null</code>. + * + * @param username Username of the Principal to look up + */ + @Override + public Principal authenticate(String username) { + + if (username == null) { + return null; + } + + if (containerLog.isTraceEnabled()) { + containerLog.trace(sm.getString("realmBase.authenticateSuccess", username)); + } + + return getPrincipal(username); + } + + + /** * Return the Principal associated with the specified username and * credentials, if there is one; otherwise return <code>null</code>. * Modified: tomcat/trunk/java/org/apache/coyote/Request.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/Request.java?rev=1667546&r1=1667545&r2=1667546&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/Request.java (original) +++ tomcat/trunk/java/org/apache/coyote/Request.java Wed Mar 18 13:31:00 2015 @@ -127,9 +127,10 @@ public final class Request { private final ServerCookies serverCookies = new ServerCookies(INITIAL_COOKIE_SIZE); private final Parameters parameters = new Parameters(); - private final MessageBytes remoteUser=MessageBytes.newInstance(); - private final MessageBytes authType=MessageBytes.newInstance(); - private final HashMap<String,Object> attributes=new HashMap<>(); + private final MessageBytes remoteUser = MessageBytes.newInstance(); + private boolean remoteUserNeedsAuthorization = false; + private final MessageBytes authType = MessageBytes.newInstance(); + private final HashMap<String,Object> attributes = new HashMap<>(); private Response response; private ActionHook hook; @@ -415,6 +416,14 @@ public final class Request { return remoteUser; } + public boolean getRemoteUserNeedsAuthorization() { + return remoteUserNeedsAuthorization; + } + + public void setRemoteUserNeedsAuthorization(boolean remoteUserNeedsAuthorization) { + this.remoteUserNeedsAuthorization = remoteUserNeedsAuthorization; + } + public MessageBytes getAuthType() { return authType; } @@ -542,6 +551,7 @@ public final class Request { instanceId.recycle(); remoteUser.recycle(); + remoteUserNeedsAuthorization = false; authType.recycle(); attributes.clear(); Modified: tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProtocol.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProtocol.java?rev=1667546&r1=1667545&r2=1667546&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProtocol.java (original) +++ tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProtocol.java Wed Mar 18 13:31:00 2015 @@ -71,7 +71,7 @@ public abstract class AbstractAjpProtoco // ------------------------------------------ managed in the ProtocolHandler /** - * Should authentication be done in the native webserver layer, + * Should authentication be done in the native web server layer, * or in the Servlet container ? */ private boolean tomcatAuthentication = true; @@ -82,6 +82,17 @@ public abstract class AbstractAjpProtoco /** + * Should authentication be done in the native web server layer and + * authorization in the Servlet container? + */ + private boolean tomcatAuthorization = false; + public boolean getTomcatAuthorization() { return tomcatAuthorization; } + public void setTomcatAuthorization(boolean tomcatAuthorization) { + this.tomcatAuthorization = tomcatAuthorization; + } + + + /** * Required secret. */ private String requiredSecret = null; @@ -106,6 +117,7 @@ public abstract class AbstractAjpProtoco protected void configureProcessor(AjpProcessor processor) { processor.setAdapter(getAdapter()); processor.setTomcatAuthentication(getTomcatAuthentication()); + processor.setTomcatAuthorization(getTomcatAuthorization()); processor.setRequiredSecret(requiredSecret); processor.setKeepAliveTimeout(getKeepAliveTimeout()); processor.setClientCertProvider(getClientCertProvider()); Modified: tomcat/trunk/java/org/apache/coyote/ajp/AjpProcessor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/ajp/AjpProcessor.java?rev=1667546&r1=1667545&r2=1667546&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/ajp/AjpProcessor.java (original) +++ tomcat/trunk/java/org/apache/coyote/ajp/AjpProcessor.java Wed Mar 18 13:31:00 2015 @@ -303,6 +303,16 @@ public class AjpProcessor extends Abstra /** + * Use Tomcat authorization ? + */ + private boolean tomcatAuthorization = false; + public boolean getTomcatAuthorization() { return tomcatAuthorization; } + public void setTomcatAuthorization(boolean tomcatAuthorization) { + this.tomcatAuthorization = tomcatAuthorization; + } + + + /** * Required secret. */ private String requiredSecret = null; @@ -1162,11 +1172,13 @@ public class AjpProcessor extends Abstra break; case Constants.SC_A_REMOTE_USER : - if (tomcatAuthentication) { - // ignore server - requestHeaderMessage.getBytes(tmpMB); - } else { + if (tomcatAuthorization || !tomcatAuthentication) { + // Implies tomcatAuthentication == false requestHeaderMessage.getBytes(request.getRemoteUser()); + request.setRemoteUserNeedsAuthorization(tomcatAuthorization); + } else { + // Ignore user information from reverse proxy + requestHeaderMessage.getBytes(tmpMB); } break; Modified: tomcat/trunk/webapps/docs/config/ajp.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/ajp.xml?rev=1667546&r1=1667545&r2=1667546&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/config/ajp.xml (original) +++ tomcat/trunk/webapps/docs/config/ajp.xml Wed Mar 18 13:31:00 2015 @@ -429,8 +429,22 @@ <attribute name="tomcatAuthentication" required="false"> <p>If set to <code>true</code>, the authentication will be done in Tomcat. Otherwise, the authenticated principal will be propagated from the native - webserver and used for authorization in Tomcat. - The default value is <code>true</code>.</p> + webserver and used for authorization in Tomcat. Note that this principal + will have no roles associated with it. + The default value is <code>true</code>. If + <code>tomcatAuthorization</code> is set to <code>true</code> this + attribute has no effect.</p> + </attribute> + + <attribute name="tomcatAuthorization" required="false"> + <p>If set to <code>true</code>, the authenticated principal will be + propagated from the native webserver and considered already authenticated + in Tomcat. If the web application has one or more security constriants, + authorization will then be performed by Tomcat and roles asisgned to the + authenticated principal. If the appropriate Tomcat Realm for the request + does not recognise the provided user name, a Principal will be still be + created but it will have no roles. The default value is + <code>false</code>.</p> </attribute> </attributes> Modified: tomcat/trunk/webapps/docs/security-howto.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/security-howto.xml?rev=1667546&r1=1667545&r2=1667546&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/security-howto.xml (original) +++ tomcat/trunk/webapps/docs/security-howto.xml Wed Mar 18 13:31:00 2015 @@ -287,10 +287,12 @@ rel="nofollow">Qualys SSL/TLS test</a> is a useful tool for configuring these settings.</p> - <p>The <strong>tomcatAuthentication</strong> attribute is used with the - AJP connectors to determine if Tomcat should authenticate the user or if - authentication can be delegated to the reverse proxy that will then pass - the authenticated username to Tomcat as part of the AJP protocol.</p> + <p>The <strong>tomcatAuthentication</strong> and + <strong>tomcatAuthorization</strong> attributes are used with the + AJP connectors to determine if Tomcat should handle all authenication and + authorisation or if authentication should be delegated to the reverse + proxy (the authenticated user name is passed to Tomcat as part of the AJP + protocol) with the option for Tomcat to still perform authorization.</p> <p>The <strong>allowUnsafeLegacyRenegotiation</strong> attribute provides a workaround for Modified: tomcat/trunk/webapps/docs/windows-auth-howto.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/windows-auth-howto.xml?rev=1667546&r1=1667545&r2=1667546&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/windows-auth-howto.xml (original) +++ tomcat/trunk/webapps/docs/windows-auth-howto.xml Wed Mar 18 13:31:00 2015 @@ -301,7 +301,9 @@ com.sun.security.jgss.krb5.accept { <li>Configure IIS to use Windows authentication</li> <li>Configure Tomcat to use the authentication user information from IIS by setting the tomcatAuthentication attribute on the <a href="config/ajp.html"> - AJP connector</a> to <code>false</code>.</li> + AJP connector</a> to <code>false</code>. Alternatively, set the + tomcatAuthorization attribute to <code>true</code> to allow IIS to + authenticate, while Tomcat performs the authorization.</li> </ol> </subsection> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org