SpringSecurity系列——简单自定义登录流程day1-3

181 篇文章 3 订阅
24 篇文章 31 订阅

SpringSecurity认证

前后端分离的登录校验流程

在这里插入图片描述

前后端分离请求响应流程

在这里插入图片描述

SpringSecurity完整流程

SpringSecurity的原理其实是个过滤器链,其内部包含了各式各样功能各异的过滤器,通过这些过滤器,对消息进行拦截、放行、处理操作
在这里插入图片描述

如何查看过滤器

1.启动类中添加逻辑进行debug

在这里插入图片描述

2.打开评估输入表达式
run.getBean(DefaultSecurityFilterChain.class)

在这里插入图片描述

这里你可以看到filters中的共计16个过滤器了

修改流程

登录

  1. 自定义登录接口

1.1 调用ProviderManager的方法进行认证如果认证通过生成jwt
1.2 把用户信息存入redis中

  1. 自定义UserDetailsservice

在这个实现列中去查询数据库

校验

  1. 定义jwt认证过滤器

1.1 获取token
1.2 解析token获取其中的userId
1.3 从redis中获取用户信息
1.4 存入SecurityContextHolder

自定义登录流程

1.导入依赖

       <dependencies>
        <dependency>
            <groupId>cn.fly</groupId>
            <artifactId>JJWTUtil</artifactId>
            <version>1.1.2</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.17</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web-services</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.79</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </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>

2.编写yaml

server:
  port: 8080
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/syf14?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai&zeroDateTimeBehavior=CONVERT_TO_NULL&allowPublicKeyRetrieval=true
    username: root
    password: syf20020816

3.编写entity,mapper

User
package com.example.ss1.entity;

import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@AllArgsConstructor
@NoArgsConstructor
@Data
@TableName("user")
public class User {
    private Long id;
    private String username;
    private String password;
    private String status;
    private String nickname;
}

UserMapper
package com.example.ss1.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.ss1.entity.User;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface UserMapper extends BaseMapper<User> {
}

4.自定义登录表单对象实现UserDetails接口

package com.example.ss1.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import java.util.Collection;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserLogin implements UserDetails {

    //传入用户对象
    private User user;

    /**
     * 判断权限信息
     * @return
     */
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {

        return null;
    }

    @Override
    public String getPassword() {
        return user.getPassword();
    }

    @Override
    public String getUsername() {
        return user.getUsername();
    }

    /**
     * 判断是否未过期
     * @return
     */
    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    /**
     * 判断账户是否未锁定
     * @return
     */
    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    /**
     * 判断是否可以使用
     * @return
     */
    @Override
    public boolean isEnabled() {
        return true;
    }
}

5.自定义UserDetailsServiceImpl实现UserDetailsService

在这里插入图片描述

package com.example.ss1.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.ss1.entity.User;
import com.example.ss1.entity.UserLogin;
import com.example.ss1.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
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 java.util.Objects;

@Service
public class UserDetailsServiceImpl implements UserDetailsService {
    @Autowired
    private UserMapper userMapper;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //查询用户信息
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUsername, username).last("limit 1");
        User user = userMapper.selectOne(queryWrapper);
        //异常
        if (Objects.isNull(user)){
            throw new UsernameNotFoundException("用户名未发现");
        }
        //查询对应权限信息

        //数据封装为UserDetails返回
        return new UserLogin(user);

    }
}

6.修改数据库密码

添加{noop}表示明文存储
在这里插入图片描述

7.测试

访问http://localhost:8080/demo
使用数据库中的用户进行登录!
在这里插入图片描述

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值