SpringSecurity入門2---基於數據庫的登錄

代碼地址
在上文中實現了基於內存的登錄,書接上文,這次我們用基於數據庫的方式實現登錄

使用SpringSecurity默認提供的

  1. 創建數據庫即對應的表,在application.properties配置好數據源
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users`  (
  `username` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `enabled` tinyint(255) NOT NULL,
  PRIMARY KEY (`username`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

DROP TABLE IF EXISTS `authorities`;
CREATE TABLE `authorities`  (
  `username` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `authority` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  UNIQUE INDEX `ix_auth_username`(`username`, `authority`) USING BTREE,
  CONSTRAINT `fk_authorities_users` FOREIGN KEY (`username`) REFERENCES `users` (`username`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;
  1. 修改WebSecurityConfig
 	@Autowired
    private DataSource dataSource;
    
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
			auth.jdbcAuthentication().dataSource(dataSource)
			                // inMemoryAuthentication()
			                .passwordEncoder(passwordEncoder())
			                .withUser("user")
			                .password(passwordEncoder().
			                        encode("123")).roles("USER")
			                .and()
			                .withUser("admin")
			                .password(passwordEncoder().
			                        encode("123")).roles("ADMIN");
    }

重啓項目,訪問請求進行測試即可;在啓動的過程中就會將配置的用戶插入到上面創建的表中

使用自定義的登錄邏輯處理

正常情況下我們系統的用戶相關表是由我們自己設計,登錄邏輯有我們自己的處理。我們只需要創建類重寫UserDetailsServiceloadUserByUsername方法並將其注入到Spring容器中,再進行配置即可。

  1. 爲了和上面的做區別,單獨再創建一個users
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users`  (
  `id` bigint(20) NOT NULL,
  `username` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `password` varchar(60) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `enable` tinyint(4) NOT NULL DEFAULT 1,
  `roles` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;
  1. 創建對應的user實體類,需要實現UserDetails
@Data
// 表名
@TableName("users")
public class User implements UserDetails {
	// id自增長
    @TableId(type= IdType.AUTO)
    private Long id;
    private String username;
    private String password;
    private String roles;
    private boolean enable;
    // 不與數據庫字段對應
    @TableField(exist = false)
    private List<GrantedAuthority> authorities; // 權限列表

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return authorities;
    }

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

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

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

    @Override
    public boolean isEnabled() {
        return this.enable;
    }
}
  1. 我使用的MybatisPlus來與數據庫交互,可以根據實際情況,實現根據用戶名查詢到用戶信息即可
  2. 創建自己的UserDetailService,重寫loadUserByUsername方法,返回自己創建的User對象
@Service
public class MyUserDetailService implements UserDetailsService {
    @Autowired
    private UserMapper userMapper;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username",username);
        // 根據用戶名查詢用戶
        User user = userMapper.selectOne(queryWrapper);
        if(null == user){
            throw new UsernameNotFoundException("user not exist");
        }
		// Roles是String格式用逗號隔開,該工具將Role拆分成數組,並將其設置進User對象中
        user.setAuthorities(AuthorityUtils.commaSeparatedStringToAuthorityList(user.getRoles()));
        return user;
    }
}
  1. 在表中插入用戶數據,注意密碼需要自己手動進行加密
		BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        String password = passwordEncoder.encode("123");
        System.out.println(password);

在這裏插入圖片描述
6. 在WebSecurityConfig中添加自己的UserDetailService

 @Autowired
    private MyUserDetailService userDetailService;
    
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//        auth.jdbcAuthentication().dataSource(dataSource)
//                // inMemoryAuthentication()
//                .passwordEncoder(passwordEncoder())
//                .withUser("user")
//                .password(passwordEncoder().
//                        encode("123")).roles("USER")
//                .and()
//                .withUser("admin")
//                .password(passwordEncoder().
//                        encode("123")).roles("ADMIN");
        auth.userDetailsService(userDetailService).passwordEncoder(passwordEncoder());
    }
  1. 重啓項目進行測試即可
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章