Wednesday, February 6, 2008

Single SignOn (SSO) with Seam using JOSSO

I recently used seam_gen to create a josso_console application. If you want to use JOSSO, but you don't yet want to take the leap to hook it up to an LDAP or other industrial strength credential store, then this is the app may come in handly. Figure 1 shows the welcome screen of josso_console application.


Figure 1. The JOSSO console.

If your objective is simply to hook your Seam application up to JOSSO then you should keep reading too.

1. Seam and JAAS
Seam comes with its own security framework which is based on JAAS. The easiest way to hook Seam up to JOSSO is to first configure your Seam-based application the conventional JOSSO way and then hooking up Seam and JOSSO using a Seam authenticator. I worked on a jossoAuthenticator that will set the SSO user and roles information into Seam context, so that you can use all the Seam security features while using JOSSO.

2. Configure JOSSO
In your josso-agent-config.xml add the josso_console in as a partner app


Now your application will have access to the JOSSO cookie.

3. Configure Seam
Next we're going to protect our application using the standard security constraints to the web.xml. For instance if we only want users that have the admin role to access our console you would add


This web.xml references the login-redirect.jsp which you will need to add to the root of your war file. Now, you will be redirected to the josso login screen when trying to access the web application.

Next we have to propagate the authorization information into Seam context. For this we use the jossoAuthenticator.
Next you need to reference this class in your pages.xml, by adding

and commenting out the default authenticator

Finally we need to modify the pages.xml, where we reference the jossoAuthenticator on our welcome page (index.xhtml) like

which will cause the jossoAuthenticator.checkLogin to be called for this page, and in the exception class configuration we specify the index.xhtml page


All should now be working. If you want, you can obtain the full sources from the josso_console application to see the complete application.

Some other resources in this context you may find useful are:
http://www.josso.org/confluence/display/JOSSO1/JBoss+4.2
http://sdudzin.blogspot.com/2007/12/windows-sso-with-jboss-seam.html, and
http://www.ja-sig.org/wiki/display/CASC/Seam+Identity+Integration+(Seam+1.2.1+-+2.0.0)

23 comments:

Geoff said...

Great work. This seems to be the one and only Josso/Seam integration article on the web.

One error above though: the security:identity.... line should be put in the component.xml, not faces.xml

Geoff said...

How do you implement logout of the seam identity ?

The identity would never know if the user logged out in another partner app, then logged in as someone else. Therefore your first check (identity.isLoggedOn()) could return true while the user is not the user you think he is.

Therefore do you have to always check the josso cookie as well ?

Kurt Stam said...

Hi Geoff,

Sure that would be one approach. I usually modify the third-party app a little. I look for the jsp that handles the logout and I add the session invalidation code like so:

<%
org.jboss.seam.Seam.invalidateSession();
String redirectURL = "/josso/signon/logout.do?josso_back_to=/@distro.name@/logoff.jsp";
response.sendRedirect(redirectURL);
%>


--Kurt

Geoff said...

What about the scenario where we have 2 partner apps, and a josso (all running on seperate JBoss servers).
PartnerApp1: User logs in (via josso)
PartnerApp2: Users goes there, then logs out of PartnerApp2.
At PartnerApp2, the user logs in as someone else (via Josso).
PartnerApp1: 2nd User comes back to partnerapp1, seam still has a valid indentity, thinks he's still the original user.

In summary, you need to implement "Single Sign Out", so that logouts away from your application are identified in your application, and that can only occur by looking at the josso cookie.

Kurt Stam said...

Hi Geoff,

String redirectURL = "/josso/signon/logout.do?josso_back_to=/@distro.name@/logoff.jsp";
response.sendRedirect(redirectURL);

will invalidate the SSO session. So when you get back to app1, you should be logged out and anything you do there should redirect you back to the login screen.

--Kurt

Tomas said...

Hi Kurt.

Thank you for providing a tutorial for integrating seam with josso. Have you been working with the josso team? They say that josso 1.7 "Integrates with JBoss Seam 2.x". What version of seam and josso have used with your JossoAuthenticator.java? I can't get it to work with 1.7 and seam 2.0.1.

Kurt Stam said...

Thank you Thomas,

Did you try using the console as is? Since it is a seam app it should be a nice example. I created it using JOSSO-1.6 and it became part of the JOSSO-1.7 release. It's using Seam-2.0.1.GA according to the jar's manifest.

--Kurt

Tomas said...

Hi Kurt.

Well I got the josso_console to work. For my own application, I did some minor alterations to your sample code.

Instead of looking for the josso cookie, I look for a principal:

FacesContext facesContext = FacesContext.getCurrentInstance();
// Obtain authenticated UserPrincipal from Servlet container
Principal rawPrincipal = facesContext.getExternalContext().getUserPrincipal();

...and I also need to need to run:

identity.authenticate();
Events.instance().raiseEvent("org.jboss.seam.security.loginSuccessful"); Events.instance().raiseEvent(Identity.EVENT_LOGIN_SUCCESSFUL);

Thanks for the sample code, it was very usefull.

cheers

