You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Thomas Strauß <t....@srs-management.de> on 2015/01/26 09:54:42 UTC

request.getUserPrincipal() is null but StandardSession.principal is set

Hi,

we have an issue with later and latest Tomcat versions, that prevent us from upgrading to a version later than something like 7.0.22.

We use FormBasedAuthentication with a custom realm.

This is tested with Tomcat 7.0.57 and JDK 7u76 on Windows.

My setup has a login form calling the j_security servlet. The custom realm is called and authentication is successful, a custom principal is returned.

Tomcat will then forward to the protected resource, and we catch the request in a RequestListener.

The problem is, that request.getUserPrincipal() returns null. The debugger exposes, that the sessionwrapper returned by request.getSession(false) (instance of SessionWrapper, containing StandardSession) has a field "principal", that contains the principal returned from my realm.

I have seen a discussion on the requirement to return a userprincipal on non protected requests in bugzilla, but the request here is calling for a protected resource.

Any idea on why this can happen would be very helpful. Actually, I see it as a bug, that the request is not authenticated but still served.


Mit freundlichen Grüßen

Thomas Strauß
Geschäftsführer Entwicklung

SRS PaperDynamix®
WE MAKE PAPER WORK

T +49 6251 85 424 - 20 | M +49 174 2110912

SRS-Management GmbH | Berliner Ring 103 | D-64625 Bensheim
Geschäftsführer: Detlev Homilius, Thomas Strauß HRB 25262 AG Darmstadt
Fon +49 6251 85 424-0 | Fax +49 6251 85 424-14

Wir freuen uns auf einen Besuch in unserem Forum auf XING oder Facebook
https://www.xing.com/net/prozessoptimierung/
http://www.facebook.com/srs.management<http://www.facebook.com/pages/SRS-Management-GmbH/155489571182317?sk=wall>


AW: request.getUserPrincipal() is null but StandardSession.principal is set

Posted by Thomas Strauß <t....@srs-management.de>.
Hi,

the problem is isolated in StandardHostValve Lines 165ff:

        boolean errorAtStart = response.isError();
