最近看了好幾個認證框架,什麼 Appache Shiro 啦、Sa-Token 啦、Spring Security啦。。。尤其是Spring Security,做為對標 Spring Boot & Cloud 的框架 Solon 怎麼的也要有自己的親生安全認證框架。所以在適配了 Sa-Token(satoken-solon-plugin) 和 sureness(sureness-solon-plugin) 之後,也開發了Solon 的親兒子:Solon Auth (solon.extend.auth)。設計目標是更加簡單些、更直接些,同時為使用者提供更豐富而不同的認證框架選擇。
Solon Auth (solon.extend.auth)
Solon Auth 的定位是,只做認證控制。側重對驗證結果的適配,及在此基礎上的統一控制和應用。功能會少,但適配起來不會暈。
Solon Auth 支援規則控制和註解控制兩種方案,各有優缺點,也可組合使用:
- 規則控制,適合在一個地方進行整體的巨集觀控制
- 註解控制,方便在細節處精準把握
一、開始適配,完成2步動作即可
- 第1步,構建一個認證介面卡
@Configuration
public class Config {
@Bean
public AuthAdapter init() {
//
// 構建介面卡
//
return new AuthAdapter()
.loginUrl("/login") //設定登入地址,未登入時自動跳轉(如果不設定,則輸出401錯誤)
.addRule(r -> r.include("**").verifyIp().failure((c, t) -> c.output("你的IP不在白名單"))) //新增規則
.addRule(b -> b.exclude("/login**").exclude("/run/**").verifyPath()) //新增規則
.processor(new AuthProcessorImpl()) //設定認證處理器
.failure((ctx, rst) -> { //設定預設的驗證失敗處理
ctx.render(rst);
});
}
}
//規則配置說明
//1.include(path) 規則包函的路徑範圍,可多個
//2.exclude(path) 規則排序的路徑池圍,可多個
//3.failure(..) 規則失則後的處理
//4.verifyIp()... 規則要做的驗證方案(可多個不同的驗證方案)
- 第2步,實現一個認證處理器
先了解一下 AuthProcessor 的介面,它對接的是一系列的驗證動作結果。可能使用者得自己也得多幹點活,但很直觀。
//認證處理器
public class AuthProcessorImpl implements AuthProcessor {
@Override
public boolean verifyIp(String ip) {
//驗證IP,是否有權訪問
}
@Override
public boolean verifyLogined() {
//驗證登入狀態,使用者是否已登入
}
@Override
public boolean verifyPath(String path, String method) {
//驗證路徑,使用者可訪問
}
@Override
public boolean verifyPermissions(String[] permissions, Logical logical) {
//驗證特定許可權,使用者是權有限
}
@Override
public boolean verifyRoles(String[] roles, Logical logical) {
//驗證特定角色,使用者是否角色
}
}
現在做一次適配實戰,用的是一份生產環境的程式碼:
public class AuthProcessorImpl implements AuthProcessor {
private int puid() {
return Context.current().session("puid", 0);
}
@Override
public boolean verifyIp(String ip) {
return true; //ip不限制,直接返回true
}
@Override
public boolean verifyLogined() {
return puid() > 0; //使用者id大於0,說明已登入
}
@Override
public boolean verifyPath(String path, String method) {
try {
if (BcfClient.hasUrlpath(path)) {
return BcfClient.hasUrlpathByUser(puid(), path);
} else {
return true;
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public boolean verifyPermissions(String[] permissions, Logical logical) {
int puid = puid();
try {
if (logical == Logical.AND) {
boolean isOk = true;
for (String p : permissions) {
isOk = isOk && BcfClient.hasResourceByUser(puid, p);
}
return isOk;
} else {
for (String p : permissions) {
if (BcfClient.hasResourceByUser(puid, p)) {
return true;
}
}
return false;
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public boolean verifyRoles(String[] roles, Logical logical) {
int puid = puid();
try {
if (logical == Logical.AND) {
boolean isOk = true;
for (String p : roles) {
isOk = isOk && BcfClient.isUserInGroup(puid, p);
}
return isOk;
} else {
for (String p : roles) {
if (BcfClient.isUserInGroup(puid, p)) {
return true;
}
}
return false;
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
二、2種應用方式(一般組合使用)
剛才我們算是適配好了,現在就應用的活了。
- 第1種,在 AuthAdapter 直接配置所有規則,或部分規則(也可以不配)
//參考上面的介面卡 addRule(...)
配置的好處是,不需要侵入業務程式碼;同時在統一的地方,巨集觀可見;但容易忽略掉細節。
- 第2種,基於註解做一部份(一般特定許可權 或 特定角色時用)
@Mapping("/rock/agroup")
@Controller
public class AgroupController {
@Mapping("")
public void home() {
//agroup 首頁
}
@Mapping("inner")
public void inner() {
//內部列表頁
}
@AuthPermissions("agroup:edit") //需要特定許可權
@Mapping("edit/{id}")
public void edit(int id) {
//編輯顯示頁,需要編輯許可權
}
@AuthRoles("admin") //需要特定角色
@Mapping("edit/{id}/ajax/save")
public void save(int id) {
//編輯處理介面,需要管理員許可權
}
}
註解的好處是,微觀可見,在一個方法上就可以看到它需要什麼許可權或角色,不容易忽略。
- 組合使用方式
一般,用配置規則
,控制所有需要登入的地址;用註解
,控制特定的許可權或角色。
三、本案原始碼
https://gitee.com/noear/solon_demo/tree/master/demo16.solon_auth
四、其它生產專案應用
https://gitee.com/noear/water/tree/master/wateradmin
https://gitee.com/noear/sponge/tree/main/spongeadmin
附:Solon 專案地址
附:Solon 其它入門示例
- Solon 入門教程示例:https://gitee.com/noear/solon_demo
- Solon Rpc 入門教程示例:https://gitee.com/noear/solon_rpc_demo
- Solon Cloud 入門教程示例:https://gitee.com/noear/solon_cloud_demo
- Solon 進階教程示例:https://gitee.com/noear/solon_advance_demo