Bug 949737 - [GSS] (6.4.0) Session replication broken by NegotiationAuthenticator valve
Summary: [GSS] (6.4.0) Session replication broken by NegotiationAuthenticator valve
Keywords:
Status: CLOSED CURRENTRELEASE
Alias: None
Product: JBoss Enterprise Application Platform 6
Classification: JBoss
Component: Security
Version: 6.0.1
Hardware: Unspecified
OS: Unspecified
unspecified
medium
Target Milestone: DR11
: EAP 6.4.0
Assignee: Darran Lofthouse
QA Contact: Pavel Slavicek
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2013-04-08 20:51 UTC by Derek Horton
Modified: 2019-08-19 12:41 UTC (History)
14 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Previous versions of JBoss EAP 6 did not include an option to define global authentication mechanisms as there was in JBoss EAP 5. To overcome this limitation the advice for enabling SPNEGO authentication was to manually add the Valve to the `jboss-web.xml` of the affected deployment. The consequence of this was that the valve was invoked much earlier in the call and preceded the valve responsible for clustering. This meant that the JBoss Negotiation valve created a new HTTP session and the clustering valve did not receive any notifications regarding the life-cycle of the sessions. As the clustering valve was not receiving the notification it needed the session was not clustered and replication was affected. This release of JBoss EAP 6 now supports defining authentication mechanisms globally. This approach deprecates adding the valve manually to the web application's `jboss-web.xml`. The SPNEGO authentication valve will now be called after the clustering valve so that the clustering valve will receive the required notifications relating to session life-cycle and will replicate the session correctly.
Clone Of:
Environment:
Last Closed:
Type: Bug
Embargoed:


Attachments (Terms of Use)
Simple application with NegotiationAuthenticator (3.96 KB, application/octet-stream)
2013-05-02 12:28 UTC, Ondrej Lukas
no flags Details
Simple application without NegotiationAuthenticator (4.12 KB, application/octet-stream)
2013-05-02 12:29 UTC, Ondrej Lukas
no flags Details
test.war (3.33 KB, application/zip)
2013-06-06 10:09 UTC, Josef Cacek
no flags Details


Links
System ID Private Priority Status Summary Last Updated
Red Hat Issue Tracker SECURITY-733 0 Major Reopened Session replication broken by NegotiationAuthenticator valve 2019-07-15 17:30:24 UTC

Description Derek Horton 2013-04-08 20:51:36 UTC
Description of problem:

Enable the NegotiationAuthenticator as a valve in the jboss-web.xml file, causes session replication to quit working.

  <jboss-web>
    <security-domain>java:/jaas/jmx-console</security-domain>
      <valve>
        <class-name>org.jboss.security.negotiation.NegotiationAuthenticator</class-name>
      </valve>
  </jboss-web>

Version-Release number of selected component (if applicable):


How reproducible:


Steps to Reproduce:
1. Create an servlet that adds an attribute to the HTTP Session
2. Start a 2 node cluster
3. Hit the application on one node, then on the other node.  The attribute will not be set on the second node when the NegotiationAuthenticator is enabled.
  
Actual results:


Expected results:


Additional info:

Comment 1 Derek Horton 2013-04-08 20:52:06 UTC
It looks like the NegotiationAuthenticator provides its own
setNext()/getNext() implementation.  This appears to be breaking the
code above.

   @Override
   public void setNext(final Valve nextValve)
   {
      super.setNext(new Valve()
      {

         public String getInfo()
         {
            return nextValve.getInfo();
         }

         public Valve getNext()
         {
            return nextValve.getNext();
         }

         public void setNext(Valve valve)
         {
            nextValve.setNext(valve);

         }

         public void backgroundProcess()
         {
            nextValve.backgroundProcess();
         }

         public void invoke(Request request, Response response) throws IOException, ServletException
         {
            Session session = request.getSessionInternal();
            GSSCredential credential = (GSSCredential) session.getNote(DELEGATION_CREDENTIAL);
            try
            {
               DelegationCredentialManager.setDelegationCredential(credential);
               nextValve.invoke(request, response);
            }
            finally
            {
               DelegationCredentialManager.removeDelegationCredential();
            }
         }

         public void event(Request request, Response response, HttpEvent event) throws IOException, ServletException
         {
            nextValve.event(request, response, event);
         }
      });
   }

