springboot整合spring security和mybatis的demo

Spring Security的原理

  • spring security的原理就是使用很多的拦截器对URL进行拦截,以此来管理登录验证和用户权限验证。
  • 用户登陆,会被AuthenticationProcessingFilter(身份验证处理筛选器)拦截,调用AuthenticationManager(身份验证管理器)的实现,而且AuthenticationManager会调用ProviderManager(提供程序管理器)来获取用户验证信息(不同的Provider调用的服务不同,因为这些信息可以是在数据库上,可以是在LDAP服务器上,可以是xml配置文件上等),如果验证通过后会将用户的权限信息封装一个User放到spring的全局缓存SecurityContextHolder(安全上下文持有者)中,以备后面访问资源时使用。所以要自定义用户的校验机制的话,只要实现自己的AuthenticationProvider就可以了。在用AuthenticationProvider 这个之前,我们需要提供一个获取用户信息的服务,实现 UserDetailsService 接口。
  • 用户名密码->(Authentication(未认证) -> AuthenticationManager ->AuthenticationProvider->UserDetailService->UserDetails->Authentication(已认证)

步骤一:创建springboot项目,添加所需依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.1.6.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.example</groupId>
	<artifactId>demo-security-mybatis</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>demo-security-mybatis</name>
	<description>Demo project for Spring Boot</description>

	<properties>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-jdbc</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-security</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>2.0.1</version>
		</dependency>

		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

步骤二:mysql创建用户user表和角色role表

user表:
在这里插入图片描述
role表:
在这里插入图片描述

步骤三:修改application.yml配置在这里插入图片描述

步骤四:创建bean包,在该包下创建User和Role两个实体类

User类:

package com.example.demosecuritymybatis.bean;

import lombok.Data;

@Data
public class User {
    private int id;
    private String username; //账户
    private String password; //密码
}

Role类:

package com.example.demosecuritymybatis.bean;

import lombok.Data;

@Data
public class Role {
    private int id;
    private String name; //角色名称
    private String userId;
}

步骤五:创建mapper包,在该包下创建UserMapper和RoleMapper两个接口。在resources目录下创建mappers文件夹,创建UserMapper.xml和RoleMapper.xml

UserMapper接口:

@Repository
public interface UserMapper {
    User selectUserByName(String username); //通过用户名查询用户
}

UserMapper.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.example.demosecuritymybatis.mapper.UserMapper">
    <select id="selectUserByName" parameterType="java.lang.String" resultType="com.example.demosecuritymybatis.bean.User">
        select * from user where username=#{username}
    </select>
</mapper>

RoleMapper接口:

@Repository
public interface RoleMapper {
    List<Role> selectRoleByUserId(int userId); //通过用户id查询角色
}

RoleMapper.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.example.demosecuritymybatis.mapper.RoleMapper">
    <select id="selectRoleByUserId" parameterType="java.lang.Integer" resultType="com.example.demosecuritymybatis.bean.Role">
        select * from role where userId=#{userId}
    </select>
</mapper>

application类需开启mapper扫描:

@MapperScan("com.example.demosecuritymybatis.mapper")

步骤六:创建controller包,在该包下创建TestController类

@Controller
public class TestController{

    @RequestMapping("/")
    public String index(){
        return "index"; //一开始要访问的页面
    }
    @RequestMapping("/login")
    public String login(){
        return "login"; //登录页面
    }
    @RequestMapping("/fail")
    public String fail(){
        return "fail"; //登录失败页面
    }
}

步骤七:在templates目录下创建login.html、index.html和fail.html页面

login.html:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>    
	<meta content="text/html;charset=UTF-8"/>    
    <title>登录页面</title>
</head>
<body>    
    <div>        
        <h2>使用账号密码登录</h2>        
        <form name="form" th:action="@{/login}" action="/login" method="POST">           	<div class="form-group">                
            	<label>账号</label>                
            	<input type="text" class="form-control" name="username" value="" placeholder="账号" />            
           </div>            
           <div class="form-group">                
                <label>密码</label>                
                <input type="password" class="form-control" name="password" placeholder="密码" />            
           </div>           
           <input type="submit" id="login" value="Login" />        
        </form>    
    </div>
</body>
</html>

index.html:
在这里插入图片描述
fail.html:
在这里插入图片描述

步骤八:创建security包,在该包下创建SecurityConfig类和WjcUserDetailsService类

SecurityConfig类:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    UserDetailsService wjcUserDetailsService(){ //注册UserDetailsService 的bean
        return new WjcUserDetailsService();
    }
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //user Details Service验证
        //密码加密,与数据库匹配
        auth.userDetailsService(wjcUserDetailsService()).passwordEncoder(new BCryptPasswordEncoder());
    }
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .anyRequest().authenticated() //任何请求,登录后可以访问
                .and()
                .formLogin()
                .loginPage("/login")
                .failureUrl("/fail")
                .permitAll() //登录页面用户任意访问
                .and()
                .logout().permitAll(); //注销行为任意访问
    }
}

WjcUserDetailsService类:

@Component
public class WjcUserDetailsService implements UserDetailsService {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private RoleMapper roleMapper;

    //复写此方法用于登录验证
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userMapper.selectUserByName(username); //获得用户
        if (user==null){
            throw new UsernameNotFoundException("用户名不存在");
        }
        //权限列表
        List<SimpleGrantedAuthority> authorities = new ArrayList<>();
        //根据用户名获取角色列表
        List<Role> roles = roleMapper.selectRoleByUserId(user.getId());
        for (Role role:roles){
            //循环角色,将角色名称放入到权限列表中
            authorities.add(new SimpleGrantedAuthority(role.getName()));
        }
        return new org.springframework.security.core.userdetails.User(
                user.getUsername(), user.getPassword(), authorities);
    }
}

步骤九:给user表添加测试数据前,密码需要加密,方法如下

public class Main {
    public static void main(String args[]){
        BCryptPasswordEncoder bCryptPasswordEncoder = 
            new BCryptPasswordEncoder();
        //加密"123"
        String encode = bCryptPasswordEncoder.encode("123");
        System.out.println(encode);
    }
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值