165:    if (asyncAtStart || context.fireRequestInitEvent(request)) {

            // Ask this Context to process this request
            try {
                if (!asyncAtStart || asyncDispatching) {
170:               context.getPipeline().getFirst().invoke(request, response);
                } else {
                    if (!errorAtStart) {
                        throw new IllegalStateException(sm.getString("standardHost.asyncStateError"));
                    }



In line 165, the request is feed into the request listener (no authentication set here).

In line 170, the pipeline is processed, including the authentication process. The form based authentication is then setting the userPrincipal.

This is definitely different to earlier versions of the engine. The request listener cannot be used to handle authentication any more. If this is against or valid with the spec, I cannot tell for the moment. Yet, it is somewhat strange, as the request is not fully initialized, when the request initialized event is fired.

Should I copy this behaviour into bugzilla and open an issue? Should be mentioned in the release notes, at least...

Mit freundlichen Grüßen

Thomas Strauß
Geschäftsführer Entwicklung

SRS PaperDynamix® 
WE MAKE PAPER WORK

T +49 6251 85 424 - 20 | M +49 174 2110912

SRS-Management GmbH | Berliner Ring 103 | D-64625 Bensheim
Geschäftsführer: Detlev Homilius, Thomas Strauß HRB 25262 AG Darmstadt 
Fon +49 6251 85 424-0 | Fax +49 6251 85 424-14

Wir freuen uns auf einen Besuch in unserem Forum auf XING oder Facebook
https://www.xing.com/net/prozessoptimierung/
http://www.facebook.com/srs.management


-----Ursprüngliche Nachricht-----
Von: Konstantin Kolinko [mailto:knst.kolinko@gmail.com] 
Gesendet: Montag, 26. Januar 2015 11:43
An: Tomcat Users List
Betreff: Re: request.getUserPrincipal() is null but StandardSession.principal is set

2015-01-26 11:54 GMT+03:00 Thomas Strauß <t....@srs-management.de>:
> Hi,
>
> we have an issue with later and latest Tomcat versions, that prevent us from upgrading to a version later than something like 7.0.22.
>
> We use FormBasedAuthentication with a custom realm.
>
> This is tested with Tomcat 7.0.57 and JDK 7u76 on Windows.
>
> My setup has a login form calling the j_security servlet. The custom realm is called and authentication is successful, a custom principal is returned.
>
> Tomcat will then forward to the protected resource, and we catch the request in a RequestListener.
>
> The problem is, that request.getUserPrincipal() returns null. The debugger exposes, that the sessionwrapper returned by request.getSession(false) (instance of SessionWrapper, containing StandardSession) has a field "principal", that contains the principal returned from my realm.
>
> I have seen a discussion on the requirement to return a userprincipal on non protected requests in bugzilla, but the request here is calling for a protected resource.
>
> Any idea on why this can happen would be very helpful. Actually, I see it as a bug, that the request is not authenticated but still served.


1. Source code = ?
I see that you have it here:
https://stackoverflow.com/questions/28147261/request-getuserprincipal-is-null-but-standardsession-principal-is-set

2. Stacktrace when RequestListener is invoked = ?

When the listener is called? Is it called after authenticator valve or before it?

3. Try debugging through AuthenticatorBase.invoke() https://wiki.apache.org/tomcat/FAQ/Developing#Debugging

There is code that copies the principal from session into request [[[
        if (cache) {
...
                    if (principal != null) {
                        if (log.isDebugEnabled())
                            log.debug("We have cached auth type " +
                                session.getAuthType() +
                                " for principal " +
                                session.getPrincipal());
                        request.setAuthType(session.getAuthType());
                        request.setUserPrincipal(principal);
                    }
                }
            }
        }
]]]


4. This does not reproduce in the default configuration. There is a page in examples webapp that uses FORM authentication.

http://localhost:8080/examples/jsp/security/protected/index.jsp

If you look into index.jsp it will display "No user principal could be identified." when request.getUserPrincipla() is null.  It displays the correct principal name for me.

5. Is your principal a subclass of GenericPrincipal? How do you set it?


Best regards,
Konstantin Kolinko

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


--
This message has been scanned for viruses and dangerous content by MailScanner, and is believed to be clean.


Re: request.getUserPrincipal() is null but StandardSession.principal is set

Posted by Konstantin Kolinko <kn...@gmail.com>.
2015-01-26 15:10 GMT+03:00 Thomas Strauß <t....@srs-management.de>:
>
> -----Ursprüngliche Nachricht-----
>> Von: Konstantin Kolinko [mailto:knst.kolinko@gmail.com]
>> Gesendet: Montag, 26. Januar 2015 13:01
>> An: Tomcat Users List
>> Betreff: Re: request.getUserPrincipal() is null but StandardSession.principal is set
>
>> The stacktrace above does not have FormAuthenticatorValve,  so there is no wonder that request has not been authenticated yet.
>>
>> There is the following change for 7.0.22 in the changelog file:
>>
>> [quote]
>> Correct a regression with the fix for 51653 that broke custom error pages for 4xx responses from the Authenticators. Error handling and > request listeners are now handled in the StandardHostValve to ensure they wrap all Context level activity. (markt) [/quote]
>
> Yes, maybe obvious for you, and is clear now for me, but the side effect, that authentication is no longer available to a request listener would have saved me some hours. Anyway, thanks for helping out.
>
> I will rewrite the listener to a filter then, as I see no other possibility here.
>

Generally Filter is a better defined interface. People have different
expectations on RequestListener behaviour. (A recent discussion was in
https://issues.apache.org/bugzilla/show_bug.cgi?id=57314 )

Best regards,
Konstantin Kolinko

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


AW: request.getUserPrincipal() is null but StandardSession.principal is set

Posted by Thomas Strauß <t....@srs-management.de>.
-----Ursprüngliche Nachricht-----
> Von: Konstantin Kolinko [mailto:knst.kolinko@gmail.com] 
> Gesendet: Montag, 26. Januar 2015 13:01
> An: Tomcat Users List
> Betreff: Re: request.getUserPrincipal() is null but StandardSession.principal is set

> In this mailing list the convention is to respond below the original question:
> http://tomcat.apache.org/lists.html#tomcat-users
> -> 6.

Sorry.


> The stacktrace above does not have FormAuthenticatorValve,  so there is no wonder that request has not been authenticated yet.
>
> There is the following change for 7.0.22 in the changelog file:
>
> [quote]
> Correct a regression with the fix for 51653 that broke custom error pages for 4xx responses from the Authenticators. Error handling and > request listeners are now handled in the StandardHostValve to ensure they wrap all Context level activity. (markt) [/quote]

Yes, maybe obvious for you, and is clear now for me, but the side effect, that authentication is no longer available to a request listener would have saved me some hours. Anyway, thanks for helping out. 

I will rewrite the listener to a filter then, as I see no other possibility here.

Best regards, 

Thomas

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: request.getUserPrincipal() is null but StandardSession.principal is set

Posted by Konstantin Kolinko <kn...@gmail.com>.
2015-01-26 14:27 GMT+03:00 Thomas Strauß <t....@srs-management.de>:
> Hi,
>
> thanks for replying, yes, this question is also posted on SO.
>
> You did actually help me understand the problem better, yet, I cannot resolve it for the moment.
>
> To summarize my findings: I have a principal set in the protected resource. If a request is triggered from the protected resource, the request is no longer equipped with the principal in the listener. When arriving on the jsp, the principal is set again.
>
> If I set a breakpoint inside the request listener to trigger on a non null principal, it is never triggered.
>
> Hmmm, shouldn't tomcat provide the generic principal from the session before the listener is called, when running form authentication?
>
> I gave some details to your questions below.
>
> To (1): is additional source required?
>
> To (2): Here is the stack when the listener triggers:
>
> PortalRequestListener.requestInitialized(ServletRequestEvent) line: 79
> StandardContext.fireRequestInitEvent(ServletRequest) line: 6157
> StandardHostValve.__invoke(Request, Response) line: 165
> StandardHostValve.invoke(Request, Response) line: not available
> ErrorReportValve.invoke(Request, Response) line: 103
> AccessLogValve.invoke(Request, Response) line: 950
> StandardEngineValve.invoke(Request, Response) line: 116
> CoyoteAdapter.service(Request, Response) line: 421
> Http11Processor(AbstractHttp11Processor).process(SocketWrapper<S>) line: 1070
> Http11Protocol$Http11ConnectionHandler(AbstractProtocol$AbstractConnectionHandler).process(SocketWrapper<S>, SocketStatus) line: 611
> JIoEndpoint$SocketProcessor.run() line: 314
>
> I checked with all requests coming in, but the stack contents is the same for all breakpoints.
>

In this mailing list the convention is to respond below the original question:
http://tomcat.apache.org/lists.html#tomcat-users
-> 6.


The stacktrace above does not have FormAuthenticatorValve,  so there
is no wonder that request has not been authenticated yet.

There is the following change for 7.0.22 in the changelog file:

[quote]
Correct a regression with the fix for 51653 that broke custom error
pages for 4xx responses from the Authenticators. Error handling and
request listeners are now handled in the StandardHostValve to ensure
they wrap all Context level activity. (markt)
[/quote]


Best regards,
Konstantin Kolinko

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


AW: request.getUserPrincipal() is null but StandardSession.principal is set

Posted by Thomas Strauß <t....@srs-management.de>.
Hi,

thanks for replying, yes, this question is also posted on SO.

You did actually help me understand the problem better, yet, I cannot resolve it for the moment.

To summarize my findings: I have a principal set in the protected resource. If a request is triggered from the protected resource, the request is no longer equipped with the principal in the listener. When arriving on the jsp, the principal is set again.

If I set a breakpoint inside the request listener to trigger on a non null principal, it is never triggered.

Hmmm, shouldn't tomcat provide the generic principal from the session before the listener is called, when running form authentication?

I gave some details to your questions below.

To (1): is additional source required? 

To (2): Here is the stack when the listener triggers:

PortalRequestListener.requestInitialized(ServletRequestEvent) line: 79	
StandardContext.fireRequestInitEvent(ServletRequest) line: 6157	
StandardHostValve.__invoke(Request, Response) line: 165	
StandardHostValve.invoke(Request, Response) line: not available	
ErrorReportValve.invoke(Request, Response) line: 103	
AccessLogValve.invoke(Request, Response) line: 950	
StandardEngineValve.invoke(Request, Response) line: 116	
CoyoteAdapter.service(Request, Response) line: 421	
Http11Processor(AbstractHttp11Processor).process(SocketWrapper<S>) line: 1070	
Http11Protocol$Http11ConnectionHandler(AbstractProtocol$AbstractConnectionHandler).process(SocketWrapper<S>, SocketStatus) line: 611	
JIoEndpoint$SocketProcessor.run() line: 314	

I checked with all requests coming in, but the stack contents is the same for all breakpoints.

To (3): I have debugged the FormAuthenticator and found that the request is actually at some point equipped with the correct principal. So the authentication actually works to some extent.

I have restructured the main.jsp to do nothing, and it gets displayed properly, genericPrincipal is set.
If I call from that page a protected resource, that request has no principal set, but I can see the principal in the session (buried in the StandardSession object).

Shouldn't the request receive the principal, as it is requesting a protected resource?

To (5): Yes, it is subclass from GenericPrincipal and created by the realm (using new) and returned to the caller of authenticate. I see the principal object with right class name in the debugger at the right place.

Mit freundlichen Grüßen

Thomas Strauß
Geschäftsführer Entwicklung

SRS PaperDynamix® 
WE MAKE PAPER WORK

T +49 6251 85 424 - 20 | M +49 174 2110912

SRS-Management GmbH | Berliner Ring 103 | D-64625 Bensheim
Geschäftsführer: Detlev Homilius, Thomas Strauß HRB 25262 AG Darmstadt 
Fon +49 6251 85 424-0 | Fax +49 6251 85 424-14

Wir freuen uns auf einen Besuch in unserem Forum auf XING oder Facebook
https://www.xing.com/net/prozessoptimierung/
http://www.facebook.com/srs.management

-----Ursprüngliche Nachricht-----
Von: Konstantin Kolinko [mailto:knst.kolinko@gmail.com] 
Gesendet: Montag, 26. Januar 2015 11:43
An: Tomcat Users List
Betreff: Re: request.getUserPrincipal() is null but StandardSession.principal is set

2015-01-26 11:54 GMT+03:00 Thomas Strauß <t....@srs-management.de>:
> Hi,
>
> we have an issue with later and latest Tomcat versions, that prevent us from upgrading to a version later than something like 7.0.22.
>
> We use FormBasedAuthentication with a custom realm.
>
> This is tested with Tomcat 7.0.57 and JDK 7u76 on Windows.
>
> My setup has a login form calling the j_security servlet. The custom realm is called and authentication is successful, a custom principal is returned.
>
> Tomcat will then forward to the protected resource, and we catch the request in a RequestListener.
>
> The problem is, that request.getUserPrincipal() returns null. The debugger exposes, that the sessionwrapper returned by request.getSession(false) (instance of SessionWrapper, containing StandardSession) has a field "principal", that contains the principal returned from my realm.
>
> I have seen a discussion on the requirement to return a userprincipal on non protected requests in bugzilla, but the request here is calling for a protected resource.
>
> Any idea on why this can happen would be very helpful. Actually, I see it as a bug, that the request is not authenticated but still served.


1. Source code = ?
I see that you have it here:
https://stackoverflow.com/questions/28147261/request-getuserprincipal-is-null-but-standardsession-principal-is-set

2. Stacktrace when RequestListener is invoked = ?

When the listener is called? Is it called after authenticator valve or before it?

3. Try debugging through AuthenticatorBase.invoke() https://wiki.apache.org/tomcat/FAQ/Developing#Debugging

There is code that copies the principal from session into request [[[
        if (cache) {
...
                    if (principal != null) {
                        if (log.isDebugEnabled())
                            log.debug("We have cached auth type " +
                                session.getAuthType() +
                                " for principal " +
                                session.getPrincipal());
                        request.setAuthType(session.getAuthType());
                        request.setUserPrincipal(principal);
                    }
                }
            }
        }
]]]


