[Spring Cloud] - Spring Security实践(三)- 数据库方式的基本认证和授权

基本配置及controller设置

首先,创建针对三种role的controller(App/Admin/User):

@RestController
@RequestMapping("/app/api")
public class Controllers {
    @GetMapping("hello")
    public String hello(){
        return "hello, app";
    }
}
@RestController
@RequestMapping("/admin/api")
class AdminController {
    @GetMapping("hello")
    public String hello(){
        return "hello, admin";
    }
}
@RestController
@RequestMapping("/user/api")
class UserController {
    @GetMapping("hello")
    public String hello(){
        return "hello, user";
    }
}

此三个controller分别对应三种Role,此时我们在配置中添加权限控制的配置:

@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
     @Override
     protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests()
                    .antMatchers("/admin/**").hasRole("ADMIN")
                    .antMatchers("/user/**").hasRole("USER")
                    .antMatchers("/app/**").permitAll()
                    .anyRequest().authenticated()
                    .and()
                .formLogin();
        }
}

此时重启服务,发现登录后访问user及admin资源均提示403错误,但app可以正常进入,说明此配置没有问题。只缺少用户信息的Role部分。

创建数据库及修改配置文件

spring security自带建表语句,在security的core包中,路径为:\org\springframework\security\spring-security-core\5.3.2.RELEASE\spring-security-core-5.3.2.RELEASE.jar!\org\springframework\security\core\userdetails\jdbc\users.ddl
注意:mysql不支持varchar_ignorecase类型,需手动改为vachar

create table users(
    username varchar(50) not null primary key,
    password varchar(500) not null,
    enabled boolean not null
);
create table authorities (
    username varchar(50) not null,
    authority varchar(50) not null,
    constraint fk_authorities_users foreign key(username) references users(username)
);
create unique index ix_auth_username on authorities (username,authority);

配置文件:

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/springdemo?useUnicode=true&characterEncoding=utf-8&useSSL=falser
    username: root
    password: 1234

默认数据库连接设置

[Spring Cloud] - Spring Security实践(一)- 基本概念及实践中,提到了自定义用户信息的两种方式。
与第二种(即通过InMemoryUserDetailsManager对象来设置用户信息)类似,数据库连接是通过JdbcUserDetailsManager实现。
优点:方便,直接使用
缺点:数据库模型需遵守spring security默认规范, 每次重启需手动删除数据库中用户信息

@Configuration
public class AuthConfiguration {
    private DataSource dataSource;
    @Autowired
    public AuthConfiguration(DataSource dataSource){
        this.dataSource = dataSource;
    }
    @Bean
    public UserDetailsService userDetailsService(){
        JdbcUserDetailsManager manager = new JdbcUserDetailsManager();
        manager.setDataSource(dataSource);
        manager.createUser(
                User.withUsername("user").password("{bcrypt}" + new BCryptPasswordEncoder().encode("123"))
                        .roles("USER").build());
        manager.createUser(
                User.withUsername("admin").password("{bcrypt}" + new BCryptPasswordEncoder().encode("123"))
                        .roles("ADMIN").build());
        return manager;
    }
}

改良:添加判断,如果不存在则create,否则无操作,直接获取。

@Configuration
public class AuthConfiguration {
    private DataSource dataSource;
    @Autowired
 public AuthConfiguration(DataSource dataSource){
        this.dataSource = dataSource;
    }
    @Bean
 public UserDetailsService userDetailsService(){
        JdbcUserDetailsManager manager = new JdbcUserDetailsManager();
        manager.setDataSource(dataSource);
        if (!manager.userExists("user")){
            manager.createUser(
                    User.withUsername("user").password("{bcrypt}" + new BCryptPasswordEncoder().encode("123"))
                            .roles("USER").build());
        }
        if (!manager.userExists("admin")) {
            manager.createUser(
                    User.withUsername("admin").password("{bcrypt}" + new BCryptPasswordEncoder().encode("123"))
                            .roles("ADMIN").build());
        }
        return manager;
    }
}

查看数据库:数据库中的users和authorities表中已存在代码中定义的用户了
image.png
[Spring Cloud] - Spring Security实践(三)- 数据库方式的基本认证和授权_第1张图片


但这样做仍然灵活性欠佳,而且不符合正常逻辑及标准。所以下一步就是使用数据库的自定义模型的认证和鉴权,请关注下一篇文章。

你可能感兴趣的:(spring-security)