spring-security(一):自定义数据库模型的认证与授权

前言

自定义数据库结构实际上仅仅需要实现一个自定义的UserDetailsService;

1.数据库准备

CREATE TABLE `sys_users` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `username` varchar(50) NOT NULL,
  `password` varchar(60) DEFAULT NULL,
  `enable` tinyint(4) NOT NULL DEFAULT '1' COMMENT '用户是否可用',
  `roles` text COMMENT '用户角色,多个角色之间用逗号隔开',
  PRIMARY KEY (`id`),
  KEY `username` (`username`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

2.插入测试数据

INSERT INTO `springdemo`.`sys_users`(`id`, `username`, `password`, `enable`, `roles`) VALUES (1, 'admin', '123', 1, 'ROLE_ADMIN,ROLE_USER');
INSERT INTO `springdemo`.`sys_users`(`id`, `username`, `password`, `enable`, `roles`) VALUES (2, 'user', '123', 1, 'ROLE_USER');

3.编写User实体

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
public class SysUsers implements UserDetails {
    private Long id;
    private String userName;
    private String password;
    private String roles;
    private boolean enable;

    private List<GrantedAuthority> authorities;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

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

    @Override
    public String getPassword() {
        return password;
    }

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

    @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;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getRoles() {
        return roles;
    }

    public void setRoles(String roles) {
        this.roles = roles;
    }

    public boolean isEnable() {
        return enable;
    }

    public void setEnable(boolean enable) {
        this.enable = enable;
    }

    public void setAuthorities(List<GrantedAuthority> authorities) {
        this.authorities = authorities;
    }
    
}

4.持久层准备

4.1准备pom依赖

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.1</version>
        </dependency>

4.2配置数据库连接

spring.security.user.password=123456
spring.datasource.url=jdbc:mysql://localhost:3306/springDemo?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT
spring.datasource.username=root
spring.datasource.password=root

4.3启动类上加MapperScan

@MapperScan("com.demo.springsecuritydemo.mapper")
@SpringBootApplication
public class SpringSecurityDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringSecurityDemoApplication.class, args);
    }

}

4.4编写映射接口

@Component
public interface UserMapper {
    @Select("select * from sys_users where username = #{username}")
    SysUsers findByUsername(@Param("username")String username);
}

5.编写MyUserDetailService

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

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //从数据库尝试获取该用户
        final SysUsers user = userMapper.findByUsername(username);
        //用户不存在 抛出异常
        if (user == null) {
            throw new UsernameNotFoundException("用户不存在");
        }
        //将数据库形式的roles解析成UserDetails的权限集
        //AuthorityUtils.commaSeparatedStringToAuthorityList是spring-security提供的
        //该方法用于将逗号隔开的权限集字符串切割成可用权限列表
        //当然也可以自己实现,如用分号来隔开等,参考generateAuthorities
        user.setAuthorities(AuthorityUtils.commaSeparatedStringToAuthorityList(user.getRoles()));
        return user;
    }

    /**
     * 自行实现权限的转换
     */
    public List<GrantedAuthority> generateAuthorities(String roles) {
        final ArrayList<GrantedAuthority> authorities = new ArrayList<>();
        final String[] roleArray = roles.split(";");
        if (roles != null && !"".equals(roles)) {
            for (String role : roleArray) {
                authorities.add(new SimpleGrantedAuthority(role));
            }
        }
        return authorities;
    }

6.绑定到资源授权的配置类

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private MyUserDetailsService myUserDetailsService;

    @Autowired
    PasswordEncoder passwordEncoder;

    /**
     * 我们自定义配置认证用户
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(myUserDetailsService).passwordEncoder(passwordEncoder);
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章