如果餓了就吃,困了就睡,渴了就喝,人生就太無趣了
作者:可耳
更新時間 : 2020年04月07日
源碼地址:https://github.com/keer123456789/springbootstudy/tree/master/sercurity_demo_2
1 Spring Security 配置
1.1 創建SecurityConfig
配置類
此類繼承WebSecurityConfigurerAdapter
,並使用@EnableWebSecurity
進行註解,開啓Spring Security
,代碼如下:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
}
1.2 介紹詳細信息
要指定Web安全細節,通過重載WebSecurityConfigurerAdapter
其中的三個configure()
方法進行配置
方法 | 描述 |
---|---|
configure(WebSecurity) | 通過重載,配置SpringSecurity的Filter鏈 |
configure(HttpSecurity) | 通過重載,配置如何使用攔截器保護請求 |
configure(AuthenticationManagerBuilder) | 通過重載,配置user-detail服務 |
2 用戶信息
2.1 添加用戶信息
根據1.2介紹,添加用戶信息應該重寫configure(AuthenticationManagerBuilder)
方法,代碼如下:
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password("123456").roles("USER").and()
.withUser("admin").password("654321").roles("USER","ADMIN");
}
inMemoryAuthentication()
使用內存存儲用戶信息withUser()
,password()
,roles()
分別配置用戶名,密碼,角色and()
連接用戶配置
2.2 配置用戶信息詳細方法
方法 | 描述 |
---|---|
accountExpired(boolean) | 定義賬號是否過期 |
accountLocked(boolean) | 定義賬號是否鎖定 |
and() | 連接配置 |
authorities(GrantedAuthority…) | 授予用戶一個或多個權限 |
authorities(List<? extends GrantedAuthority>) | 授予用戶一個或多個權限 |
authorities(String…) | 授予用戶一個或多個權限 |
credentialsExpired(boolean) | 定義憑證是否過期 |
disabled(boolean) | 定義賬號是否已經被禁用 |
password(String ) | 定義賬號密碼 |
roles(String… ) | 授予用戶一個或多個權限 |
其中roles()
和authorities()
作用相同,但是roles()
是authorities()
的簡寫方式,roles()
都會給值添加一個ROLE_
的前綴,2.1
中的代碼和下面代碼等價:
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password("123456").authorities("ROLE_USER").and()
.withUser("admin").password("654321").authorities("ROLE_USER","ROLE_ADMIN");
}
3 登錄測試
3.1 添加訪問接口
@RestController
@RequestMapping("/security")
public class Controller {
protected Logger logger= LoggerFactory.getLogger(this.getClass());
@RequestMapping(value = "hello",method = RequestMethod.GET)
public String hello() {
return "hello_world";
}
}
3.2 訪問接口
瀏覽器訪問:http://127.0.0.1:8080/security/hello
3.3 密碼異常
輸入賬號密碼後,會出現登錄不進去的問題,後臺日誌:
在 SpringSecurity 5.x 中,密碼需要經過加密,也就是需要一個編碼器 PasswordEncorder
的實例。
修改上述代碼:添加BCryptPasswordEncoder
編碼器對密碼進行編碼。
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Autowired
private PasswordEncoder passwordEncoder;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password(passwordEncoder.encode("123456")).roles("USER").and()
.withUser("admin").password(passwordEncoder.encode("654321")).roles("USER","ADMIN");
}
}
再次訪問http://127.0.0.1:8080/security/hello,輸入賬號密碼即可成功訪問。
4 權限控制
Spring Security
支持方法方法級別的權限控制。
4.1 添加@EnableGlobalMethodSecurity
註解
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//other configures……
}
4.2 在相應方法上添加權限控制
在Controller
中添加新的訪問接口:
/**
* 擁有ADMIN權限的用戶才能訪問
* @return
*/
@PreAuthorize("hasAnyRole('ADMIN')")
@RequestMapping(value = "/admin",method = RequestMethod.GET)
public String helloAdmin() {
return "hello, admin";
}
/**
* 擁有ADMIN或USER權限的用戶才能訪問
* @return
*/
@PreAuthorize("hasAnyRole('ADMIN','USER')")
@RequestMapping(value = "/user",method = RequestMethod.GET)
public String helloUser() {
return "hello, user";
}
4.3 登錄測試
- 啓動項目,訪問http://127.0.0.1:8080/security/user,輸入
admin ,654321
,和user , 123456
,都可以訪問成功。 - 重啓項目,http://127.0.0.1:8080/security/admin,輸入
user , 123456
,會返回403錯誤。再次重啓,輸入admin ,654321
,可以正常訪問。
參考文檔
https://blog.csdn.net/m_sicily/article/details/102804608
https://docs.spring.io/spring-security/site/docs/5.3.2.BUILD-SNAPSHOT/reference/html5/