The ClusterSessionValve gets put into the pipeline correctly and session
replication works if I comment out the NegotiationAuthenticator.setNext() 
method.

Comment 2 Darran Lofthouse 2013-04-18 16:17:01 UTC
I believe I see the cause, debugging further to be sure - the Valve ClusterSessionValve also implements Lifecycle - I suspect that as the wrapper around the valve does not implement this interface some Lifecycle related notifications are getting missed.

Comment 3 JBoss JIRA Server 2013-04-22 12:43:09 UTC
Darran Lofthouse <darran.lofthouse> updated the status of jira SECURITY-733 to Resolved

Comment 4 JBoss JIRA Server 2013-04-22 12:43:09 UTC
Darran Lofthouse <darran.lofthouse> made a comment on jira SECURITY-733

JBoss Negotiation makes use of a wrapper to intercept calls through the Valves to ensure the delegation credential is set - this was unfortunately hiding the Lifecycle implementation of the wrapped valve.

The code change now introduces an additional valve in the chain rather than completely wrapping the next valve - this makes the Lifecycle implementation visible.

Comment 6 Ondrej Lukas 2013-05-02 11:33:47 UTC
I've tried to verify it, but it still doesn't work in Negotiation 2.2.3. Application without NegotiationAuthenticator works fine. 

@Derek, It hasn't blocker flag set yet. Is it a customer request? If so I would request the blocker flag for this issue. WDYT?

Comment 7 Rostislav Svoboda 2013-05-02 11:46:55 UTC
Setting Blocker flag to ?, we need to discuss this on triage meeting

jboss security negotiation will be probably upgraded in ER7 for ldap login module fix ...

Comment 8 Ondrej Lukas 2013-05-02 12:28:54 UTC
Created attachment 742686 [details]
Simple application with NegotiationAuthenticator

Comment 9 Ondrej Lukas 2013-05-02 12:29:33 UTC
Created attachment 742687 [details]
Simple application without NegotiationAuthenticator

Comment 10 Dimitris Andreadis 2013-05-02 12:52:05 UTC
Darran can you look at this (again)?

Comment 12 Derek Horton 2013-05-02 20:46:52 UTC
@Ondrej, It is a customer request.  I would really like to get this fix included in EAP 6.1, but I don't think it has to be a blocker.

Comment 15 Dimitris Andreadis 2013-05-03 12:16:45 UTC
Assign to Jaikiran, if he has time to move it forward.

Comment 18 Derek Horton 2013-05-10 15:05:58 UTC
I can't see Darrin's comment on the case, but I see it on the linked jira and in emails...



Darrin, the FIX and RESULT in the Doc Text are a description of how this should be fixed in the future.

Comment 21 Darran Lofthouse 2013-06-05 09:57:16 UTC
Setting need info as I don't understand what is now failing.

Comment 22 Josef Cacek 2013-06-06 10:09:06 UTC
Created attachment 757589 [details]
test.war

Steps to reproduce:
0) save attached test.war to /tmp
1) ./domain.sh
2) ./jboss-cli.sh -c
/server-group=main-server-group:write-attribute(name=profile,value=ha)
/server-group=main-server-group:write-attribute(name=socket-binding-group, value=ha-sockets)
/server-group=main-server-group:restart-servers
deploy /tmp/test.war --server-groups=main-server-group
3) make a single request to http://localhost:8080/test/
4) make a single request to http://localhost:8230/test/

And here are the difference against the expected behavior:

==========
With the NegotiationAuthenticator (i.e. test.war)

Step 3) output:
Session attribute 'test': null
Writing 'value' to session attribute 'test'.

Step 4) output:
Session attribute 'test': null
Writing 'value' to session attribute 'test'.

==========
Without the NegotiationAuthenticator (remove WEB-INF/jboss-web.xml from test.war):

Step 3) output:
Session is null!
Session attribute 'test': null
Writing 'value' to session attribute 'test'.

Step 4) output:
Session attribute 'test': value
Writing 'value' to session attribute 'test'.

Comment 23 FIlip Bogyai 2013-06-13 12:22:31 UTC
If you deploy this test.war on two standalone-ha nodes, it works fine.

