shiro的注册和登陆

Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码学和会话管理。

以下将详细讲解用户的验证(用户登陆)以及用户的注册(用户注册不是shiro的功能,这里用户注册用到了shiro的密码加密)

1.导包

在maven的pom.xml文件下导入shiro的相关包

			<!-- 二级缓存ehcache -->
		<dependency>
			<groupId>net.sf.ehcache</groupId>
			<artifactId>ehcache</artifactId>
			<version>2.10.4</version>
		</dependency>
             <!-- shiro -->
		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-core</artifactId>
			<version>${shiro-version}</version>
		</dependency>
		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-ehcache</artifactId>
			<version>${shiro-version}</version>
		</dependency>
		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-web</artifactId>
			<version>${shiro-version}</version>
		</dependency>
		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-spring</artifactId>
			<version>${shiro-version}</version>
		</dependency>
		<!-- shiro end -->

2.在web.xml中配置shiro

    <!-- 配置Shiro过滤器,先让Shiro过滤系统接收到的请求 -->  
    <!-- 这里filter-name必须对应applicationContext.xml中定义的<bean id="shiroFilter"/> -->  
    <!-- 使用[/*]匹配所有请求,保证所有的可控请求都经过Shiro的过滤 -->  
    <!-- 通常会将此filter-mapping放置到最前面(即其他filter-mapping前面),以保证它是过滤器链中第一个起作用的 -->  
    <filter>  
        <filter-name>shiroFilter</filter-name>  
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>  
        <init-param>  
            <!-- 该值缺省为false,表示生命周期由SpringApplicationContext管理,设置为true则表示由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>  

shiroFilter其实和springmvc拦截器原理一样,也是对请求进行拦截

3.配置shiro的配置文件spring-shiro.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"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
  
    <!-- 1. 配置 securityManager -->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="cacheManager" ref="cacheManager"/>
        <property name="realm" ref="jdbcRealm"/>
    </bean>
    
	<!-- 
		2. 配置cacheManager
		2.1  需要加入ehcache的jar包及其配置文件
	 -->
    <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
        <property name="cacheManagerConfigFile" value="classpath:ehcache.xml"/>
    </bean>

    <!--  3. 配置 Realm-->
    <bean id="jdbcRealm" class="com.tansen.selecting.realms.ShiroRealm">
    	<property name="credentialsMatcher">
    		<bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
    			<property name="hashAlgorithmName" value="MD5"></property>
    			<property name="hashIterations" value="1024"></property>
    		</bean>
    	</property>
    </bean>
    
	<!-- 4. 配置lifecycleBeanPostProcessor,可以自定义来调用Spring IOC容器中shiro bean 的生命周期的方法 -->
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
    
	<!-- 5. 启用IOC容器中使用shiro的注解,但必须在配置了LifecycleBeanPostProcessor之后才可以使用 -->
    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
          depends-on="lifecycleBeanPostProcessor"/>
    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
        <property name="securityManager" ref="securityManager"/>
    </bean>

    <!-- 6. 配置shiroFilter,id必须和web.xml文件中配置的DelegatingFilterProxy的<filter-name>一致-->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
    	<!-- Shiro的核心安全接口,这个属性是必须的 -->
        <property name="securityManager" ref="securityManager"/>
        <!-- 没有登陆验证的用户所跳转的页面 -->
        <property name="loginUrl" value="/index.jsp"/>
        <!-- 用户访问未对其授权的资源时,所显示的连接 -->
        <property name="unauthorizedUrl" value="/unauthorized.jsp"/>
        <!--
        	 哪些页面收到保护。以及访问这些页面需要的权限
        	 1). anon表示可以匿名访问,不用登陆就可以访问
        	 2). authc必须验证(即登陆才可以访问的页面,没有验证则跳转到上面配置的 property name="loginUrl"的页面)
         -->
        <property name="filterChainDefinitions">
            <value>
               /index.jsp = anon
               /register.jsp = anon
               /user/register = anon
               /user/login = anon
               /logout = logout
               /** = authc
            </value>
        </property>
    </bean>

</beans>

4.在spring的配置文件中(applicationContext.xml)引入spring-shiro.xml

<import resource="spring-shiro.xml"/>

5.编写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>Insert title here</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/user/login" method="post">
	用户名 :<input type="text" name="username">
	<br>
	密码:<input type="text" name="password">
	<br>
	
	<input type="submit" value="登陆"  >
	<input type="button" value="注册" onclick="location.href='register.jsp'">
</form>
</body>
</html>

注册页面

<%@ 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>
<form action="${pageContext.request.contextPath}/user/register" method="post">
	用户名:<input type="text" name="uAccount">
	<br>
	密码:<input type="text" name="uPassword">
	<br>
	性别:
	<input type="radio" name="uGender" value="男">男
	<input type="radio" name="uGender" value="女">女
	<br>
	<input type="submit" value="注册">
</form>
</body>
</html>

6.以下为User的实体类

package com.tansen.selecting.entities;

import java.util.Date;

public class User {
	private Integer id;
	private String uAccount;
	private String uPassword;
	private String uGender;
	private Date uCreateTime;
	private Integer uState;

	public User() {
	}

	public User(String uAccount, String uPassword, String uGender, Integer uState) {
		super();
		this.uAccount = uAccount;
		this.uPassword = uPassword;
		this.uGender = uGender;
		this.uState = uState;
	}

	public User(String uAccount, String uPassword, String uGender, Date uCreateTime, Integer uState) {
		this.uAccount = uAccount;
		this.uPassword = uPassword;
		this.uGender = uGender;
		this.uCreateTime = uCreateTime;
		this.uState = uState;
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getuAccount() {
		return uAccount;
	}

	public void setuAccount(String uAccount) {
		this.uAccount = uAccount;
	}

	public String getuPassword() {
		return uPassword;
	}

	public void setuPassword(String uPassword) {
		this.uPassword = uPassword;
	}

	public String getuGender() {
		return uGender;
	}

	public void setuGender(String uGender) {
		this.uGender = uGender;
	}

	public Date getuCreateTime() {
		return uCreateTime;
	}

	public void setuCreateTime(Date uCreateTime) {
		this.uCreateTime = uCreateTime;
	}

	public Integer getuState() {
		return uState;
	}

	public void setuState(Integer uState) {
		this.uState = uState;
	}

	@Override
	public String toString() {
		return "User [id=" + id + ", uAccount=" + uAccount + ", uPassword=" + uPassword + ", uGender=" + uGender
				+ ", uCreateTime=" + uCreateTime + ", uState=" + uState + "]";
	}

}

再看看数据库中字段

7.编写Controller,Service,Dao(Service就不写了)

Controller

@Controller
@RequestMapping("/user")
public class UserController {
	
	@Autowired
	private UserService userservice;
	
	@RequestMapping("/register")
	public String register(User user) {
		//user为前端获取的数据
		User user1 = userservice.getuserName(user);
		//user1为通过前端的用户名和密码查询的数据库的结果
		if(user1 == null) {
			String password1 = user.getuPassword();
			System.out.println("加密之前的密码为"+password1);
			//使用shiro的md5进行盐值加密
			String password = new SimpleHash("MD5", user.getuPassword(),user.getuAccount(),1024).toString();
	        System.out.println("加密后的密码为"+password);
	    	user.setuPassword(password);
			Date date = new Date();
			Timestamp timeStamp = new Timestamp(date.getTime()); 
			user.setuCreateTime(timeStamp);
			user.setuState(1);
	    	//添加用户
			userservice.addUser(user);
			System.out.println("注册成功");
			return "redirect:/index.jsp";
		}else {
			System.out.println("用户名存在");
			return "redirect:/register.jsp";
		}
	}
	
	@RequestMapping("/login")
	public String login(@RequestParam("username") String username, @RequestParam("password") String password,Map<String,Object> map) {
		Subject currentUser = SecurityUtils.getSubject();
		if (!currentUser.isAuthenticated()) {
			//把前端页面输入的账号和密码封装成 UsernamePasswordToken对象
            UsernamePasswordToken token = new UsernamePasswordToken(username,password);
            token.setRememberMe(true);
            try {
                currentUser.login(token);
            } catch(AuthenticationException ae) {
            	System.out.println("登陆失败"+ae.getMessage());
            }
        }
		return ""; //登陆成功后的页面
	}
}

Dao(Mapper)

package com.tansen.selecting.mapper;

import com.tansen.selecting.entities.User;

public interface UserMapper {
	//注册用户时查找用户是否存在
	User getuAccount(User user);
	//注册用户
	void adduAccount(User user);
}

DaoImpl(Mapper.xml)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.tansen.selecting.mapper.UserMapper">
	<resultMap id="UserResultMap"
		type="com.tansen.selecting.entities.User">
		<id column="id" property="id" />
		<result column="user_account" property="uAccount" />
		<result column="user_password" property="uPassword" />
		<result column="user_gender" property="uGender" />
		<result column="user_createtime" property="uCreateTime" />
		<result column="user_state" property="uState" />
	</resultMap>

	<!-- User getuAccount(User user); -->
	<select id="getuAccount" resultMap="UserResultMap">
		select * from user where
		user_account = #{uAccount}
	</select>

	<!-- void adduAccount(User user); -->
	<insert id="adduAccount">
		insert into user
		(user_account,user_password,user_gender,user_createtime,user_state)
		values
		(#{uAccount},#{uPassword},#{uGender},#{uCreateTime},#{uState})
	</insert>

</mapper>

猜你喜欢

转载自blog.csdn.net/laogay_tansen/article/details/81126336