ASF Bugzilla – Attachment 32567 Details for
Bug 57708
[Patch] Authentication by reverse proxy, authorization by Tomcat
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch for tomcat v7.0.x
tomcat-authorization7.patch (text/plain), 15.34 KB, created by
Graham Leggett
on 2015-03-14 23:00:43 UTC
(
hide
)
Description:
Patch for tomcat v7.0.x
Filename:
MIME Type:
Creator:
Graham Leggett
Created:
2015-03-14 23:00:43 UTC
Size:
15.34 KB
patch
obsolete
>Index: java/org/apache/catalina/Realm.java >=================================================================== >--- java/org/apache/catalina/Realm.java (revision 1666658) >+++ java/org/apache/catalina/Realm.java (working copy) >@@ -76,6 +76,15 @@ > > > /** >+ * 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>. > * >Index: java/org/apache/catalina/authenticator/BasicAuthenticator.java >=================================================================== >--- java/org/apache/catalina/authenticator/BasicAuthenticator.java (revision 1666658) >+++ java/org/apache/catalina/authenticator/BasicAuthenticator.java (working copy) >@@ -120,6 +120,21 @@ > return true; > } > >+ // If we are preauthenticated, run the authorization >+ String remoteUser = (String) >+ request.getCoyoteRequest().getAttribute(Constants.REQ_REMOTE_USER_NOTE); >+ if (remoteUser != null) { >+ if (log.isDebugEnabled()) >+ log.debug("Already authenticated '" + remoteUser + "', authorizing"); >+ principal = context.getRealm().authenticate(remoteUser); >+ if (principal != null) { >+ register(request, response, principal, >+ HttpServletRequest.BASIC_AUTH, remoteUser, null); >+ return (true); >+ } >+ return (false); >+ } >+ > // Validate any credentials already included with this request > String username = null; > String password = null; >Index: java/org/apache/catalina/authenticator/Constants.java >=================================================================== >--- java/org/apache/catalina/authenticator/Constants.java (revision 1666658) >+++ java/org/apache/catalina/authenticator/Constants.java (working copy) >@@ -85,6 +85,12 @@ > public static final String REQ_SSOID_NOTE = > "org.apache.catalina.request.SSOID"; > >+ /** >+ * The notes key to track the principal name when the user is >+ * pre-authenticated, but where tomcat must perform authorization. >+ */ >+ public static final String REQ_REMOTE_USER_NOTE = >+ "org.apache.catalina.request.REMOTE_USER"; > > // ---------------------------------------------------------- Session Notes > >Index: java/org/apache/catalina/authenticator/DigestAuthenticator.java >=================================================================== >--- java/org/apache/catalina/authenticator/DigestAuthenticator.java (revision 1666658) >+++ java/org/apache/catalina/authenticator/DigestAuthenticator.java (working copy) >@@ -291,6 +291,21 @@ > } > */ > >+ // If we are preauthenticated, run the authorization >+ String remoteUser = (String) >+ request.getCoyoteRequest().getAttribute(Constants.REQ_REMOTE_USER_NOTE); >+ if (remoteUser != null) { >+ if (log.isDebugEnabled()) >+ log.debug("Already authenticated '" + remoteUser + "', authorizing"); >+ principal = context.getRealm().authenticate(remoteUser); >+ if (principal != null) { >+ register(request, response, principal, >+ HttpServletRequest.DIGEST_AUTH, remoteUser, null); >+ return (true); >+ } >+ return (false); >+ } >+ > // Validate any credentials already included with this request > String authorization = request.getHeader("authorization"); > DigestInfo digestInfo = new DigestInfo(getOpaque(), getNonceValidity(), >Index: java/org/apache/catalina/authenticator/FormAuthenticator.java >=================================================================== >--- java/org/apache/catalina/authenticator/FormAuthenticator.java (revision 1666658) >+++ java/org/apache/catalina/authenticator/FormAuthenticator.java (working copy) >@@ -184,6 +184,22 @@ > } > } > >+ // If we are preauthenticated, run the authorization >+ String remoteUser = (String) >+ request.getCoyoteRequest().getAttribute(Constants.REQ_REMOTE_USER_NOTE); >+ if (remoteUser != null) { >+ if (log.isDebugEnabled()) >+ log.debug("Already authenticated '" + remoteUser + "', authorizing"); >+ principal = context.getRealm().authenticate(remoteUser); >+ if (principal != null) { >+ session.setNote(Constants.FORM_PRINCIPAL_NOTE, principal); >+ register(request, response, principal, >+ HttpServletRequest.FORM_AUTH, remoteUser, null); >+ return (true); >+ } >+ return (false); >+ } >+ > // Have we authenticated this user before but have caching disabled? > if (!cache) { > session = request.getSessionInternal(true); >Index: java/org/apache/catalina/authenticator/SSLAuthenticator.java >=================================================================== >--- java/org/apache/catalina/authenticator/SSLAuthenticator.java (revision 1666658) >+++ java/org/apache/catalina/authenticator/SSLAuthenticator.java (working copy) >@@ -98,6 +98,21 @@ > return (true); > } > >+ // If we are preauthenticated, run the authorization >+ String remoteUser = (String) >+ request.getCoyoteRequest().getAttribute(Constants.REQ_REMOTE_USER_NOTE); >+ if (remoteUser != null) { >+ if (containerLog.isDebugEnabled()) >+ containerLog.debug("Already authenticated '" + remoteUser + "', authorizing"); >+ principal = context.getRealm().authenticate(remoteUser); >+ if (principal != null) { >+ register(request, response, principal, >+ HttpServletRequest.CLIENT_CERT_AUTH, remoteUser, null); >+ return (true); >+ } >+ return (false); >+ } >+ > // NOTE: We don't try to reauthenticate using any existing SSO session, > // because that will only work if the original authentication was > // BASIC or FORM, which are less secure than the CLIENT_CERT auth-type >Index: java/org/apache/catalina/authenticator/SpnegoAuthenticator.java >=================================================================== >--- java/org/apache/catalina/authenticator/SpnegoAuthenticator.java (revision 1666658) >+++ java/org/apache/catalina/authenticator/SpnegoAuthenticator.java (working copy) >@@ -167,6 +167,21 @@ > } > } > >+ // If we are preauthenticated, run the authorization >+ String remoteUser = (String) >+ request.getCoyoteRequest().getAttribute(Constants.REQ_REMOTE_USER_NOTE); >+ if (remoteUser != null) { >+ if (log.isDebugEnabled()) >+ log.debug("Already authenticated '" + remoteUser + "', authorizing"); >+ principal = context.getRealm().authenticate(remoteUser); >+ if (principal != null) { >+ register(request, response, principal, >+ Constants.SPNEGO_METHOD, remoteUser, null); >+ return (true); >+ } >+ return (false); >+ } >+ > MessageBytes authorization = > request.getCoyoteRequest().getMimeHeaders() > .getValue("authorization"); >Index: java/org/apache/catalina/realm/RealmBase.java >=================================================================== >--- java/org/apache/catalina/realm/RealmBase.java (revision 1666658) >+++ java/org/apache/catalina/realm/RealmBase.java (working copy) >@@ -347,6 +347,28 @@ > > > /** >+ * 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>. > * >Index: java/org/apache/coyote/ajp/AbstractAjpProcessor.java >=================================================================== >--- java/org/apache/coyote/ajp/AbstractAjpProcessor.java (revision 1666658) >+++ java/org/apache/coyote/ajp/AbstractAjpProcessor.java (working copy) >@@ -277,6 +277,16 @@ > > > /** >+ * Use Tomcat authorization ? >+ */ >+ protected boolean tomcatAuthorization = false; >+ public boolean getTomcatAuthorization() { return tomcatAuthorization; } >+ public void setTomcatAuthorization(boolean tomcatAuthorization) { >+ this.tomcatAuthorization = tomcatAuthorization; >+ } >+ >+ >+ /** > * Required secret. > */ > protected String requiredSecret = null; >@@ -828,11 +838,17 @@ > break; > > case Constants.SC_A_REMOTE_USER : >- if (tomcatAuthentication) { >+ if (tomcatAuthorization) { >+ requestHeaderMessage.getBytes(tmpMB); >+ request.setAttribute( >+ org.apache.catalina.authenticator.Constants.REQ_REMOTE_USER_NOTE, >+ tmpMB.toString()); >+ } >+ else if (tomcatAuthentication) { > // ignore server > requestHeaderMessage.getBytes(tmpMB); > } else { >- requestHeaderMessage.getBytes(request.getRemoteUser()); >+ requestHeaderMessage.getBytes(request.getRemoteUser()); > } > break; > >Index: java/org/apache/coyote/ajp/AbstractAjpProtocol.java >=================================================================== >--- java/org/apache/coyote/ajp/AbstractAjpProtocol.java (revision 1666658) >+++ java/org/apache/coyote/ajp/AbstractAjpProtocol.java (working copy) >@@ -52,6 +52,13 @@ > } > > >+ protected boolean tomcatAuthorization = false; >+ public boolean getTomcatAuthorization() { return tomcatAuthorization; } >+ public void setTomcatAuthorization(boolean tomcatAuthorization) { >+ this.tomcatAuthorization = tomcatAuthorization; >+ } >+ >+ > /** > * Required secret. > */ >Index: java/org/apache/coyote/ajp/AjpAprProtocol.java >=================================================================== >--- java/org/apache/coyote/ajp/AjpAprProtocol.java (revision 1666658) >+++ java/org/apache/coyote/ajp/AjpAprProtocol.java (working copy) >@@ -146,6 +146,7 @@ > AjpAprProcessor processor = new AjpAprProcessor(proto.packetSize, (AprEndpoint)proto.endpoint); > processor.setAdapter(proto.adapter); > processor.setTomcatAuthentication(proto.tomcatAuthentication); >+ processor.setTomcatAuthorization(proto.tomcatAuthorization); > processor.setRequiredSecret(proto.requiredSecret); > processor.setKeepAliveTimeout(proto.getKeepAliveTimeout()); > processor.setClientCertProvider(proto.getClientCertProvider()); >Index: java/org/apache/coyote/ajp/AjpNioProtocol.java >=================================================================== >--- java/org/apache/coyote/ajp/AjpNioProtocol.java (revision 1666658) >+++ java/org/apache/coyote/ajp/AjpNioProtocol.java (working copy) >@@ -172,6 +172,7 @@ > AjpNioProcessor processor = new AjpNioProcessor(proto.packetSize, (NioEndpoint)proto.endpoint); > processor.setAdapter(proto.adapter); > processor.setTomcatAuthentication(proto.tomcatAuthentication); >+ processor.setTomcatAuthorization(proto.tomcatAuthorization); > processor.setRequiredSecret(proto.requiredSecret); > processor.setKeepAliveTimeout(proto.getKeepAliveTimeout()); > processor.setClientCertProvider(proto.getClientCertProvider()); >Index: java/org/apache/coyote/ajp/AjpProtocol.java >=================================================================== >--- java/org/apache/coyote/ajp/AjpProtocol.java (revision 1666658) >+++ java/org/apache/coyote/ajp/AjpProtocol.java (working copy) >@@ -134,6 +134,7 @@ > AjpProcessor processor = new AjpProcessor(proto.packetSize, (JIoEndpoint)proto.endpoint); > processor.setAdapter(proto.adapter); > processor.setTomcatAuthentication(proto.tomcatAuthentication); >+ processor.setTomcatAuthorization(proto.tomcatAuthorization); > processor.setRequiredSecret(proto.requiredSecret); > processor.setKeepAliveTimeout(proto.getKeepAliveTimeout()); > processor.setClientCertProvider(proto.getClientCertProvider()); >Index: webapps/docs/config/ajp.xml >=================================================================== >--- webapps/docs/config/ajp.xml (revision 1666658) >+++ webapps/docs/config/ajp.xml (working copy) >@@ -432,9 +432,18 @@ > <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> >+ 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. Authorization will then be performed by Tomcat as normal. >+ The default value is <code>false</code>.</p> >+ </attribute> >+ > </attributes> > > </subsection> >Index: webapps/docs/security-howto.xml >=================================================================== >--- webapps/docs/security-howto.xml (revision 1666658) >+++ webapps/docs/security-howto.xml (working copy) >@@ -276,7 +276,8 @@ > the list of available ciphers. Secure environments will normally want to > configure a more limited set of ciphers.</p> > >- <p>The <strong>tomcatAuthentication</strong> attribute is used with the >+ <p>The <strong>tomcatAuthentication</strong> and >+ <strong>tomcatAuthorization</strong> attributes are 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> >Index: webapps/docs/windows-auth-howto.xml >=================================================================== >--- webapps/docs/windows-auth-howto.xml (revision 1666658) >+++ webapps/docs/windows-auth-howto.xml (working copy) >@@ -299,7 +299,9 @@ > <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 Windows to >+ authenticate, while Tomcat performs the authorization.</li> > </ol> > </subsection> >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 57708
: 32567 |
32568
|
32569