4. This does not reproduce in the default configuration. There is a page in examples webapp that uses FORM authentication.

http://localhost:8080/examples/jsp/security/protected/index.jsp

If you look into index.jsp it will display "No user principal could be identified." when request.getUserPrincipla() is null.  It displays the correct principal name for me.

5. Is your principal a subclass of GenericPrincipal? How do you set it?


Best regards,
Konstantin Kolinko

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


--
This message has been scanned for viruses and dangerous content by MailScanner, and is believed to be clean.


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: request.getUserPrincipal() is null but StandardSession.principal is set

Posted by Konstantin Kolinko <kn...@gmail.com>.
2015-01-26 11:54 GMT+03:00 Thomas Strauß <t....@srs-management.de>:
> Hi,
>
> we have an issue with later and latest Tomcat versions, that prevent us from upgrading to a version later than something like 7.0.22.
>
> We use FormBasedAuthentication with a custom realm.
>
> This is tested with Tomcat 7.0.57 and JDK 7u76 on Windows.
>
> My setup has a login form calling the j_security servlet. The custom realm is called and authentication is successful, a custom principal is returned.
>
> Tomcat will then forward to the protected resource, and we catch the request in a RequestListener.
>
> The problem is, that request.getUserPrincipal() returns null. The debugger exposes, that the sessionwrapper returned by request.getSession(false) (instance of SessionWrapper, containing StandardSession) has a field "principal", that contains the principal returned from my realm.
>
> I have seen a discussion on the requirement to return a userprincipal on non protected requests in bugzilla, but the request here is calling for a protected resource.
>
> Any idea on why this can happen would be very helpful. Actually, I see it as a bug, that the request is not authenticated but still served.


1. Source code = ?
I see that you have it here:
https://stackoverflow.com/questions/28147261/request-getuserprincipal-is-null-but-standardsession-principal-is-set

2. Stacktrace when RequestListener is invoked = ?

When the listener is called? Is it called after authenticator valve or
before it?

3. Try debugging through AuthenticatorBase.invoke()
https://wiki.apache.org/tomcat/FAQ/Developing#Debugging

There is code that copies the principal from session into request
[[[
        if (cache) {
...
                    if (principal != null) {
                        if (log.isDebugEnabled())
                            log.debug("We have cached auth type " +
                                session.getAuthType() +
                                " for principal " +
                                session.getPrincipal());
                        request.setAuthType(session.getAuthType());
                        request.setUserPrincipal(principal);
                    }
                }
            }
        }
]]]


4. This does not reproduce in the default configuration. There is a
page in examples webapp that uses FORM authentication.

http://localhost:8080/examples/jsp/security/protected/index.jsp

If you look into index.jsp it will display "No user principal could be
identified." when request.getUserPrincipla() is null.  It displays the
correct principal name for me.

5. Is your principal a subclass of GenericPrincipal? How do you set it?


Best regards,
Konstantin Kolinko

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org