基本配置及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表中已存在代码中定义的用户了
但这样做仍然灵活性欠佳,而且不符合正常逻辑及标准。所以下一步就是使用数据库的自定义模型的认证和鉴权,请关注下一篇文章。