After a spending about 2 days researching on the HttpRequestMethodNotSupportedException thrown when running AbstractController.handleRequest in my test, I decided to view spring source code to see the real cause of this problem.

The problem was when creating MockHttpServletRequest, it doesn't set a default method name. To solve this problem, I simply added a request method type on the mock request object. See the following code:

request = new MockHttpServletRequest();
request.setMethod("POST");

Customizing spring security

One problem I encountered while trying to configure spring security is customizing it based on my own preferences. The default setup uses j_spring_security_login as the login page and j_spring_security_logout as the logout page. Although the default setup is enough to create a secured application, its not what I wanted. What I want is to configure spring security based on my own preferences, based on my own rules.

This is the login controller that i customized :

public class LoginController extends AbstractController {

@Override
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
ModelAndView mav = new ModelAndView();

SecurityContext securityContext = SecurityContextHolder.getContext();
Authentication auth = securityContext.getAuthentication();
String login = request.getParameter("login");

if(login != null && login.equals("1")) {
GrantedAuthority grantedAuthority = new GrantedAuthorityImpl("ROLE_ADMIN");
UserAuthentication userAuth = new UserAuthentication("rey", "q", new GrantedAuthority[]{grantedAuthority});
securityContext.setAuthentication(userAuth);
}

return mav;
}
}


And the applicationContext-security.xml :
<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="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-2.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.xsd">

<security:global-method-security secured-annotations="enabled">
</security:global-method-security>

<security:http auto-config="true" session-fixation-protection="none">
<!-- <intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" /> -->

<security:intercept-url pattern="/login.htm" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern="/css/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern="/images/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />


<security:intercept-url pattern="/**" access="ROLE_ADMIN" />
<security:remember-me user-service-ref="jdbcDaoImpl" />
<security:form-login login-page="/login.htm"/>
</security:http>

<security:authentication-provider user-service-ref="jdbcDaoImpl" />

</beans>

You can use http://tuckey.org/urlrewrite/ to rewrite the url of your java web application. This works when used with any java framework or even plain servlet.

I was trying to integrate spring security on my application but got a bit disappointed with it. Comparing it to jboss rules engine (drools), I find spring security a bit harder to be understood. The documentation and example is not very clear, most of the example on the documentation covers only xml based configuration and It didnt cover programmatic usage of the library.

Although its too early to conclude which one is better, right now I feel that jboss rules engine is a better choice since its much easier to use and understand. But anyway I'm gonna continue playing around with spring security because I may have missed something.

rolling back transaction

Annotating the method with the following:

@Transactional(readOnly=false, propagation=Propagation.NESTED)

will cause the transaction to wait until all sub transaction is completed. If any of the sub transaction fails, the global transaction will fail as well causing everything to be rolled back

After spending a couple of hours configuring this kind of setup, I was able to make my application run. Though there are some noticeable changes to when setting up application using struts/spring/hibernate or seam/ejb/jsf, I was able to learn some few things and they are the following:

1. using stereo type annotations (@Service, @Repository) is okay but not @Controller because it doesn't offer a very flexible way to configure controllers.

2. When using hibernate as persistence provider, it uses javassist to modify the java byte code.

3. persistence.xml should be placed on classes/META-INF not on web/META-INF (for tomcat users) because some very weird thing happens

4. Using spring mvc is much simpler than struts because the dependencies are not too many and by default a spring application context is already available when initializing a dispatcher servlet.

5. No need to use load time weaver when using hibernate as persistence provider.

Newer Posts Older Posts Home

Blogger Template by Blogcrowds