View | Details | Raw Unified | Return to bug 57708
Collapse All | Expand All

(-)java/org/apache/catalina/Realm.java (+9 lines)
Lines 76-81 Link Here
76
76
77
77
78
    /**
78
    /**
79
     * Return the Principal associated with the specified username, if there
80
     * is one; otherwise return <code>null</code>.
81
     *
82
     * @param username Username of the Principal to look up
83
     */
84
    public Principal authenticate(String username);
85
86
87
    /**
79
     * Return the Principal associated with the specified username and
88
     * Return the Principal associated with the specified username and
80
     * credentials, if there is one; otherwise return <code>null</code>.
89
     * credentials, if there is one; otherwise return <code>null</code>.
81
     *
90
     *
(-)java/org/apache/catalina/authenticator/BasicAuthenticator.java (+15 lines)
Lines 120-125 Link Here
120
                return true;
120
                return true;
121
        }
121
        }
122
122
123
        // If we are preauthenticated, run the authorization
124
        String remoteUser = (String)
125
        		request.getCoyoteRequest().getAttribute(Constants.REQ_REMOTE_USER_NOTE);
126
        if (remoteUser != null) {
127
            if (log.isDebugEnabled())
128
                log.debug("Already authenticated '" + remoteUser + "', authorizing");
129
            principal = context.getRealm().authenticate(remoteUser);
130
            if (principal != null) {
131
                register(request, response, principal,
132
                        HttpServletRequest.BASIC_AUTH, remoteUser, null);
133
                return (true);
134
            }
135
            return (false);
136
        }
137
123
        // Validate any credentials already included with this request
138
        // Validate any credentials already included with this request
124
        String username = null;
139
        String username = null;
125
        String password = null;
140
        String password = null;
(-)java/org/apache/catalina/authenticator/Constants.java (+6 lines)
Lines 85-90 Link Here
85
    public static final String REQ_SSOID_NOTE =
85
    public static final String REQ_SSOID_NOTE =
86
      "org.apache.catalina.request.SSOID";
86
      "org.apache.catalina.request.SSOID";
87
87
88
    /**
89
     * The notes key to track the principal name when the user is
90
     * pre-authenticated, but where tomcat must perform authorization.
91
     */
92
    public static final String REQ_REMOTE_USER_NOTE =
93
      "org.apache.catalina.request.REMOTE_USER";
88
94
89
    // ---------------------------------------------------------- Session Notes
95
    // ---------------------------------------------------------- Session Notes
90
96
(-)java/org/apache/catalina/authenticator/DigestAuthenticator.java (+15 lines)
Lines 291-296 Link Here
291
        }
291
        }
292
        */
292
        */
293
293
294
        // If we are preauthenticated, run the authorization
295
        String remoteUser = (String)
296
        		request.getCoyoteRequest().getAttribute(Constants.REQ_REMOTE_USER_NOTE);
297
        if (remoteUser != null) {
298
            if (log.isDebugEnabled())
299
                log.debug("Already authenticated '" + remoteUser + "', authorizing");
300
            principal = context.getRealm().authenticate(remoteUser);
301
            if (principal != null) {
302
                register(request, response, principal,
303
                        HttpServletRequest.DIGEST_AUTH, remoteUser, null);
304
                return (true);
305
            }
306
            return (false);
307
        }
308
294
        // Validate any credentials already included with this request
309
        // Validate any credentials already included with this request
295
        String authorization = request.getHeader("authorization");
310
        String authorization = request.getHeader("authorization");
296
        DigestInfo digestInfo = new DigestInfo(getOpaque(), getNonceValidity(),
311
        DigestInfo digestInfo = new DigestInfo(getOpaque(), getNonceValidity(),
(-)java/org/apache/catalina/authenticator/FormAuthenticator.java (+16 lines)
Lines 184-189 Link Here
184
            }
184
            }
185
        }
185
        }
186
186
187
        // If we are preauthenticated, run the authorization
188
        String remoteUser = (String)
189
        		request.getCoyoteRequest().getAttribute(Constants.REQ_REMOTE_USER_NOTE);