Steps to reproduce:
0) copy test.war to standalone/deployments on two separate installations
1) ./standalone.sh -c standalone-ha.xml
2) ./standalone.sh -c standalone-ha.xml \
-Djboss.socket.binding.port-offset=150 \
-Djboss.node.name=node2
3) make a single request to http://localhost:8080/test/
4) make a single request to http://localhost:8230/test/

Session attribute is successfully replicated.

Comment 24 FIlip Bogyai 2013-06-13 12:57:07 UTC
Sorry, it doesn't work too. Tested on wrong version.

Comment 25 baranowb 2013-09-04 07:56:39 UTC
Update milestone and related.

Comment 32 Jimmy Wilson 2014-01-13 12:12:26 UTC
We are moving this to CP02 as this missed the cutoff.

TODO: 6.3 bug to be created.

Comment 35 JBoss JIRA Server 2014-04-11 19:23:42 UTC
Derek Horton <dhorton> updated the status of jira SECURITY-733 to Reopened

Comment 37 Scott Mumford 2014-07-17 04:29:08 UTC
Removing privacy flags for inclusion in 6.3.0 Release Notes as a Known Issue.

Comment 39 Jochen Riedlinger 2014-09-01 07:14:46 UTC
We nee it for 6.3 CP01 !
I just opened a support-case (01183034).

This should have been a blocker and it's definitely not o.k. to change the target release to 6.4.0.

Comment 44 Darran Lofthouse 2014-11-20 18:06:02 UTC
Reviewing the comments again in this BZ I am considering if the reason I have seen a difference in behaviour is that my testing was after authentication had been performed but the remaining failure scenario is where no authentication is being performed.

Derek mentions above a suspicion regarding a call to getSessionInternal() - one thing I do notice here is that we may be trigering session creation on every request when it is only the ones that attempt authentication that we want a session created for but not sure how this relates.

And as I type that I believe I see the problem, the ClusteredSessionValve is performing some initialisation so that it receives a Callback when a new session is created - however the NegotiationAuthenticator is using sessions before we hit the ClusteredSessionValve so this callback is not being received.

Comment 45 Darran Lofthouse 2014-11-20 18:28:19 UTC
It looks like I should make a small fix to JBoss Negotiation to prevent sessions being created where they are not actually required however I believe this can be resolved with a configuration change.

Firstly a history lesson ;-)

In previous AS/EAP releases SPNEGO would be enabled by first defining a custom authenticator in the global configuration and then in the web.xml set the auth-method to match the name assigned to the authenticator e.g. SPNEGO.

However when we reached AS7 this global configuration was no longer possible and a request for it to be restored was denied, so the workaround was to ask users to add the authenticator valve to jboss-web.xml - during deployment this is detected and the addition of a subsequent authenticator is skipped.

Unfortunately as we see in this BZ this means that the NegotiationAuthenticator valve is now too early in the chain of valves and triggers session creation before the ClusteredSession valve so session creation goes unnoticed.

The good news is under PRODMGT-136 the definition of globally defined authenticators has now been restored so it should now be possible for the NegotiationAuthenticator valve to be defined globally and referenced from the auth-method of the web.xml.  This should be done instead of adding it to jboss-web.xml and should result in it being added in the correct place in the chain of valves AFTER the ClusteredSession valve.

I will go ahead with the minor fix I see is needed here but the comment from Derek re getSessionInternal definitely looks to me to be the issue here.

Comment 46 Darran Lofthouse 2014-11-21 18:01:18 UTC
I am about to send in a PR and ask for this to be switched to ON_QE, the PR will contain the following bug fix: -

https://bugzilla.redhat.com/show_bug.cgi?id=1166724

Note: For this specific bug I don't believe any fix is required and instead the NegotiationAuthenticator should be defined as a global authenticator in the web subsystem and then referenced by the auth-method in the web.xml - the valve definition should be removed from the jboss-web.xml descriptor.

However do take care as the PR minimises when sessions are created which would mask the underlying issue here.

Comment 47 Kabir Khan 2014-11-22 10:35:14 UTC
https://github.com/jbossas/jboss-eap/pull/2038 Setting to ON_QA in line with Darran's instructions in https://github.com/jbossas/jboss-eap/pull/2038 and previous comment.


Note You need to log in before you can comment on or make changes to this bug.