Spring Security

配置关于安全方面的设置,用@Configuration注解来注册一个security设置:

1
2
3
4
@Configuration
public class DemoSecurityConfig {
// 添加你的安全设置
}

Spring Security Password Storage

在spring security中,密码可以用不同的方式存储:

id代表使用的加密算法, noop表示 "no operation"即保存纯文本密码,不适用加密算法。

在内存中保存用户、密码和角色

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@Configuration
public class DemoSecurityConfig {

@Bean
public InMemoryUserDetailManager userDetailsManager() {

UserDetails john = User.bulider()
.username("john")
.password("{noop}test123")
.roles("EMPLOYEE")
.build();

UserDetails mary = User.bulider()
.username("john")
.password("{noop}test123")
.roles("EMPLOYEE","MANAGER")
.build();

UserDetails susan = User.bulider()
.username("john")
.password("{noop}test123")
.roles("EMPLOYEE","MANAGER","ADMIN")
.build();

return new InMemoryUserDetailsManager(john, mary, susan);
}
}

为不同的端点设置可查看的角色

我们可以根据roles去开发对应的API端点, 例如:

添加一个角色的语句:

1
2
requestMatchers(<<添加HTTP方法>>, <<添加路径>>)
.hasRole(<<添加角色>>)

添加多个角色的语句:

1
2
requestMatchers(<<添加HTTP方法>>, <<添加路径>>)
.hasAnyRole(<<添加角色list>>)

具体的:

1
2
3
4
requestMatchers(HttpMethod.GET, "/api/employees").hasRole("EMPLOYEE")

requestMatchers(HttpMethod.GET, "/api/employees/**").hasRole("EMPLOYEE)

在代码中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(configurer ->
configurer
.requestMatchers(HttpMethod.GET, "/api/employees").hasRole("EMPLOYEE")
......
);
http.httpBasic(Customizer.withDefaults());

//如果构建非页面的rest api,组需要禁掉CSRF保护
http.csrf(csrf -> csrf.disable());

return http.build();
}

用数据库存储用户、密码和授权

Spring Security有默认固定的表名和列名,但是也是可以自定义修改的:

再代码中使用:

1
2
3
4
@Bean
public UserDetailsManager userDetailManager(Datasource dataSource) {
return new JdbcUserDetailsManager(dataSource);
}

修改默认的表名和列名,使用自定义的表名和列名:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Bean
public UserDetailsManager userDetailsManager(DataSource dataSource) {
JdbcUserDetailsManager jdbcUserDetailsManager = new JdbcUserDetailsManager(dataSource);

jdbcUserDetailsManager.setUsersByUsernameQuery(
"select user_id, pw, active from members where user_id=?"
);

jdbcUserDetailsManager.setAuthoritiesByUsernameQuery(
"select user_id, roles from roles where user_id=?"
);

return jdbcUserDetailsManager;
}