190
        if (remoteUser != null) {
191
            if (log.isDebugEnabled())
192
                log.debug("Already authenticated '" + remoteUser + "', authorizing");
193
            principal = context.getRealm().authenticate(remoteUser);
194
            if (principal != null) {
195
                session.setNote(Constants.FORM_PRINCIPAL_NOTE, principal);
196
                register(request, response, principal,
197
                        HttpServletRequest.FORM_AUTH, remoteUser, null);
198
                return (true);
199
            }
200
            return (false);
201
        }
202
187
        // Have we authenticated this user before but have caching disabled?
203
        // Have we authenticated this user before but have caching disabled?
188
        if (!cache) {
204
        if (!cache) {
189
            session = request.getSessionInternal(true);
205
            session = request.getSessionInternal(true);
(-)java/org/apache/catalina/authenticator/SSLAuthenticator.java (+15 lines)
Lines 98-103 Link Here
98
            return (true);
98
            return (true);
99
        }
99
        }
100
100
101
        // If we are preauthenticated, run the authorization
102
        String remoteUser = (String)
103
        		request.getCoyoteRequest().getAttribute(Constants.REQ_REMOTE_USER_NOTE);
104
        if (remoteUser != null) {
105
            if (containerLog.isDebugEnabled())
106
            	containerLog.debug("Already authenticated '" + remoteUser + "', authorizing");
107
            principal = context.getRealm().authenticate(remoteUser);
108
            if (principal != null) {
109
                register(request, response, principal,
110
                        HttpServletRequest.CLIENT_CERT_AUTH, remoteUser, null);
111
                return (true);
112
            }
113
            return (false);
114
        }
115
101
        // NOTE: We don't try to reauthenticate using any existing SSO session,
116
        // NOTE: We don't try to reauthenticate using any existing SSO session,
102
        // because that will only work if the original authentication was
117
        // because that will only work if the original authentication was
103
        // BASIC or FORM, which are less secure than the CLIENT_CERT auth-type
118
        // BASIC or FORM, which are less secure than the CLIENT_CERT auth-type
(-)java/org/apache/catalina/authenticator/SpnegoAuthenticator.java (+15 lines)
Lines 167-172 Link Here
167
            }
167
            }
168
        }
168
        }
169
169
170
        // If we are preauthenticated, run the authorization
171
        String remoteUser = (String)
172
        		request.getCoyoteRequest().getAttribute(Constants.REQ_REMOTE_USER_NOTE);
173
        if (remoteUser != null) {
174
            if (log.isDebugEnabled())
175
                log.debug("Already authenticated '" + remoteUser + "', authorizing");
176
            principal = context.getRealm().authenticate(remoteUser);
177
            if (principal != null) {
178
                register(request, response, principal,
179
                		Constants.SPNEGO_METHOD, remoteUser, null);
180
                return (true);
181
            }
182
            return (false);
183
        }
184
170
        MessageBytes authorization = 
185
        MessageBytes authorization = 
171
            request.getCoyoteRequest().getMimeHeaders()
186
            request.getCoyoteRequest().getMimeHeaders()
172
            .getValue("authorization");
187
            .getValue("authorization");
(-)java/org/apache/catalina/realm/RealmBase.java (+22 lines)
Lines 347-352 Link Here
347
347
348
348
349
    /**
349
    /**
350
     * Return the Principal associated with the specified username, if there
351
     * is one; otherwise return <code>null</code>.
352
     *
353
     * @param username Username of the Principal to look up
354
     */
355
    @Override
356
    public Principal authenticate(String username) {
357
358
    	if (username == null) {
359
    		return null;
360
    	}
361
362
        if (containerLog.isTraceEnabled()) {
363
            containerLog.trace(sm.getString("realmBase.authenticateSuccess",
364
                                            username));
365
        }
366
367
        return getPrincipal(username);
368
    }
369
370
371
    /**
350
     * Return the Principal associated with the specified username and
372
     * Return the Principal associated with the specified username and
351
     * credentials, if there is one; otherwise return <code>null</code>.
373
     * credentials, if there is one; otherwise return <code>null</code>.
352
     *
374
     *
(-)java/org/apache/coyote/ajp/AbstractAjpProcessor.java (-2 / +18 lines)
Lines 277-282 Link Here
277
277
278
278
279
    /**
279
    /**
280
     * Use Tomcat authorization ?
281
     */
282
    protected boolean tomcatAuthorization = false;
