Spring Security

I have written about integrating Spring Security with Spring MVC earlier – https://javashine.wordpress.com/tag/spring-security/

Here is another step by step by instructions. This blog post assumes you already have a Spring MVC working in your workspace. This one uses annotation based configurations.

I have a simple test web application with two URLs.

/ (root URL)

/add_expense

While I’ll leave my / url unprotected, I want to secure /add_expense. Here is how we do it.

Adding Spring Security to Spring4 MVC

This is my project structure.

springmvc_spring_security

I wrote very simple MVC controller and it is working.

Add the following to Maven project dependencies.

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- Security -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${spring.security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${spring.security.config.version}</version>
</dependency>

Under properties I’ve added this.

<spring.security.version>4.0.0.RELEASE</spring.security.version>

<spring.security.config.version>4.0.0.RELEASE</spring.security.config.version>

Following is the controller I’m going to secure. I’ll leave / open and protect /add_expense

springmvc_spring_security_1

Define a Spring security configuration. I have only one user admin.


package org.grassfield.gaja;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("admin").password("password").roles("ADMIN");
}

@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/add**").access("hasRole('ROLE_ADMIN')")
.and().formLogin();
}
}

Initialize security filter chain.


package org.grassfield.gaja;

import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;

public class SpringSecurityInitializer extends
AbstractSecurityWebApplicationInitializer {

}

Load the spring security to Spring MVC Application config. Check the highlighted path.

springmvc_spring_security_2

 

And finally load everything

package org.grassfield.gaja;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class SpringMvcInitializer extends
AbstractAnnotationConfigDispatcherServletInitializer {

@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { ApplicationContextConfig.class };
}

@Override
protected Class<?>[] getServletConfigClasses() {
return null;
}

@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}

Capture

 

Capture

 

Capture

Capture

Way to go!

And, finally, here is the pic of the day.

CYmwbxbUQAAWCGH.jpg large
Learning something is a time machine that can bring you back to your school days!

Happy Pongal.
Happy Sankaranti.Happy Utarayan.

Advertisements

Spring 4 MVC + Spring 3 Security + Hibernate 4 – integration with java annotations

Dear folks,

This may be the final post in the Spring 4 environment setup. We have already completed 3 out of 4 stages.

Last but not least, we do the hibernate integration in this post. Since ibatis is not doing good, Hibernate is monopolize the ORM market. Hence hibernate will be used in our next project. Here comes the integration. This tutorial assumes you have completed all the above steps and have the web project ready now.

hibernate.properties

Save this property file to the class path. I usually save at /src folder

jdbc.driverClassName = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://localhost:3306/vriksha
jdbc.username = root
jdbc.password =
hibernate.dialect = org.hibernate.dialect.MySQLDialect
hibernate.show_sql = true
hibernate.format_sql = true

Changes to WebMvcConfigurerAdapter

We are doing important changes to the MVC Configurer. Please check all the methods and beans except getViewResolver(), which exists from the beginning.

package org.grassfield.conf;

import java.util.Properties;

import javax.sql.DataSource;

import org.apache.commons.dbcp2.BasicDataSource;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = { "org.grassfield.conf", "org.grassfield.common.dao", "org.grassfield.common.entity" })
@EnableTransactionManagement
@PropertySource(value={"classpath:hibernate.properties"})
public class ApplicationContextConfig extends WebMvcConfigurerAdapter {
    
    @Autowired
    private Environment environment;

    @Bean(name = "viewResolver")
    public InternalResourceViewResolver getViewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setPrefix("/WEB-INF/views/");
        viewResolver.setSuffix(".jsp");
        return viewResolver;
    }

    @Bean(name = "datasource")
    public static DataSource dataSource() {
        BasicDataSource ds = new BasicDataSource();
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUrl("jdbc:mysql://localhost:3306/license_prod_2");
        ds.setUsername("root");
        ds.setPassword("");

        return ds;
    }
    
    @Bean
    public LocalSessionFactoryBean sessionFactory(){
        LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
        sessionFactory.setDataSource(dataSource());
        sessionFactory.setPackagesToScan(new String[]{"org.grassfield.common.entity"});
        sessionFactory.setHibernateProperties(hibernateProperties());
        return sessionFactory;
        
    }
    
    private Properties hibernateProperties() {
        Properties properties = new Properties();
        properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect"));
        properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql"));
        properties.put("hibernate.format_sql", environment.getRequiredProperty("hibernate.format_sql"));
        return properties;        
    }
    
    @Bean
    @Autowired
    public HibernateTransactionManager transactionManager(SessionFactory sessionFactory){
        HibernateTransactionManager tx = new HibernateTransactionManager();
        tx.setSessionFactory(sessionFactory);
        return tx;
    }
}

 

