Sunday, September 16, 2012

Jforum Integartion with existing webapplication

JForum is a powerful and robust discussion board system implemented in Java.

There are various ways to integrate JFourm with a existing web application.
1. Co-Exist as a seprate web application with a existing web application.
2. Embedd Jforum in your web application.

It is suggested to use the approach 1(Jforum Co-Exist as a separate web application), as in this approach the only Change you need to do in your application code is to provide a link to JForum. This is just a view(jsp) level change. You do not make your application clumsy, complex and jforum dependent using this approach.

In this tutorial i will focus on approach 1(Jforum Co-Exist as a separate web application).

JForum Installation
1. Download jforum-2.1.8 zip from Here

2. Rename directory as JFroum and deploy it (copy it to webapp of tomcat) as a separate application

3. It is better to install Jforum tables in seprate database.create desired database in mysql using sql command:

Create database db_name

4. run tomcat and access following url:

http://localhost/JForum/install.jsp

Installation wizard will be shown,The field names are self explanatory. Provide the appropriate details and complete the setup.

It is cleaner approach to keep the JForum Database separate from the application database.
Consider your application name is “myapp”. And the app server used is tomcat.

Integrating myapp with Jforum


Our requirement is to provide Single sign on to between myapp and jforum,that is when a user who has already signed in into myapp clicks on the jforum link, User is successfully logged in into JForum(in back end, without taking any inputs from user) .
JForum uses Cookie for Authentication. Note this binds us to keep both myapp and jforu both in same domain. Best approach is to keep both myapp and jforum web applications collocated in tomcat’s webapps folder
Call flow for integration will be as follows
1. User log in into myapp.
2. User clicks on the jforum link.
3. Myapp sets cookie and opens jforum in a IFrame
4. JForum SSO module checks cookie and authenticates the user
Enough Theory, lets start coding .


Thursday, July 12, 2012

Single sign on with spring security and Siteminder

Enviorment-Spring version-3.0.5,Siteminder

Goal-Integrating Single sign on using site minder with spring security.


1.What is Single Sign On?
Single sign on is a property/concept means login once into a web portal and navigate to other supported independent portals without being prompted login again.
Say you login into portal A once, now you can navigate to supported independent portal b,portal c without need to login again.

2.what is Site minder?
Site minder is single sign on system that authenticates the user and puts a token in http request header(SM_USER).
Overview of the request request processing-
1. Consider a user say user1 in your system logs in, on successfull authentication siteminder would put a header(SM_USER) in the httprequest with value say smuser1.
2. User clicks on a link on your web page to navigate to SSO supported portalb(siteminder will again populate the request with SM_USER header token,we will not get into details here).
3. Portalb will check if the SM_USER header is available. In our sample case here SM_USER=SMUSER1.
4. portalb can further check for further check say if the SMUSER1 mapps to any user in there system if yes consider authentication done move for aurthorization check.

Spring security Support for Siteminder
Spring provide out of box support for SSO/Pre-Authentication scenarios. Refer Spring PreAuthentication documents section16.2.1 for siminder related configurations
Step 1. Create a bean to handel sso/pre-authentication,
<bean id="siteminderFilter" class="org.springframework.security.ui.preauth.header.RequestHeaderPreAuthenticatedProcessingFilter">
<property name="principalRequestHeader" value="SM_USER"/>
<property name="authenticationManager" ref="authenticationManager" />
</bean>

step 2. Specify the above bean to be used as preauth filter. Make following entry in <http.... tag


step 3. Create a Preauth provider bean,
<beans:bean id="preauthAuthProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
<beans:property name="preAuthenticatedUserDetailsService">
<beans:bean id="userDetailsServiceWrapper" class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">

<beans:property name="userDetailsService" ref="myUserDetailsService"/>
</beans:bean>
</beans:property>

<beans:property name="userDetailsChecker" ref="myUserDetailsChecker"/>
</beans:bean>

step 4. Add the preauthAuthProvider to the provider list in the authentication-manager tag.

step 5. Specify org.springframework.security.core.AuthenticationException in web.xml to handel the exceptions and show appropriate view
<error-page>
<exception-type>org.springframework.security.core.AuthenticationException</exception-type>
<location>/myportal/error</location>
</error-page>

Spring framework internal processing and hooks to put extra checks

RequestHeaderPreAuthenticatedProcessingFilter- Handles the request ,
1. checks if the header is not available throws the PreAuthenticatedCredentialsNotFoundException.
2. Iterates over the providers, as we have specified preauthAuthProvider on the top of provider list this is the first provider to be evaluated.
preauthAuthProvider calls the loadUserByUsername function of myUserDetailsService.
Note -This is the point to perform any extra check on the value coming in from the header and evaluate if value in header maps to a user in our system.
Typical implementation is

public UserDetails loadUserByUsername(String smHeadervalue) throws UsernameNotFoundException, DataAccessException {

// find it the user in my system maps to smHeadervalue
//if user is null throw exception
if (user == null) {
throw new UsernameNotFoundException("No such user");
}
return user;
}

3.Next the frame work call check function of the myUserDetailsChecker. As now we know the user exist in our system, check for various states as per your requirement ,throw exception to abort and show the error page.
This step is optional and can be avoided by removing from preauthprovider configuration.


public void check(UserDetails user) {
if (!user.isAccountNonLocked()) {
throw new LockedException( "User account is locked", user);
}
if (!user.isEnabled()) {
throw new DisabledException( "User is disabled", user);
}
if (!user.isAccountNonExpired()) {
throw new AccountExpiredException("User account has expired", user);
}

}
4. if no exception is thrown in the above steps (Authentication is successfull) , user will be checked for aurthorization . If the user hae appropriate roles
the requested page will be displayed.