283
    public boolean getTomcatAuthorization() { return tomcatAuthorization; }
284
    public void setTomcatAuthorization(boolean tomcatAuthorization) {
285
        this.tomcatAuthorization = tomcatAuthorization;
286
    }
287
288
289
    /**
280
     * Required secret.
290
     * Required secret.
281
     */
291
     */
282
    protected String requiredSecret = null;
292
    protected String requiredSecret = null;
Lines 828-838 Link Here
828
                break;
838
                break;
829
839
830
            case Constants.SC_A_REMOTE_USER :
840
            case Constants.SC_A_REMOTE_USER :
831
                if (tomcatAuthentication) {
841
            	if (tomcatAuthorization) {
842
                    requestHeaderMessage.getBytes(tmpMB);
843
            		request.setAttribute(
844
            				org.apache.catalina.authenticator.Constants.REQ_REMOTE_USER_NOTE,
845
            				tmpMB.toString());
846
            	}
847
            	else if (tomcatAuthentication) {
832
                    // ignore server
848
                    // ignore server
833
                    requestHeaderMessage.getBytes(tmpMB);
849
                    requestHeaderMessage.getBytes(tmpMB);
834
                } else {
850
                } else {
835
                    requestHeaderMessage.getBytes(request.getRemoteUser());
851
                	requestHeaderMessage.getBytes(request.getRemoteUser());
836
                }
852
                }
837
                break;
853
                break;
838
854
(-)java/org/apache/coyote/ajp/AbstractAjpProtocol.java (+7 lines)
Lines 52-57 Link Here
52
    }
52
    }
53
53
54
54
55
    protected boolean tomcatAuthorization = false;
56
    public boolean getTomcatAuthorization() { return tomcatAuthorization; }
57
    public void setTomcatAuthorization(boolean tomcatAuthorization) {
58
        this.tomcatAuthorization = tomcatAuthorization;
59
    }
60
61
55
    /**
62
    /**
56
     * Required secret.
63
     * Required secret.
57
     */
64
     */
(-)java/org/apache/coyote/ajp/AjpAprProtocol.java (+1 lines)
Lines 146-151 Link Here
146
            AjpAprProcessor processor = new AjpAprProcessor(proto.packetSize, (AprEndpoint)proto.endpoint);
146
            AjpAprProcessor processor = new AjpAprProcessor(proto.packetSize, (AprEndpoint)proto.endpoint);
147
            processor.setAdapter(proto.adapter);
147
            processor.setAdapter(proto.adapter);
148
            processor.setTomcatAuthentication(proto.tomcatAuthentication);
148
            processor.setTomcatAuthentication(proto.tomcatAuthentication);
149
            processor.setTomcatAuthorization(proto.tomcatAuthorization);
149
            processor.setRequiredSecret(proto.requiredSecret);
150
            processor.setRequiredSecret(proto.requiredSecret);
150
            processor.setKeepAliveTimeout(proto.getKeepAliveTimeout());
151
            processor.setKeepAliveTimeout(proto.getKeepAliveTimeout());
151
            processor.setClientCertProvider(proto.getClientCertProvider());
152
            processor.setClientCertProvider(proto.getClientCertProvider());
(-)java/org/apache/coyote/ajp/AjpNioProtocol.java (+1 lines)
Lines 172-177 Link Here
172
            AjpNioProcessor processor = new AjpNioProcessor(proto.packetSize, (NioEndpoint)proto.endpoint);
172
            AjpNioProcessor processor = new AjpNioProcessor(proto.packetSize, (NioEndpoint)proto.endpoint);
173
            processor.setAdapter(proto.adapter);
173
            processor.setAdapter(proto.adapter);
174
            processor.setTomcatAuthentication(proto.tomcatAuthentication);
174
            processor.setTomcatAuthentication(proto.tomcatAuthentication);
175
            processor.setTomcatAuthorization(proto.tomcatAuthorization);
175
            processor.setRequiredSecret(proto.requiredSecret);
176
            processor.setRequiredSecret(proto.requiredSecret);
176
            processor.setKeepAliveTimeout(proto.getKeepAliveTimeout());
177
            processor.setKeepAliveTimeout(proto.getKeepAliveTimeout());
177
            processor.setClientCertProvider(proto.getClientCertProvider());
