It has a lot of differences and developments in Spring Security 3 versus 2, for this I thought to add this article..
The following tutorial will talk about how integrating Spring security 3 with extjs login page.
If you try to execute the application now with a basic applicationContext-security.xml file, the user will be successfully authenticated, but is not going to be redirected. So, we will need to create a filter.
The applicationContext-security will be:
Since we use Spring MVC, we will need to create a controller.
Of course, you can add a link disconnect in the main page. So you need:
1- add in the configuration spring file and under the tag http the following tag:
New features for spring 3.0 here
The following tutorial will talk about how integrating Spring security 3 with extjs login page.
Tools:
- Netbeans 6.9.1
- Spring framework 3.0.2
- Spring security 3.0.4
- Extjs 3.2.1
- Tomcat 6.0.24
Step1:
Create a java web application with netbeans, and add the spring web MVC framework dependency.
Step2:
In the webcontent create a js file named login.js
Ext.onReady(function(){
Ext.QuickTips.init();
var login = new Ext.FormPanel({
labelWidth:80,
url:'j_spring_security_check',
frame:true,
title:'Please Login',
defaultType:'textfield',
width:300,
height:150,
monitorValid:true,
items:[{
fieldLabel:'Username',
name:'j_username',
allowBlank:false
},{
fieldLabel:'Password',
name:'j_password',
inputType:'password',
allowBlank:false
}],
buttons:[{
text:'Login',
formBind: true,
handler:function(){
login.getForm().submit({
method:'POST',
success:function(){
Ext.Msg.alert('Status', 'Login Successful!', function(btn, text){
if (btn == 'ok'){
window.location = 'main.htm';
}
});
},
failure:function(form, action){
if(action.failureType == 'server'){
obj = Ext.util.JSON.decode(action.response.responseText);
Ext.Msg.alert('Login Failed!', obj.errors.reason);
}else{
Ext.Msg.alert('Warning!', 'Authentication server is unreachable : ' + action.response.responseText);
}
login.getForm().reset();
}
});
}
}]
});
login.render('login');
});
Step3:If you try to execute the application now with a basic applicationContext-security.xml file, the user will be successfully authenticated, but is not going to be redirected. So, we will need to create a filter.
public class RecrutementAuthProcessingFilter extends UsernamePasswordAuthenticationFilter {
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, Authentication authResult) throws IOException, ServletException {
SavedRequestAwareAuthenticationSuccessHandler srh = new SavedRequestAwareAuthenticationSuccessHandler();
this.setAuthenticationSuccessHandler(srh);
srh.setRedirectStrategy(new RedirectStrategy() {
@Override
public void sendRedirect(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse, String s) throws IOException {
//do nothing, no redirect
}
});
super.successfulAuthentication(request, response, authResult);
HttpServletResponseWrapper responseWrapper = new HttpServletResponseWrapper(response);
Writer out = responseWrapper.getWriter();
out.write("{success:true}");
out.close();
}
@Override
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException {
super.unsuccessfulAuthentication(request, response, failed);
HttpServletResponseWrapper responseWrapper = new HttpServletResponseWrapper(response);
Writer out = responseWrapper.getWriter();
out.write("{success:false}");
out.close();
}
}
UsernamePasswordAuthenticationFilter(AuthenticationProcessingFilter prior to Spring Security 3.0) processes an authentication form submission. Called login forms must present two parameters to this filter: a username (j_username) and password (j_password).The applicationContext-security will be:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd">
<global-method-security pre-post-annotations="enabled"/>
<http auto-config='false' entry-point-ref="authenticationEntryPoint">
<intercept-url pattern="/index*" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<intercept-url pattern="/js/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<intercept-url pattern="/main*" access="ROLE_USER" />
<custom-filter position="FORM_LOGIN_FILTER" ref="authenticationFilter" />
</http>
<beans:bean id="authenticationFilter" class="com.blog.dev.security.RecrutementAuthProcessingFilter">
<beans:property name="authenticationManager" ref="authenticationManager" />
</beans:bean>
<beans:bean id="authenticationEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<beans:property name="loginFormUrl" value="/index.jsp" />
</beans:bean>
<!--
Usernames/Passwords are
moez/moez
test/test
-->
<authentication-manager alias="authenticationManager" >
<authentication-provider>
<password-encoder hash="md5"/>
<user-service>
<user name="moez" password="f69471ca2c42621b8b8e731b2b4446e4" authorities="ROLE_SUPERVISOR, ROLE_USER, ROLE_TELLER" />
<user name="test" password="098f6bcd4621d373cade4e832627b4f6" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
</beans:beans>
Step4:
Now you need to create a jsp page 'main.jsp' in order to call it when you are successfully authenticated.Since we use Spring MVC, we will need to create a controller.
public class MainController extends MultiActionController{
public ModelAndView main(HttpServletRequest request,
HttpServletResponse response) throws Exception {
return new ModelAndView("main.jsp");
}
}
Step5:
In the dispatcher-servlet.xml add the following line:
<bean name="/*.htm" class="com.blog.dev.controller.MainController"/>
Step6:
In the web.xml add the following code:
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Step7:
Deploy your application under tomcat, you can test it with test/test. Of course, you can add a link disconnect in the main page. So you need:
1- add in the configuration spring file and under the tag http the following tag:
<logout/>
2- add in main.jsp the link disconnect:
<a href="j_spring_security_logout">Logout</a>
Source code (Netbeans project) until http://spring-extjs.googlecode.com/svn/trunk/
Excellent work!!!
ReplyDeleteCan you provide something on Session Timeout using Spring Security 3.0?
Of course, just redirect the user to an appropriate URL by adding into <http> the following tag: <session-management invalid-session-url="/yourSessionTimeoutPage.htm" />
ReplyDeletewhen i use tag in context-security.xml:
ReplyDeletei receive the following error:
Context initialization failed
org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Security namespace does not support decoration of element [http]
Offending resource: ServletContext resource [/WEB-INF/hrp-applicationContext-security.xml]
please see my applicationContaxt-security.xml file below:
Ok, try to use the following namespaces:
ReplyDeletexmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd">
getting the following error using above namespaces:
ReplyDeleteNested in org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 15 in XML document from ServletContext resource [/WEB-INF/hrp-applicationContext-security.xml] is invalid; nested exception is org.xml.sax.SAXParseException: cvc-elt.1: Cannot find the declaration of element 'beans'.:
org.xml.sax.SAXParseException: cvc-elt.1: Cannot find the declaration of element 'beans'.
at org.apache.xerces.parsers.DOMParser.parse(DOMParser.java:267)
unable to copy xml contents here. so, may i have you email id, so i can send you my applicationContaxt-security.xml???
You can use the following link to post your xml content:
ReplyDeletehttp://www.accessify.com/tools-and-wizards/developer-tools/quick-escape/default.php
But, you can start from my context-security.xml
<!-- Start of Session Timeout configuration -->
ReplyDelete<bean id="sessionMgmtFilter" class="org.springframework.security.web.session.SessionManagementFilter" >
<constructor-arg ref="securityContextRepository" />
<sec:http>
<sec:session-management invalid-session-url="/actions/login" />
</sec:http>
</bean>
<bean id="concurrencyFilter"
class="org.springframework.security.web.session.ConcurrentSessionFilter">
<property name="sessionRegistry" ref="sessionRegistry" />
<property name="expiredUrl" value="/actions/login" />
</bean>
<bean id="sas"
class="org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy">
<constructor-arg name="sessionRegistry" ref="sessionRegistry" />
<property name="maximumSessions" value="1" />
</bean>
<bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl" />
<!-- End of Session Timeout configuration -->
it's ok now?
ReplyDeleteNot yet... I am using the below namespaces:
ReplyDelete<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:sec="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
try this:
ReplyDelete<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd">
<beans:bean id="sessionMgmtFilter" class="org.springframework.security.web.session.SessionManagementFilter" >
<beans:constructor-arg ref="securityContextRepository" />
<http>
<session-management invalid-session-url="/actions/login" />
</http>
</beans:bean>
<beans:bean id="concurrencyFilter"
class="org.springframework.security.web.session.ConcurrentSessionFilter">
<beans:property name="sessionRegistry" ref="sessionRegistry" />
<beans:property name="expiredUrl" value="/actions/login" />
</beans:bean>
<beans:bean id="sas"
class="org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy">
<beans:constructor-arg name="sessionRegistry" ref="sessionRegistry" />
<beans:property name="maximumSessions" value="1" />
</beans:bean>
<beans:bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl" />
This comment has been removed by the author.
ReplyDeleteafter removing <http> element from applicationContext-security.xml, session timeout work but does not redirect to invalidSessionUrl.
ReplyDeleteTried overriding SessionManagementFilter also...
what might be the problem?
Please use my applicationContext-security.xml posted in the blog and add the tag session-managemente. It will be ok.
ReplyDeleteHi, Can you post the eclipse project?
ReplyDeleteBrowsing the will be more understandable.
Thanks for the article.
Netbeans project until http://spring-extjs.googlecode.com/svn/trunk/
ReplyDeletegreat article on spring security
ReplyDeletewhen login failed, failure method of form submit can't pop up the error message even if i changed the code this code in RecrutementAuthProcessingFilter.java;
ReplyDeleteprotected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed)
throws IOException, ServletException {
super.unsuccessfulAuthentication(request, response, failed);
HttpServletResponseWrapper responseWrapper = new HttpServletResponseWrapper(response);
Writer out = responseWrapper.getWriter();
// out.write("{success:false}");
out.write("{success:false,errors: { reason: 'Login failed. Try again.' }}");
out.close();
}