Changes to HomeController

HomeController exists from the beginning. We are changing the method which handles the /protect url. This is secured by Spring Security. Please note the DAO call and ModelAndView population. Wiring Controller with a DAO is a bad practice. Don’t do it in your project, dear coders!

@RequestMapping("/protect")
    public ModelAndView handleProtectedRequest(HttpServletRequest arg0,
            HttpServletResponse arg1) throws Exception {
        List<UserRole> userRoleList = this.userRoleDAO.list();
        System.out.println(userRoleList);
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("protect");
        modelAndView.addObject("userRoleList", userRoleList);
        return modelAndView;
    }

 

New DAO tier

We will be getting a list of user roles. Following is the interface for UserRoleDAO.

package org.grassfield.common.dao;

import java.util.List;

import org.grassfield.common.entity.UserRole;

public interface IUserRoleDAO {
    public List<UserRole> list();
}

 

The implementation goes like this. Please note the annotations.

package org.grassfield.common.dao;

import java.util.List;

import org.grassfield.common.entity.UserRole;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

@Repository
public class UserRoleDAO implements IUserRoleDAO {
    @Autowired
    private SessionFactory sessionFactory;
    
    public SessionFactory getSessionFactory() {
        return sessionFactory;
    }

    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    @Override
    @Transactional
    public List<UserRole> list() {
        Session currentSession = this.sessionFactory.getCurrentSession();
        @SuppressWarnings("unchecked")
        List<UserRole> list = currentSession.createQuery("From UserRole").list();
        return list;
    }
}

Entity/Model

And finally, our entity class is given below. Please note the annotations.

/*
 * Package: com.eginnovations.common.entity 
 * FileName: UserRole.java
 * (c) 2010 eG Innovations private limited
 * 
 * Created by pandian on May 27, 2010 3:15:36 PM
 */
package org.grassfield.common.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

/**
 * The Class UserRole.
 */
@Entity
@Table(name="user_role")
public class UserRole {
    @Id @GeneratedValue
    @Column(name="id")
    private Long id;
    
    @Column(name="NAME")
    private String name;
    
    @Column(name="EMAIL_PERMISSION")
    private String emailPermission;
    
    /**
     * Gets the id.
     * 
     * @return the id
     */
    public Long getId() {
        return id;
    }
    
    /**
     * Sets the id.
     * 
     * @param id the new id
     */
    public void setId(Long id) {
        this.id = id;
    }
......
.....

 

Now load the protected URL! You will see the list of the user roles.

spring4_hibernate4

Okay, This is more or less ready now. I need to do some refactoring. We can start building it by next weekend. Till then Bye!

spring-tool-suite-project-logo java8-logo image00110 Apache-Tomcat-logo

 

 

Spring 4 MVC and JDBC authenticated Spring Security – 100% java annotation based configuration

I feel pleasure to introduce you another post on this spring 4 development environment series. So far we have done the following steps.

This post would be an extension to my earlier post Spring 4 MVC and Spring Security 100% java annotation based configuration. We have used in-memory authentication, which is suitable for a beginner. But my next project has already a database designed and I need to authenticate against it. So here would be the jdbc based authentication. Please add MySQL and Commons DBCP in your maven dependencies.

Modify WebSecurityConfig

The in-memory configuration has been defined in WebSecurityConfig.java in our earlier example. Lets modify it slightly to handle the authentication with JDBC. Pls look at the method public void configAuthentication(AuthenticationManagerBuilder auth).

package org.grassfield.conf;

import org.apache.commons.dbcp2.BasicDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;

@SuppressWarnings("deprecation")
@Configuration
@EnableWebMvcSecurity
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    /*@Autowired
    private DataSource datasource;*/

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();
        http.authorizeRequests().antMatchers("/", "/home").permitAll()
                .anyRequest().authenticated().and().formLogin()
                .loginPage("/login").permitAll().and().logout().permitAll();
    }

    
    @Autowired
    public void configAuthentication(AuthenticationManagerBuilder auth)
            throws Exception {
        BasicDataSource ds = new BasicDataSource();
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUrl("jdbc:mysql://localhost:3306/vriksha");
        ds.setUsername("root");
        ds.setPassword("");
        
        auth.jdbcAuthentication()
        .dataSource(ds)
        .usersByUsernameQuery(
                "select u.user_name, u.password, true from user_info u, user_role r where u.user_role_id=r.id and u.user_name=?")
        .authoritiesByUsernameQuery(
                "select u.user_name, r.name from user_info u, user_role r where u.user_role_id=r.id and u.user_name=?");
    }
}

