springsecurity中有兩種許可權控制方法
1.基於註解
@PreAuthorize("hasAuthority('syst:add')")
他的作用是在controller方法上進行許可權校驗,如果該使用者具有對應的許可權則放行,否則丟擲AccessDeniedHandler,403(許可權不足)
2.基於配置
// 基於配置的許可權控制 http .authorizeRequests() .antMatchers("/example").hasAuthority("admin");
翻閱一下原始碼:
// 註解對應的最外層方法,傳入註解內對應的許可權字串,進入下一個方法
@Override
public final boolean hasAuthority(String authority) {
return hasAnyAuthority(authority);
}
// 繼續向下傳播
@Override
public final boolean hasAnyAuthority(String... authorities) {
return hasAnyAuthorityName(null, authorities);
}
// 上述prefix傳的是null,即不用處理字首問題(prefix是在role的判斷時使用的) roles即authorities
// 這個方法即透過getAuthoritySet取得一個當前使用者的許可權集合,然後和roles一一比對,一旦有成功則返回true即可以放行
private boolean hasAnyAuthorityName(String prefix, String... roles) {
Set<String> roleSet = getAuthoritySet();
for (String role : roles) {
String defaultedRole = getRoleWithDefaultPrefix(prefix, role);
if (roleSet.contains(defaultedRole)) {
return true;
}
}
return false;
}
//getRoleWithDefaultPrefix就是拼勁字串不寫了
//getAuthoritySet意思很直白,程式碼看不太懂,不寫了喵。
自定義一份hasAuthority:(效果和系統自帶的是一樣的,這裡只是演示如何實現)
//取出當前使用者的所有許可權,和註解提供的許可權一一比對,
@Component public class AuthorityExpression { public boolean hasAuthority(String authority) { Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); LoginUser loginUser=(LoginUser) principal; List<String> permissions = loginUser.getPermissions(); return permissions.contains(authority); } }
el表示式:使用自定義許可權校驗@beanName.method
@PreAuthorize("@authorityExpression.hasAuthority('syst:list')")
securityConfig解讀:csrf
http
.csrf().disable()
這裡是指關閉了csrf防護,
什麼是csrf:攻擊者透過欺騙瀏覽器去訪問使用者認證過的站點,因為已經在瀏覽器認證過,所以瀏覽器會放行操作
csrf的成功離不開cookie,但是我們的前後端分離專案透過請求頭自定義的token可以有效防禦。也就是說,我們其實是不需要csrf防禦的,所以這裡選擇了關閉