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);
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章