Wednesday, February 16, 2011

Spring Security For vaadin

I found that implementing security in vaadin is not easy as in normal Spring MVC application. So I created this simple project with spring form based authentication.

I used maven to create the project with vaadin-archetype-clean .

1. Run mvn archetype:generate and select 14 to create project with vaadin-archetype-clean. I used mvn 3.0.2.
2. Run mvn jetty:run to start your web application. Yeah ... jetty will start the web application, you no need a separate web server for this. If you need run mvn package. it will create the war file and you can deploy it in your preferred java web server.
3. Add spring securtiy dependencies to pom.xml.
 <dependency>
     <groupId>org.springframework.security</groupId>
     <artifactId>spring-security-web</artifactId>
     <version>3.0.0.RELEASE</version>
 </dependency>

 <dependency>
     <groupId>org.springframework.security</groupId>
     <artifactId>spring-security-config</artifactId>
     <version>3.0.0.RELEASE</version>
 </dependency>

 <dependency>
     <groupId>jstl</groupId>
     <artifactId>jstl</artifactId>
     <version>1.1.2</version>
 </dependency>

4. I used spring form based authentication, so we can create custom login and error page with and you need to configure them in spring security xml.

<http auto-config='true'>
  <intercept-url pattern="/jsp/login*" access="IS_AUTHENTICATED_ANONYMOUSLY" />
  <intercept-url pattern="/jsp/login_error*" access="IS_AUTHENTICATED_ANONYMOUSLY" />
  <intercept-url pattern="/**" access="ROLE_USER" />
  <form-login login-page='/jsp/login' authentication-failure-url="/jsp/login_error" />
 </http>

 <authentication-manager>
  <authentication-provider>
   <user-service>
    <user name="jimi" password="a" authorities="ROLE_USER, ROLE_ADMIN" />
    <user name="bob" password="b" authorities="ROLE_USER" />
   </user-service>
  </authentication-provider>
 </authentication-manager>


 <global-method-security pre-post-annotations="enabled" />

5. Configure web.xml as below.
<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>
      /WEB-INF/spring-sec.xml
      /WEB-INF/app-context.xml
  </param-value>

</context-param>

<servlet>
  <servlet-name>login</servlet-name>
  <jsp-file>/jsp/login.jsp</jsp-file>
</servlet>

<servlet>
  <servlet-name>login_error</servlet-name>
  <jsp-file>/jsp/login_error.jsp</jsp-file>
</servlet>

<servlet-mapping>
  <servlet-name>login</servlet-name>
  <url-pattern>/jsp/login</url-pattern>
</servlet-mapping>

<servlet-mapping>
  <servlet-name>login_error</servlet-name>
  <url-pattern>/jsp/login_error</url-pattern>
</servlet-mapping>

<servlet>
  <servlet-name>Vaadin Application Servlet</servlet-name>
  <servlet-class>kws.vaadin.MyVaadinApplication</servlet-class>
</servlet>

<servlet-mapping>
  <servlet-name>Vaadin Application Servlet</servlet-name>
  <url-pattern>/*</url-pattern>
</servlet-mapping>

<listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<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>

6. My login.jsp is below
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<div align="center">
Login here
<form action="/vaadin-sec/j_spring_security_check" method="post">
<table>
  <tr>
      <td>
          User
      </td>
      <td>
          <input name="j_username">
      </td>
  </tr>
  <tr>
      <td>
          Password
      </td>
      <td>
          <input type="password" name="j_password"/>
      </td>
  </tr>
  <tr>
      <td>
          <input type="submit" value="login">
      <td>
  </tr>
</table>
</form>
</div>
</body>
</html>

7. Now Add the main applicaton Servlet.

package kws.vaadin;

import java.io.IOException;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.vaadin.Application;
import com.vaadin.terminal.gwt.server.AbstractApplicationServlet;

public class MyVaadinApplication extends AbstractApplicationServlet
{
private WebApplicationContext appContext;
private Class<? extends Application> applicationClass;

@Override
protected Application getNewApplication(HttpServletRequest httpServletRequest) throws ServletException {
    System.out.println("Creating a new application");
    MainApplication mMa = (MainApplication) appContext.getBean("applicationBean");
    mMa.setWebApplicationContext(appContext);
    return  mMa;
}

@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    super.service(request, response);    //To change body of overridden methods use File | Settings | File Templates.
}

@Override
public void init(ServletConfig servletConfig) throws ServletException {
    super.init(servletConfig);    //To change body of overridden methods use File | Settings | File Templates.
    appContext = WebApplicationContextUtils.getWebApplicationContext(servletConfig.getServletContext());
}

@Override
protected Class<? extends Application> getApplicationClass() throws ClassNotFoundException {
    return MainApplication.class;
}
}

8. This is the application class.

package kws.vaadin;

import java.util.Collection;

import kws.vaadin.security.Roles;
import kws.vaadin.service.SecuredService;

import com.vaadin.Application;
import com.vaadin.ui.Button;
import com.vaadin.ui.Label;
import com.vaadin.ui.Window;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.security.access.annotation.Secured;
import org.springframework.security.access.expression.SecurityExpressionRoot;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.access.expression.WebSecurityExpressionRoot;
import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestWrapper;
import org.springframework.stereotype.Component;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

@Component("applicationBean")
@Scope("prototype")
public class MainApplication extends Application {

@Autowired
private SecuredService securedService;

public WebApplicationContext appContext;

@Override
public void init() {
    Window window;
    window = new Window("My Vaadin Application");
    window.addComponent(new HeaderWindow(this));
    window.addComponent(new BodyWindow(this));
    window.addComponent(new FooterWindow(this));
    setMainWindow(window);
}

public boolean hasAnyRole(String ... roles){
    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    Collection<GrantedAuthority> authorities = authentication.getAuthorities();
    for(GrantedAuthority authority: authorities){
        for(String role: roles){
            if(role.equals(authority.getAuthority())){
                return true;
            }
        }
    }
    return false;
}

public void setWebApplicationContext(WebApplicationContext appContext){
    this.appContext = appContext;
}

}


9. Ok Done. You can find complete project from 'git clone git@github.com:changit/vaadin-spring-sec.git'

Saturday, February 5, 2011

SCWCD short Notes

Bean should have a default empty
constructor ? yes it is


what is the default scope for a java bean and can it see to included page. default is page. if it is

<error-page> tag. can we include
a error type here, you need provide the <error-code> or
<exception-type> with <location> tag


Sorry about this, I am not continuing this note because now I have done the exam. I was able to get 95 marks. I found more than half of the questions were in whislab exam simulator, So this exam can be easily pass to any one who can memorise that questions. This exams should not be like this. It should give different questions that we can't find within simulators.


Tuesday, February 1, 2011

Java web services

We can use fallowing tools to create and test web services.

CXF web services
Spring web services

SoapUi to test web services.

for spring follow this

http://justcompiled.blogspot.com/2010/09/building-web-service-with-spring-ws.html