We have upgraded from 2.8 to 4.3 and find page fetch performance is significantly degraded when using a custom authenticator.
Though this is partly because of the increased page content in 4.3, performance is severely exacerbated when we enable our custom authenticator.
The support for this was why we chose Confluence in the first place, to integrate the Digital Certificate authentication used by all our applications.
There is some difference in the authentication chain in 4.3 that we need instruction about, or documentation for (there being none I can find online).
I attach the code for our current one (GdsConfluenceAuthenticator-2.8.java which won't build against 4.3 libraries) and the version that I derived from it (GdsConfluenceAuthenticator.java) - somewhat by trial and error (and by decompiling some of your .jar files!).
GdsConfluenceAuthenticator is enabled in the normal way, by modifying two files:
1. seraph-config.xml - changing the
2. web.xml - adding three fields:,and
I attach the modified files.
I enabled the Profiler while clicking on two links (/display/WebSolutions/Web+Solutions+IT and /display/WebSolutions/AskBIS+Development) with default (ie: name+password authentication) and our (GdsConfluenceAuthenticator) authentication.
In both scenarios I pre-clicked each link to get any browser-cacheable content loaded.
The load times reported by the profiler belie the actual time seen by a user. For name+password authentication (profile-passwords.log), the times are similar, but with GdsConfluenceAuthenticator (profile-certificatesE.log) the real time is longer.
The differing order of events, and the debugging I have enabled, muddy the output a bit. But if you diff the two files side-by-side, what stands out is that there are many more calls to UserAccessor.getUser() with GdsConfluenceAuthenticator than without.
This makes me think that there is some other step needed on initial login as well as AuthenticatedUserThreadLocal.setUser() (at line 48).
We cannot upgrade until we can get comparable performance out of 4.3
Since this miserable website won't let me comment on Jamie Echlin's answer, I have to do so here by "answering" my own question:
Hi Jamie - I've switched to your ExampleSSOAuthenticator but sadly the performance problem is unchanged.
Authentication works (as it does with my original - which only really differs from yours in that it extends ConfluenceGroupJoiningAuthenticator rather than ConfluenceAuthenticator). All I have done to your code is, in getUser(), immediately below
if (existingUser != null) { // .... return existingUser; }
I added this:
// No session, so "login" using GdsUser principal set up by gdsrealm.jar (or indeed any other JAAS LoginModule) Principal result = request.getUserPrincipal(); if (result != null) { String username = result.getName(); Principal user = getUser(username); // Get the com.atlassian.user.User if (user != null) { putPrincipalInSessionContext(request, user); getElevatedSecurityGuard().onSuccessfulLoginAttempt(request, username); getEventPublisher().publish(new LoginEvent(this, username, request.getSession().getId(), request.getRemoteHost(), request.getRemoteAddr())); LoginReason.OK.stampRequestResponse(request, response); log.info("getUser() GDSREALM login for : " + username + " response: " + response + " user: " + user + " in " + (System.currentTimeMillis() - start) + "ms"); return user; } } log.info("We never get here ...");
As with my original code, when compared with a session configured for name+password:
a) the performance is massively worse, and
b) it generates many more UserAccessor.getUser() calls (as shown with Confluence Profiling enabled).
So it feels to me that there must be something else that should be done during the initial SSO login.
An anomaly I see in the logging I make on initial login, is that there are two calls at the beginning of a new session. The first has "response" set to null and hence, I assume, fails to do whatever it then does on the second call when "response" is a HttpServletResponse object.
Any further thoughts would be very much appreciated!
Hrm... firstly it's not my code, but @Joseph Clark's, who is the right man to help you here.
I won't pretend this shizzle is not hard, it's much worse than trying to write a standard plugin imho.
Why are you extending GroupJoiningAuthenticator? You should not... what is the performance like extending the class that the sample extends? You don't need it to auto-join any groups, this is covered by the standard embedded crowd stuff. If the user is plucked from a directory that has the configuration where a user is auto-added to a group or list of groups, that will happen.
> b) it generates many more UserAccessor.getUser() calls (as shown with Confluence Profiling enabled).
But where is this being called from, can you mod the code to log a stack trace? Or stick a breakpoint in or something.
Um... you really need Joe Clarke's attentions on this one.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Sorry if my wording wasn't clear. I am now extending ConfluenceAuthenticator. I am using the exact code that you posted, with just the addition of the block I show above.
I've no idea where UserAccessor.getUser() is called from - I just note that there are many more of them in the Confluence Profiler output with ExampleSSOAuthenticator than using the out-of-the box name+password login. This may be a red herring. The Profiler shows each of them taking only 1 or 2ms, and there can't be more than about 30 additional ones.
I'll see if I can pester Joe Clark!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Jamie - I've had no joy yet in raising a response from Joe or anyone at Atlassian.
I wonder if there is a problem with the 3 sections we add to web.xml (security-constraint, login-config and security-role) to get CLIENT-CERT authentication.
They are what we used in 2.8 (which used Java servlet 2.3 spec). I see 4.3 uses 2.4 spec, so maybe the syntax and/or ordering of sections needs to change.
What do you put in web.xml?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Peter... I'd create a support request and beg for help from Joe.
Although we both use x.509 certs I'd guess we do things differently, although this doesn't account for the difference I think.
I used to do it like you do, we had the stuff in the web.xml and java libs for decoding the cert etc. At some point though I switched to having the ssl connection terminated at apache, and apache just sets a request header with the authenticated user name. The authenticator takes this and stuffs the user in the session as per usual. For this bit apache to tomcat is via ajp.
The other main difference is that I only use two-way SSL for hitting a special url called /loginsso.action, everything else is redirected to http. The /loginsso is redirected to https. So to all intents and purposes, unless the user is logging in, then the auth module just behaves like the standard one.
I'm quite happy with this method, because I only need to change minimal code in all the atlassian products, and not add any jars or anything.
Don't know if that helps you, but thought I'd expand a bit.
Can you add some debug to your code to verify that once the user is logged in and in the session, they never go through your pki bit of code?
jamie
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
So to answer your question, nothing is put in the web.xml (anymore).
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Jamie - many thanks for that. As it happens we also use an Apache fronting server do the cert negotiation, with it AJP-ing to the Tomcat. But, we also like to support direct client-cert access to the Tomcat.
We use a (JAAS, I believe) "realm" to handle either scenario. This, from my understanding, has to be enabled in web.xml (if it isn't request.getUserPrincipal() returns null).
I have logging in (Joe's) ExampleSSOAuthenticator which shows our realm-based lookup only happens at session setup.
All following calls return at the top of the method because getUserFromSession(request) has a non-null value.
I have a ticket with Atlassian, but they say this is "out of scope issue for Atlassian Support", that I should pursue via this answers.atlassian discussion and that "hopefully [Joe] will be there replying soon".
Forgive my (as must be becoming clear!) ignorance, but how do you configure so that your /loginsso.action is called at login?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
> but how do you configure so that your /loginsso.action is called at login?
I want to support both SSO and forms-based login. So I've just modified the login.jsp page to have a new link called Secure Sign-On, that points to /loginsso.action. Then apache rewrites that to https://.../login.action. So there is not really a different action...
> All following calls return at the top of the method because getUserFromSession(request) has a non-null value
In that case I really don't understand why you'd see a performance difference... baffled.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I've found the problem: it was in the <security-constraint> we add to web.xml to enable "realm" authentication.
In Confluence 2.8 (Java servlet 2.3) it was set (possibly over-archingly) to <url-pattern>/*</url-pattern>
With 4.3 (servlet 2.4), when I restricted this to <url-pattern>/login.action</url-pattern> performance became normal.
Related wrinkles in the unlikely event that anyone else is upgrading from 2.8 (I believe the 2.8 -> 3.5 is the crucial change):
Very many thanks again Jamie for your pointers and feedback.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I'd start by blowing off your old authenticator completely and rewriting based on https://bitbucket.org/jaysee00/example-confluence-sso-authenticator.
BTW nothing is attached to your question so hard to comment further.
Our custom authenticator handles x.509 certs, which I assume is what you have too, and there is no performance hit. Once you have retrieved the user you put them in the session and then the profile should be no different than with the out of the box authenticator.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Here's an attempt to add the two .log files directly after Jira support tells me that .java and .xml are not supported on the "Upload" button: (profile-certificatesE.log) and
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Here are the files referred to in my original post:
http://www.binney.net/work/GdsConfluenceAuthenticator-2.8.java
http://www.binney.net/work/GdsConfluenceAuthenticator.java
http://www.binney.net/work/profile-certificatesE.log
http://www.binney.net/work/profile-passwords.log
http://www.binney.net/work/seraph-config.xml
http://www.binney.net/work/web.xml
and also, the slightly modified http://www.binney.net/work/ExampleSSOAuthenticator.java I now have also tried.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I'm getting distinctly fed up with this website! I just tried to post a comment to Jamie Echlin's answer below which was rejected with "Sorry, our spambot thinks your comment is spam. Please post an answer instead".
But when I try and answer it then says: "Please make sure you are providing an answer to your own question. Otherwise, choose "add comment" to continue a conversation about a given answer or to clarify your question. For more information, see the FAQ."
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
But easier to add them to gist.gitbub.com and link from here.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
One for @Jeremy Largman.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Sadly that's blocked from my work. The files are innocuous, so I'll upload them at the weekend onto my noddy website which isn't.
But am continuing with your template SSO - many thanks again!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
That doesn't seem to work. I'm clicking the "Upload" arrow button and selecting a file called GdsConfluenceAuthenticator.java : but nothing appears to be uploaded :-(
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
But, I think I can upload a .log file ... profile-certificatesE.log ...
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Nope . That didn't work either. The .log "upload" behaved differently from the .xml and .java ones in that an apparrant link to the file appeared in this editor. But, when I pressed "Comment" it disappeared
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
If you create a new answer or comment you can upload them.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Many thanks Jamie. I have effectively done what you suggested. But I'll try again from the one you link to.
Sorry about the missing attachments - this issue was auto-created from a post to Atlassian support and I didn't notice that the files were missing. I'll try and attach them here...
... hmm that doesn't seem to work. Any idea how to attach files here?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.