SpringSecurity学习二 SpringSecurity部署数据库

上一篇:SpringSecurity学习一 快速开始
下一篇::SpringSecurity学习三 SpringSecurity 结合jwt


SpringSecurity部署数据库

基本的SpringSecurity部署,从数据库读取用户。
持久层框架是mybatis-plus
项目源码gitte地址: https://gitee.com/xiang_Gitee/spring-security-learn(子工程basic)

必要依赖

	<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
      <version>RELEASE</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <!--数据相关-->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>${mysql.version}</version>
    </dependency>
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid-spring-boot-starter</artifactId>
      <version>${druid.version}</version>
    </dependency>
    <dependency>
      <groupId>com.baomidou</groupId>
      <artifactId>mybatis-plus-boot-starter</artifactId>
      <version>${mybatisplus.version}</version>
    </dependency>

开始之前

理解SpringSecurity是完全由Filter链进行控制的,所以要根据需求定制就需要替换其中的Filter,这意味着Filter的内容掌握得好更便于学习SpringSecurity。
推荐博文Spring Security 入门原理及实战Spring Security的一些工作原理部分解释得很好。

配置

数据库配置

  1. 建user表
    在这里插入图片描述
  2. 建立user表的映射类
    这里比较特殊的是将user表的映射类直接继承了UserDetails ,UserDetails 是SpringSecurity运行时用来存储用户信息的类,实际上也可以为UserDetails 建一个表作为用户表来用
@Data
public class User implements UserDetails {
    private Integer id;

    private String username;
    private String password;
    
	@TableField(exist = false)
	private Boolean enabled;
    @TableField(exist = false)
    private String userface;
    @TableField(exist = false)
    private String remark;
    @TableField(exist = false)
    private List<Role> roles;

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return null;
    }
    @Override
    public boolean isAccountNonExpired() {
        return true;
    }
    @Override
    public boolean isAccountNonLocked() {
        return true;
    }
    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }
    @Override
    public boolean isEnabled() {
        return true;
    }
}
  1. mapper
public interface UserMapper extends BaseMapper<User> {
}

4.service
注意此service并不同于普通的service类,这里的UserService 实现了UserDetailsService ,这个接口只需要实现一个方法loadUserByUsername(String username),顾名思义就是根据用户名加载用户,返回值类型是UserDetails,不管是从数据库还是别的什么地方都可以在方法体里自定义了。

public class UserService implements UserDetailsService {
@Resource
private UserMapper userMapper;
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        LambdaQueryWrapper<User> lambdaQueryWrapper = new QueryWrapper().lambda();
        lambdaQueryWrapper.eq(User::getUsername,username);
        User user = userMapper.selectOne(lambdaQueryWrapper);
        if (user==null){
            throw new UsernameNotFoundException("用户查询失败");
        }
        return user;
    }
}

只要把这个UserDetailsService 的实现类配置到某个位置,就可以根据在方法体的流程获取用户信息了。这个配置自然是在SecurityConfig.java里面做了。

  1. 配置SecurityConfig
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Resource
private UserService userService;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .csrf()//禁用跨域保护策略,默认开启
                .disable()
                .authorizeRequests()//认证需求路径
                .antMatchers("/", "/home")
                .permitAll()
                .anyRequest()
                .authenticated()
                .and()
                .formLogin()//登录路径
                .loginPage("/signin")
                .loginProcessingUrl("/dosignin")
                .failureUrl("/error")
                .defaultSuccessUrl("/hello")
                .permitAll()
                .and()
                .logout()//登出路径
                .logoutSuccessUrl("/home")
                .logoutUrl("/logout");
        }


    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService).passwordEncoder(NoOpPasswordEncoder.getInstance());
    }
}

可以看到和上一篇文章simple相比,去掉了内存用户的配置,多了一个覆盖方法configure(AuthenticationManagerBuilder auth),参数类型AuthenticationManagerBuilder 是认证管理器,在认证管理器里去配置上一步的UserService,密码编码器为了方便仍然采用NoOpPasswordEncoder不加密,也可以换成auth.userDetailsService(userService).passwordEncoder(new BCryptPasswordEncoder());用BCrypt编码

Spring Security 中提供了 BCryptPasswordEncoder 密码编码工具,可以非常方便的实现密码的加密加盐,相同明文加密出来的结果总是不同,这样就不需要用户去额外保存盐的字段了,这一点比 Shiro 要方便很多。

运行

在这里插入图片描述

其他文章

SpringSecurity学习一 快速开始
SpringSecurity学习二 SpringSecurity部署数据库

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值