178
            processor.setClientCertProvider(proto.getClientCertProvider());
(-)java/org/apache/coyote/ajp/AjpProtocol.java (+1 lines)
Lines 134-139 Link Here
134
            AjpProcessor processor = new AjpProcessor(proto.packetSize, (JIoEndpoint)proto.endpoint);
134
            AjpProcessor processor = new AjpProcessor(proto.packetSize, (JIoEndpoint)proto.endpoint);
135
            processor.setAdapter(proto.adapter);
135
            processor.setAdapter(proto.adapter);
136
            processor.setTomcatAuthentication(proto.tomcatAuthentication);
136
            processor.setTomcatAuthentication(proto.tomcatAuthentication);
137
            processor.setTomcatAuthorization(proto.tomcatAuthorization);
137
            processor.setRequiredSecret(proto.requiredSecret);
138
            processor.setRequiredSecret(proto.requiredSecret);
138
            processor.setKeepAliveTimeout(proto.getKeepAliveTimeout());
139
            processor.setKeepAliveTimeout(proto.getKeepAliveTimeout());
139
            processor.setClientCertProvider(proto.getClientCertProvider());
140
            processor.setClientCertProvider(proto.getClientCertProvider());
(-)webapps/docs/config/ajp.xml (-1 / +10 lines)
Lines 432-440 Link Here
432
      <p>If set to <code>true</code>, the authentication will be done in Tomcat.
432
      <p>If set to <code>true</code>, the authentication will be done in Tomcat.
433
      Otherwise, the authenticated principal will be propagated from the native
433
      Otherwise, the authenticated principal will be propagated from the native
434
      webserver and used for authorization in Tomcat.
434
      webserver and used for authorization in Tomcat.
435
      The default value is <code>true</code>.</p>
435
      The default value is <code>true</code>. If
436
      <code>tomcatAuthorization</code> is set to <code>true</code> this
437
      attribute has no effect.</p>
436
    </attribute>
438
    </attribute>
437
439
440
    <attribute name="tomcatAuthorization" required="false">
441
      <p>If set to <code>true</code>, the authenticated principal will be
442
      propagated from the native webserver and considered already authenticated
443
      in Tomcat. Authorization will then be performed by Tomcat as normal.
444
      The default value is <code>false</code>.</p>
445
    </attribute>
446
438
  </attributes>
447
  </attributes>
439
448
440
  </subsection>
449
  </subsection>
(-)webapps/docs/security-howto.xml (-1 / +2 lines)
Lines 276-282 Link Here
276
      the list of available ciphers. Secure environments will normally want to
276
      the list of available ciphers. Secure environments will normally want to
277
      configure a more limited set of ciphers.</p>
277
      configure a more limited set of ciphers.</p>
278
278
279
      <p>The <strong>tomcatAuthentication</strong> attribute is used with the
279
      <p>The <strong>tomcatAuthentication</strong> and
280
      <strong>tomcatAuthorization</strong> attributes are used with the
280
      AJP connectors to determine if Tomcat should authenticate the user or if
281
      AJP connectors to determine if Tomcat should authenticate the user or if
281
      authentication can be delegated to the reverse proxy that will then pass
282
      authentication can be delegated to the reverse proxy that will then pass
282
      the authenticated username to Tomcat as part of the AJP protocol.</p>
283
      the authenticated username to Tomcat as part of the AJP protocol.</p>
(-)webapps/docs/windows-auth-howto.xml (-1 / +3 lines)
Lines 299-305 Link Here
299
  <li>Configure IIS to use Windows authentication</li>
299
  <li>Configure IIS to use Windows authentication</li>
300
  <li>Configure Tomcat to use the authentication user information from IIS by
300
  <li>Configure Tomcat to use the authentication user information from IIS by
301
  setting the tomcatAuthentication attribute on the <a href="config/ajp.html">
301
  setting the tomcatAuthentication attribute on the <a href="config/ajp.html">
302
  AJP connector</a> to <code>false</code>.</li>
302
  AJP connector</a> to <code>false</code>. Alternatively, set the
303
  tomcatAuthorization attribute to <code>true</code> to allow Windows to
304
  authenticate, while Tomcat performs the authorization.</li>
303
  </ol>
305
  </ol>
304
  </subsection>
306
  </subsection>
305
307

Return to bug 57708