Solon Web 开发,十、签权
1、认识 solon.auth 框架
solon.auth 的定位是,只做认证控制。侧重对验证结果的适配,及在此基础上的统一控制和应用。功能会少,但适配起来不会晕。同时支持规则控制和注解控制两种方案,各有优缺点,也可组合使用:
- 规则控制,适合在一个地方进行整体的宏观控制
- 注解控制,方便在细节处精准把握
2、开始适配,完成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 GritAuthProcessor implements AuthProcessor {
/**
* 获取主体Id
* */
protected long getSubjectId() {
return SessionBase.global().getSubjectId();
}
/**
* 获取主体显示名
*/
protected String getSubjectDisplayName() {
return SessionBase.global().getDisplayName();
}
@Override
public boolean verifyIp(String ip) {
//安装模式,则忽略
if (Solon.cfg().isSetupMode()) {
return true;
}
long subjectId = getSubjectId();
if (subjectId > 0) {
String subjectDisplayName = getSubjectDisplayName();
Context ctx = Context.current();
if (ctx != null) {
//old
ctx.attrSet("user_puid", String.valueOf(subjectId));
ctx.attrSet("user_name", subjectDisplayName);
//new
ctx.attrSet("user_id", String.valueOf(subjectId));
ctx.attrSet("user_display_name", subjectDisplayName);
}
}
//非白名单模式,则忽略
if (Solon.cfg().isWhiteMode() == false) {
return true;
}
return CloudClient.list().inListOfClientAndServerIp(ip);
}
@Override
public boolean verifyLogined() {
//安装模式,则忽略
if (Solon.cfg().isSetupMode()) {
return true;
}
return getSubjectId() > 0;
}
@Override
public boolean verifyPath(String path, String method) {
//安装模式,则忽略
if (Solon.cfg().isSetupMode()) {
return true;
}
try {
if (GritClient.global().resource().hasResourceByUri(path) == false) {
return true;
} else {
return GritClient.global().auth().hasUri(getSubjectId(), path);
}
} catch (SQLException e) {
throw new GritException(e);
}
}
@Override
public boolean verifyPermissions(String[] permissions, Logical logical) {
long subjectId = getSubjectId();
try {
if (logical == Logical.AND) {
boolean isOk = true;
for (String p : permissions) {
isOk = isOk && GritClient.global().auth().hasPermission(subjectId, p);
}
return isOk;
} else {
for (String p : permissions) {
if (GritClient.global().auth().hasPermission(subjectId, p)) {
return true;
}
}
return false;
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public boolean verifyRoles(String[] roles, Logical logical) {
long subjectId = getSubjectId();
try {
if (logical == Logical.AND) {
boolean isOk = true;
for (String r : roles) {
isOk = isOk && GritClient.global().auth().hasRole(subjectId, r);
}
return isOk;
} else {
for (String r : roles) {
if (GritClient.global().auth().hasRole(subjectId, r)) {
return true;
}
}
return false;
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
3、两种应用方式(一般组合使用)
刚才我们算是适配好了,现在就应用的活了。
- 第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) {
//编辑处理接口,需要管理员权限
}
}
注解的好处是,微观可见,在一个方法上就可以看到它需要什么权限或角色,不容易忽略。
- 组合使用方式
一般,用配置规则,控制所有需要登录的地址;用注解,控制特定的权限或角色。
Solon Web 开发,十、签权的更多相关文章
- Solon Web 开发,十二、统一的渲染控制
Solon Web 开发 一.开始 二.开发知识准备 三.打包与运行 四.请求上下文 五.数据访问.事务与缓存应用 六.过滤器.处理.拦截器 七.视图模板与Mvc注解 八.校验.及定制与扩展 九.跨域 ...
- Solon Web 开发,十四、与Spring、Jsr330的常用注解对比
Solon Web 开发 一.开始 二.开发知识准备 三.打包与运行 四.请求上下文 五.数据访问.事务与缓存应用 六.过滤器.处理.拦截器 七.视图模板与Mvc注解 八.校验.及定制与扩展 九.跨域 ...
- Solon Web 开发
Solon Web 开发 一.开始 二.开发知识准备 三.打包与运行 四.请求上下文 五.数据访问.事务与缓存应用 六.过滤器.处理.拦截器 七.视图模板与Mvc注解 八.校验.及定制与扩展 九.跨域 ...
- Solon Web 开发,一、开始
Solon Web 开发 一.开始 二.开发知识准备 三.打包与运行 四.请求上下文 五.数据访问.事务与缓存应用 六.过滤器.处理.拦截器 七.视图模板与Mvc注解 八.校验.及定制与扩展 九.跨域 ...
- Solon Web 开发,二、开发知识准备
Solon Web 开发 一.开始 二.开发知识准备 三.打包与运行 四.请求上下文 五.数据访问.事务与缓存应用 六.过滤器.处理.拦截器 七.视图模板与Mvc注解 八.校验.及定制与扩展 九.跨域 ...
- Solon Web 开发,四、请求上下文
Solon Web 开发 一.开始 二.开发知识准备 三.打包与运行 四.请求上下文 五.数据访问.事务与缓存应用 六.过滤器.处理.拦截器 七.视图模板与Mvc注解 八.校验.及定制与扩展 九.跨域 ...
- Solon Web 开发,五、数据访问、事务与缓存应用
Solon Web 开发 一.开始 二.开发知识准备 三.打包与运行 四.请求上下文 五.数据访问.事务与缓存应用 六.过滤器.处理.拦截器 七.视图模板与Mvc注解 八.校验.及定制与扩展 九.跨域 ...
- Solon Web 开发,六、过滤器、处理、拦截器
Solon Web 开发 一.开始 二.开发知识准备 三.打包与运行 四.请求上下文 五.数据访问.事务与缓存应用 六.过滤器.处理.拦截器 七.视图模板与Mvc注解 八.校验.及定制与扩展 九.跨域 ...
- Solon Web 开发,七、视图模板与Mvc注解
Solon Web 开发 一.开始 二.开发知识准备 三.打包与运行 四.请求上下文 五.数据访问.事务与缓存应用 六.过滤器.处理.拦截器 七.视图模板与Mvc注解 八.校验.及定制与扩展 九.跨域 ...
- Solon Web 开发,八、校验、及定制与扩展
Solon Web 开发 一.开始 二.开发知识准备 三.打包与运行 四.请求上下文 五.数据访问.事务与缓存应用 六.过滤器.处理.拦截器 七.视图模板与Mvc注解 八.校验.及定制与扩展 九.跨域 ...
随机推荐
- 如何系统学习Python?
学习 Python 可以通过以下系统性的步骤进行: 1. 设定学习目标 确定你学习 Python 的主要目的,是为了编写脚本.数据分析.Web 开发.机器学习还是其他应用?理解这个目标可以帮助你更有针 ...
- C语言输入一个三位的正整数,按逆序打印出该数的各位数字。
#include <stdio.h> int main() { int n, a, b, c;//定义3位数,个位数,十位数,百位数变量 scanf_s("%d", & ...
- 通过Spring MVC 实现 Restful 风格请求⽀持
通过Spring MVC可以很方便地实现Restful风格的请求支持.Restful风格的请求是一种基于HTTP协议的轻量级的Web服务架构风格,它通过HTTP的GET.POST.PUT.DELETE ...
- 一个NET8 AOT编译的辅助项目,让你的任何可执行应用快速部署为服务
不知道大家有没有和小编一样,很多时候想将自己的一些应用转为服务运行,比如一些控制台应用或者.NET Core应用,但是又不想重新编码,把他们转为服务,本文将给大家提供些我使用过的方法,并提供一个基于N ...
- 提升开发技能:10个高级的JavaScript技巧
前言 在这个快速发展的数字时代,JavaScript作为一种广泛应用的编程语言,其重要性愈发凸显.为了在竞争激烈的开发领域中保持竞争力,不断提升自己的技能是至关重要的.本文小编将您介绍10个高级的Ja ...
- mysql--基础管理
1.docker环境登录mysql PS C:\WINDOWS\system32> docker ps -aCONTAINER ID IMAGE COMMAND CREATED STATUS P ...
- AtomicArray
AtomicInteger ai = new AtomicInteger(1); //1.获取值 System.out.println("ai.get = "+ai.get()); ...
- 向mq写消息
1.基础版本 import org.apache.rocketmq.client.producer.DefaultMQProducer; import org.apache.rocketmq.comm ...
- Storm 集群的搭建及其Java编程进行简单统计计算
一.Storm集群构建 编写storm 与 zookeeper的yml文件 storm yml文件的编写 具体如下: version: '2' services: zookeeper1: image: ...
- jenkins删除构建历史并重置构建序号
系统管理 工具和动作-->脚本命令执行 删除之前,现在已经构建了156次 输入脚本 println(Jenkins.instance.getJobNames()) //查看获取任务名列表//要 ...