springmvc + shiro + Jpa integration (1) login and logout

1. Construction of the underlying environment

 

1. Project structure:



 

 

2. shrio's maven dependency

 

<dependency>
			<groupId>commons-logging</groupId>
			<artifactId>commons-logging</artifactId>
			<version>1.1.3</version>
		</dependency>
		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-core</artifactId>
			<version>1.2.2</version>
		</dependency>
		<dependency>  
		    <groupId>org.apache.shiro</groupId>  
		    <artifactId>shiro-web</artifactId>  
		    <version>1.2.2</version>  
		</dependency>  
		<dependency>  
		    <groupId>org.apache.shiro</groupId>  
		    <artifactId>shiro-spring</artifactId>  
		    <version>1.2.2</version>  
		</dependency>  
		<dependency>  
		    <groupId>org.apache.shiro</groupId>  
		    <artifactId>shiro-ehcache</artifactId>  
		    <version>1.2.2</version>  
		</dependency>

3. Configuration of web.xml

 

 

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
			xmlns="http://java.sun.com/xml/ns/javaee"
			xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
			xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
			http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
  <display-name>TestShiro</display-name>
  <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
  </context-param>
     <!-- To prevent java.beans.Introspector memory leak, it should be configured in front of ContextLoaderListener -->  
    <!-- For a detailed description, see http://blog.csdn.net/jadyer/article/details/11991457 -->  
    <listener>  
        <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>  
    </listener>  
    
     <!-- Instantiate the Spring container-->  
    <!-- When the application starts, the listener is executed, it will read the Spring related configuration files, and by default it will look for applicationContext.xml in WEB-INF -->  
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    
    <!-- configure encoding filter-->
    <filter>
        <filter-name>characterEncodingFilter</filter-name>
        <filter-class>
            org.springframework.web.filter.CharacterEncodingFilter
        </filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>characterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
    <!-- Configure the Shiro filter, first let Shiro filter the requests received by the system-->  
    <!-- Here filter-name must correspond to <bean id="shiroFilter"/> defined in applicationContext.xml -->  
    <!-- Use [/*] to match all requests to ensure that all controllable requests are filtered by Shiro -->  
    <!-- This filter-mapping is usually placed first (i.e. before other filter-mappings) to ensure it is the first in the filter chain to work -->  
    <filter>  
        <filter-name>shiroFilter</filter-name>  
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>  
        <init-param>  
            <!-- The default value of this value is false, which means that the life cycle is managed by SpringApplicationContext. If set to true, it means that it is managed by ServletContainer -->  
            <param-name>targetFilterLifecycle</param-name>  
            <param-value>true</param-value>  
        </init-param>  
    </filter>  
    <filter-mapping>  
        <filter-name>shiroFilter</filter-name>  
        <url-pattern>/*</url-pattern>  
    </filter-mapping>  
    
    
    
    <!-- SpringMVC core dispatcher-->
    <servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>
            org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-mvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>


    <welcome-file-list>
        <welcome-file>/index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

 

 

2. Configuration of applicationContext.xml

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:cache="http://www.springframework.org/schema/cache"
    xmlns:jaxws="http://cxf.apache.org/jaxws"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa"
    xsi:schemaLocation="
                    http://www.springframework.org/schema/beans
                    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
                    http://www.springframework.org/schema/tx
                    http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
                    http://www.springframework.org/schema/aop
                    http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
                    http://www.springframework.org/schema/context      
                    http://www.springframework.org/schema/context/spring-context-3.1.xsd
                    http://www.springframework.org/schema/cache
                    http://www.springframework.org/schema/cache/spring-cache-3.1.xsd
                    http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
                    http://www.springframework.org/schema/data/jpa
                    http://www.springframework.org/schema/data/jpa/spring-jpa.xsd"
                    default-lazy-init="true">

    <context:component-scan base-package="com.libm" >
    	 <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />   
	</context:component-scan>        
    <context:property-placeholder location="classpath:jdbc.properties"/>
    <!-- c3p0 connection-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
		<property name="driverClass" value="${jdbc.driverClassName}" />
		<property name="jdbcUrl" value="${jdbc.url}" />
		<property name="user" value="${jdbc.username}" />
		<property name="password" value="${jdbc.password}" />
	</bean>
	
    <!-- JPA entity manager factory -->
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="jpaVendorAdapter" ref="hibernateJpaVendorAdapter" />
        
        <!-- Add a custom package path, this way of writing does not need to configure persistence.xml, it will automatically scan entity classes-->
        <property name="packagesToScan" value="com.libm.domain" />

        <property name="jpaProperties">
            <props>
                <prop key="hibernate.current_session_context_class">thread</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop><!-- validate/update/create -->
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">false</prop>
                
                <!-- Naming rules for creating tables-->
                <!-- <prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop> -->
                
            </props>
        </property>
    </bean>
    
    <!-- Set JPA implementation vendor specific properties-->
    <bean id="hibernateJpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
        <property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect"/>
    </bean>
    
    <!-- Jpa transaction configuration-->
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"/>
    </bean>

    <!-Spring Data Jpa placement->
    <jpa:repositories base-package="com.libm"  transaction-manager-ref="transactionManager" entity-manager-factory-ref="entityManagerFactory"/>
    
    <!-- Use annotation to define transactions-->
    <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />
    
    
    
    <!-- /////////////////////////////////////////////////////////////////////////////////// -->
    <!-- shiro -->
    
    <bean id="myShiro" class="com.libm.service.MyShiro"></bean>
     <!-- Configure Rights Manager-->  
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">    
        <!-- ref corresponds to the realm MyShiro we wrote -->  
        <property name="realm" ref="myShiro"/>    
        <!-- Use the cache manager configured below -->  
        <property name="cacheManager" ref="cacheManager"/>    
    </bean>  
      
    <!-- Configure shiro's filter factory class, id- shiroFilter should be consistent with the filter we configured in web.xml -->  
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">   
        <!-- Invoke our configured permission manager-->   
        <property name="securityManager" ref="securityManager"/>   
        <!-- Configure our login request address-->   
        <property name="loginUrl" value="/login.do"/>    
        <!-- Configure our jump address after successful login on the login page. If you visit a non-/login address, jump to the address you visit -->  
        <property name="successUrl" value="/home.do"/>    
        <!-- If the resource you request is no longer within your permission scope, jump to /403 request address -->  
        <!-- <property name="unauthorizedUrl" value="/403"/> -->    
        <!-- Permission configuration-->  
        <property name="filterChainDefinitions">    
            <value>    
                <!-- anon means this address does not require any permission to access -->  
                /index.do = anon
                /login.do = authc
                /home.do = authc
            </value>    
        </property>    
    </bean>  
    
      
    <bean id="cacheManager" class="org.apache.shiro.cache.MemoryConstrainedCacheManager" />    
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />   
 
    
</beans>

 

 

 

3. Configuration of spring-mvc.xml

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
                http://www.springframework.org/schema/beans
                http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
                http://www.springframework.org/schema/context
                http://www.springframework.org/schema/context/spring-context-3.1.xsd
                http://www.springframework.org/schema/mvc
                http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
                http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd" >
    
    <!-- Start springMVC annotation-->
    <mvc:annotation-driven/>
    <context:component-scan base-package="com.libm">
      	<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />   
    	<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service" />
    </context:component-scan>
   
    
    <!-- custom tiles -->
    <bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
    	<property name="definitions">
    		<list>
    			<value>classpath:titles.xml</value>
    		</list>
    	</property>
    </bean>
    <bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
    	<property name="viewClass">
    		<value> org.springframework.web.servlet.view.tiles3.TilesView </value>
    	</property>
    </bean>
    
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
        <property name="prefix" value="/" />
        <property name="suffix" value=".jsp" />
    </bean>
    
    <!-- <mvc:interceptors>
    	<mvc:interceptor>
    		<mvc:mapping path="/*.do"/>
    		<mvc:exclude-mapping path="/index.do"/>
    		<mvc:exclude-mapping path="/login.do"/>
    		<bean class="com.libm.interceptor.LoginInterceptor" />
    	</mvc:interceptor>
    </mvc:interceptors> -->
    
    <!-- Static resource loading -->
    <mvc:resources location="/css/" mapping="/css/**" />
    <mvc:resources location="/js/" mapping="/js/**"/>
    <mvc:resources location="/images/" mapping="/images/**" />
    
</beans>

 

 

1. Realization

1. Entity class

 

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;


@Entity
public class User {
	private Integer id;  
    private String username;  
    private String password;  
    
    
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	
	
    
}

 

2. Customize MyShiro authentication

import java.util.List;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


import com.libm.domain.User;

@Service
public class MyShiro extends AuthorizingRealm {
	
	@Autowired
	private UserService userService;
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

		
		return null;
	}

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
		// UsernamePasswordToken object is used to store submitted login information
		UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
		String username = token.getUsername();
		
		String password = String.valueOf(token.getPassword());
		// Find out if there is this user, query the database here
		User user = userService.chekLogin(username,password);
		if (user != null) {
			// If it exists, store this user in the login authentication info
			return new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), getName());
		}
		return null;
	}

}

 

 

 

 

3、index.jsp

 

<%@ 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>Login</title>
<script type="text/javascript" src="js/jquery-1.8.3.min.js"></script>

</head>
<body>
<form action="login.do" method="post">
	<div align="center">
		<table>
			<tr>
				<td>username</td>
				<td><input type="text" name="username"/> </td>
			</tr>
			<tr>
				<td>password</td>
				<td><input type="password" name="password"/> </td>
			</tr>
		</table>
		<button type="submit" id="loginBtn">login</button>
	</div>
	
</form>
</body>
</html>

 

 

4、LoginController

package com.libm.controller;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import com.libm.domain.User;

@Controller
public class LoginController {
	
	@RequestMapping(value="login")
	public String login(User user){
		Subject subject = SecurityUtils.getSubject();
		UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(), user.getPassword());
		try{
			token.setRememberMe(true);
			subject.login(token);
			return "redirect:/home.do";
		}catch(Exception e){
			return "redirect:/index.do";
		}
		
	}
	
	@RequestMapping(value="home")
	public ModelAndView home(){
		ModelAndView mv = new ModelAndView("home");
		
		return mv;
	}
	@RequestMapping(value="index")
	public ModelAndView index(){
		ModelAndView mv = new ModelAndView("index");
		
		return mv;
	}
	@RequestMapping(value="logout")
	public String logout(){
		Subject subject = SecurityUtils.getSubject();
		subject.logout();
		return "redirect:/index.do";
	}
	
	
	
	
}

 

 

 

 

 

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326227442&siteId=291194637