SpringSecurity:hasAuthority與自定義許可權校驗

天启A發表於2024-07-24

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防禦的,所以這裡選擇了關閉

相關文章