/Tomas

Anonymous said...

Could you make the code available again? That would be really helpful

Kurt Stam said...

I updated the links into the JOSSO repository. That is what you meant right?

Anonymous said...

Hi Kurt.

I have made some changes to JossoAuthenticator so that it will work with seam 2.1.0.GA. As you surely know it's a new security api in 2.1. If you are interested in the code and configurations I made, please feel free to contact me.

tomas.emmer@triii.se

/Tomas

Kurt Stam said...

That would be great Tomas, I will try rolling them in.

--Kurt

Hans said...

This is a great blog post. It helped me a lot. However I seem to have problems reading the josso session cookie it doesn't appear to be available and I have added my application to the agent config file. I have a feeling it's a simple step that I'm missing. Is there anything else necessary besides the agent config file for me to see the josso session cookie? Any thoughts would be appreciated!.

Kurt Stam said...

I'm not sure you can look at the JOSSO cookie actually, I never looked into that, but your request contains lots of user info obtained from the sign on, which should be enough. On top of that you can listen to certain JOSSO events, and get more information that way. I hope this is in any way helpful.

--Kurt

Sidydrum said...

Hi Kurt, Geoff,

I'm facing the same problem as Geoff with the multiple apps logout.
I think the only solution to the problem is to track the ssoSessionId in the app itself.
I implemented a solution which seems to work (I still need to test it heavily).
I would have prefered to use a servlet filter but it seems I can't access the seam components of the previously logged user at the time the servlet is processed.

If you have any other suggestion ...

You can follow the post I put on seam forum

Cheers,
Chris.

Kurt Stam said...

Hi Chris,

Are you protecting the entire Seam app in the web.xml of the app? Like so

<web-resource-name>protected-resources</web-resource-name>
<url-pattern>/*</url-pattern>

--Kurt

Sidydrum said...

Hi Kurt,

Yes, I have

...
<url-pattern>/*</url-pattern>
...

What's the connection ?
Do you mean the seam identity might not be populated because it is not part of the protected URIs ?
But it is part of, as I have

...
<url-pattern>/*</url-pattern>
...

Do you suggest I should change something to my security config ?

Thanks,
Chris.

Kurt Stam said...

Hi Chris,

When the SSO session is invalided, access to all other apps will be shutdown, there may be a slight delay however. I think by default it only checks with the SSO gateway every 60 seconds (I think this is configurable). This is JOSSO specific, nothing really to do with Seam in particular.

-Kurt

Anonymous said...

hi Kurt,
i am desta from indonesia..

sory for my bad english.

i had already download josso 1.8
and have many missmatch step to build JOSSO 1.8
for my spring web application

can you give me a simple step by step to build a project basic on Josso..



i had already read the step by step form www.josso.org,and can not solved my problem..

thank u Kurt,

andesta@rocketmail.com

Kurt Stam said...

Hi Desta,

I think the best approach is to download a working bundle. The you should follow the steps on the JOSSO site and you can compare it to what you see in the working bundle. And you can use their user-forum to help out with specific questions.

--Kurt

Anonymous said...

Hi kurt..

thank you for your reply before,

re:

Hi Desta,

I think the best approach is to download a working bundle. The you should follow the steps on the JOSSO site and you can compare it to what you see in the working bundle. And you can use their user-forum to help out with specific questions.

==============================




i had followed the step on the JOSSO SITE..

and i get a problem when i press login button in page in partnerapp example :

http://localhost:8080/josso/signon/login.do?josso_back_to=http://localhost:8080/partnerapp/josso_security_check

user : user1 and password:user1pwd

the browser page view error report tomcat :

===================================
HTTP Status 500 -

type Exception report

message

description The server encountered an internal error () that prevented it from fulfilling this request.

exception

java.lang.RuntimeException: Outbound relaying failed. No Principal found. Verify your SSO Agent Configuration!
org.josso.tc60.agent.SSOAgentValve.invoke(SSOAgentValve.java:501)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:857)
org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:565)
org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1509)
java.lang.Thread.run(Unknown Source)

note The full stack trace of the root cause is available in the Apache Tomcat/6.0.18 logs.
Apache Tomcat/6.0.18
=============================================

i had already search for this error problem

in josso user forum (http://sourceforge.net/forum/?group_id=116854).

and i can not get the solution for this error problem..

sory for the asking again..

please help me for this error problem.

thank u kurt

Kurt Stam said...

Hi Desta,

Your best bet is to post questions like these on the forum (don't be shy). Try to be specific with your questions. In this case you really should try to start with a working environment (try downloading a ready to go bundle), and then try adding a partner app. Just take it one step at the time!

Cheers,

--Kurt

Konstantin Spirov said...

Hello all,

Please take a look at my article:
Mission Possible: Generic JEE Inegration Between JOSSO 1.8.1

I use another approach - with eliminating the security domain dependency. I would appreciate your opinion.

http://decaffeination.eu/2009/10/18/mission-possible-generic-jee-inegration-between-josso-1-8-1-agent-seam-2-2-0-and-jboss-5-1-0-ga/