Here are the screenshots. jdbc01 jdbc02


spring-tool-suite-project-logo java8-logo image00110 Apache-Tomcat-logo

Spring 4 MVC and Spring Security 100% java annotation based configuration

 

This post would be the continuation of my previous hello-world series for Spring 4. So far we have made a Spring 4 MVC webapp ready without using XML. In this tutorial we shall enable the spring security for the same webapp. I hope it will be easier for you to follow me.

My Earier posts  on the same series

This post will not talk about how to setup spring MVC. Please check my earlier post Spring 4 MVC – 100% annotation based configuration. I assume, the mvc webapp is ready with you before you work on this.

WebSecurityConfigurerAdapter

Specify your webapp security behaviour here. The below config ensures, there is no restriction to access /home requests. Other unauthenticated requests will be forwarded to /login page

package org.grassfield.conf;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;

@SuppressWarnings("deprecation")
@Configuration
@EnableWebMvcSecurity
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();
        http
            .authorizeRequests()
                .antMatchers("/", "/home").permitAll()
                .anyRequest().authenticated()
                .and()
            .formLogin()
                .loginPage("/login")
                .permitAll()
                .and()
            .logout()
                .permitAll();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .inMemoryAuthentication()
                .withUser("user").password("password").roles("USER");
    }
}


Changes to HomeController

Added two more request mappings /login and /protect

package org.grassfield.conf;

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

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class HomeController {
    
    @RequestMapping("/")
    public ModelAndView handleRequest(HttpServletRequest arg0,
            HttpServletResponse arg1) throws Exception {
        return new ModelAndView("home");
    }
    
    @RequestMapping("/login")
    public ModelAndView handleLoginRequest(HttpServletRequest arg0,
            HttpServletResponse arg1) throws Exception {
        return new ModelAndView("login");
    }
    
    @RequestMapping("/protect")
    public ModelAndView handleProtectedRequest(HttpServletRequest arg0,
            HttpServletResponse arg1) throws Exception {
        return new ModelAndView("protect");
    }
}

 

Pls note, we added /protect url!

AbstractSecurityWebApplicationInitializer

Register your security with the web application.

package org.grassfield.conf;

import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;

public class SecurityWebApplicationInitializer extends
AbstractSecurityWebApplicationInitializer {

public SecurityWebApplicationInitializer() {
super(WebSecurityConfig.class);
}

}

spring_security

Home page has the links for the protected pages. Click and see the behaviour!

Hope it helped you!

spring-tool-suite-project-logo java8-logo image00110 Apache-Tomcat-logo

HTTP Status 403 – Expected CSRF token not found. Has your session expired?

Spring security is enabled. But got this error finally.

403_Expected_CSRF_token

Let’s write about this in detail later. As of now, lets disable the csrf check disabled. Please note http.csrf().disable(); below.

 

package org.grassfield.conf;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;

@SuppressWarnings("deprecation")
@Configuration
@EnableWebMvcSecurity
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();
        http
            .authorizeRequests()
                .antMatchers("/", "/home").permitAll()
                .anyRequest().authenticated()
                .and()
            .formLogin()
                .loginPage("/login")
                .permitAll()
                .and()
            .logout()
                .permitAll();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .inMemoryAuthentication()
                .withUser("user").password("password").roles("USER");
    }
}

 

image00110 Apache-Tomcat-logojava8-logo spring-tool-suite-project-logo