SpringSecurity数据库用户认证

1. 准备数据库环境

# 新建用户表
CREATE TABLE `user` (
  `id` INT(11) NOT NULL AUTO_INCREMENT COMMENT '编号',
  `username` VARCHAR(32) NOT NULL COMMENT '账号',
  `birthday` DATETIME DEFAULT NULL COMMENT '生日',
  `sex` CHAR(1) DEFAULT NULL COMMENT '性别',
  `address` VARCHAR(256) DEFAULT NULL COMMENT '地址',
  `password` VARCHAR(100) DEFAULT NULL COMMENT '密码',
  CONSTRAINT pk_user PRIMARY KEY (`id`)
);

# 添加用户数据
INSERT  INTO 
  `user`(`id`,`username`,`birthday`,`sex`,`address`,`password`) 
VALUES 
(1,'周瑜','2020-02-27 17:47:08','男','吴国','$2a$10$gw70IRq6RuHMgZyO3w84Sepu2zPGyXniOENu7xeTK0lZArSU/fyO6');

2. 新建SpringBoot项目

在这里插入图片描述

3. 项目依赖

<dependencies>
    <!-- mysql -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.49</version>
    </dependency>
    <!-- mybatis-plus -->
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.4.0</version>
    </dependency>
    <!-- jdbc -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>
    <!-- security -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <!-- thymeleaf -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    <!-- web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- devtools -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
    </dependency>
    <!-- configuration -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-configuration-processor</artifactId>
    </dependency>
    <!-- lombok -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <!-- tomcat -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
    </dependency>
    <!-- test -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
    </dependency>
</dependencies>

4. 用户实体类

package zw.springboot.domain;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;

/**
 * @className UserDO
 * @description 用户实体类
 * @author 周威
 * @date 2020-09-02 8:59
 **/
@Data
public class UserDO implements Serializable
{
    /* 用户编号 */
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;

    /* 用户姓名 */
    @TableField("username")
    private String userName;

    /* 用户密码 */
    @TableField("password")
    private String passWord;

    /* 用户生日 */
    @TableField("birthday")
    private Date birthday;

    /* 用户性别 */
    @TableField("sex")
    private String sex;

    /* 用户地址 */
    @TableField("address")
    private String address;
}

5. 用户展示实体类

package zw.springboot.vo;

import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import zw.springboot.domain.UserDO;
import java.io.Serializable;

/**
 * @className UserVO
 * @description 用户展示实体类
 * @author 周威
 * @date 2020-09-02 9:04
 **/
@Data
@TableName("user")
public class UserVO extends UserDO implements Serializable
{
}

6. 用户持久层接口

package zw.springboot.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import zw.springboot.vo.UserVO;

/**
 * @className UserMapper
 * @description 用户持久层接口
 * @author 周威
 * @date 2020-09-02 9:06
 **/
@Mapper
public interface UserMapper extends BaseMapper<UserVO>
{
}

7. 定义用户信息服务

  • 定义一个类实现UserDetailsService接口
  • 重写public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException方法
package zw.springboot.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import zw.springboot.mapper.UserMapper;
import zw.springboot.vo.UserVO;
import java.util.ArrayList;
import java.util.List;

/**
 * @className SecurityServiceImpl
 * @description 安全认证业务层实现类
 * @author 周威
 * @date 2020-09-02 9:08
 **/
@Service
public class SecurityServiceImpl implements UserDetailsService
{
    @Autowired
    private UserMapper userMapper;

    @Override
    public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException
    {
        // 查询数据库
        QueryWrapper<UserVO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", userName);
        UserVO userVO = userMapper.selectOne(queryWrapper);
        if (userVO == null)
        {
            // 用户不存在
            return null;
        }
        else
        {
            // 用户存在

            // 角色集合
            List<GrantedAuthority> authorities = new ArrayList<>();
            // 角色必须以`ROLE_`开头,数据库中没有,则在这里加
            authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
            User user = new User(userVO.getUserName(), userVO.getPassWord(), authorities);
            return user;
        }
    }
}

8. 安全认证表现层控制器

package zw.springboot.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @className LoginController
 * @description 安全认证表现层控制器
 * @author 周威
 * @date 2020-09-02 10:31
 **/
@Controller
@RequestMapping("security")
public class LoginController
{
    @Autowired
    private UserDetailsService securityService;

    /**
     * 跳转登录页面
     * @return 逻辑视图名
     */
    @GetMapping("page")
    public String requsetLoginPage()
    {
        return "login";
    }


    /**
     * 跳转后台首页
     * @return 逻辑视图名
     */
    @PostMapping("success")
    public String requestLoginSuccess()
    {
        return "main";
    }
}

9. 安全认证配置类

package zw.springboot.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
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.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * @className SpringSecurityConfig
 * @description 安全认证配置类
 * @author 周威
 * @date 2020-09-02 9:11
 **/
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter
{
    @Autowired
    private UserDetailsService securityService;

    /**
     * 创建密码加密器
     * @return 密码加密器
     */
    @Bean
    public PasswordEncoder createPassWordEncoder()
    {
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception
    {
        http.authorizeRequests()
                // 指定哪些资源需要认证
                .antMatchers("/user/**").authenticated()
                // 其他资源不需要认证
                .anyRequest().permitAll()
                .and()
                // 启用表单用户登录认证
                .formLogin()
                // 指定登录页面请求地址
                .loginPage("/security/page")
                // 指定登录认证请求地址
                .loginProcessingUrl("/security/login")
                // 指定登录成功跳转请求
                .successForwardUrl("/security/success");
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception
    {
        auth
                // 指定安全认证服务
                .userDetailsService(securityService)
                // 指定密码加密器
                .passwordEncoder(createPassWordEncoder());
    }
}

10. 定义登录界面

<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
    <head>
        <title>登录</title>
        <meta http-equiv="content-type" content="text/html;charset=utf-8"/>
        <meta name="author" content="周威"/>
    </head>
    <body>
        <form th:action="@{/security/login}" method="post">
            <p>
                <label>账号:</label>
                <input name="username" type="text">
            </p>
            <p>
                <label>密码:</label>
                <input name="password" type="password">
            </p>
            <p>
                <input type="submit" value="登录">
            </p>
        </form>
    </body>
</html>

11. 定义登录成功界面

<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
    <head>
        <title>后台主页</title>
        <meta http-equiv="content-type" content="text/html;charset=utf-8"/>
        <meta name="author" content="周威"/>
    </head>
    <body>
        <p th:text="'Welcome To Admin Page'"></p>
    </body>
</html>

12. 项目启动访问

在这里插入图片描述
在这里插入图片描述

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值