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 开发,十、签权的更多相关文章

  1. Solon Web 开发,十二、统一的渲染控制

    Solon Web 开发 一.开始 二.开发知识准备 三.打包与运行 四.请求上下文 五.数据访问.事务与缓存应用 六.过滤器.处理.拦截器 七.视图模板与Mvc注解 八.校验.及定制与扩展 九.跨域 ...

  2. Solon Web 开发,十四、与Spring、Jsr330的常用注解对比

    Solon Web 开发 一.开始 二.开发知识准备 三.打包与运行 四.请求上下文 五.数据访问.事务与缓存应用 六.过滤器.处理.拦截器 七.视图模板与Mvc注解 八.校验.及定制与扩展 九.跨域 ...

  3. Solon Web 开发

    Solon Web 开发 一.开始 二.开发知识准备 三.打包与运行 四.请求上下文 五.数据访问.事务与缓存应用 六.过滤器.处理.拦截器 七.视图模板与Mvc注解 八.校验.及定制与扩展 九.跨域 ...

  4. Solon Web 开发,一、开始

    Solon Web 开发 一.开始 二.开发知识准备 三.打包与运行 四.请求上下文 五.数据访问.事务与缓存应用 六.过滤器.处理.拦截器 七.视图模板与Mvc注解 八.校验.及定制与扩展 九.跨域 ...

  5. Solon Web 开发,二、开发知识准备

    Solon Web 开发 一.开始 二.开发知识准备 三.打包与运行 四.请求上下文 五.数据访问.事务与缓存应用 六.过滤器.处理.拦截器 七.视图模板与Mvc注解 八.校验.及定制与扩展 九.跨域 ...

  6. Solon Web 开发,四、请求上下文

    Solon Web 开发 一.开始 二.开发知识准备 三.打包与运行 四.请求上下文 五.数据访问.事务与缓存应用 六.过滤器.处理.拦截器 七.视图模板与Mvc注解 八.校验.及定制与扩展 九.跨域 ...

  7. Solon Web 开发,五、数据访问、事务与缓存应用

    Solon Web 开发 一.开始 二.开发知识准备 三.打包与运行 四.请求上下文 五.数据访问.事务与缓存应用 六.过滤器.处理.拦截器 七.视图模板与Mvc注解 八.校验.及定制与扩展 九.跨域 ...

  8. Solon Web 开发,六、过滤器、处理、拦截器

    Solon Web 开发 一.开始 二.开发知识准备 三.打包与运行 四.请求上下文 五.数据访问.事务与缓存应用 六.过滤器.处理.拦截器 七.视图模板与Mvc注解 八.校验.及定制与扩展 九.跨域 ...

  9. Solon Web 开发,七、视图模板与Mvc注解

    Solon Web 开发 一.开始 二.开发知识准备 三.打包与运行 四.请求上下文 五.数据访问.事务与缓存应用 六.过滤器.处理.拦截器 七.视图模板与Mvc注解 八.校验.及定制与扩展 九.跨域 ...

  10. Solon Web 开发,八、校验、及定制与扩展

    Solon Web 开发 一.开始 二.开发知识准备 三.打包与运行 四.请求上下文 五.数据访问.事务与缓存应用 六.过滤器.处理.拦截器 七.视图模板与Mvc注解 八.校验.及定制与扩展 九.跨域 ...

随机推荐

  1. [Python急救站课程]猜拳游戏

    猜拳游戏 import random # 调用random函数库 while True: x = random.randint(0, 2) # 调用库里的randint函数使用随机数. print(& ...

  2. mysql 代码适配 postgresql 适配改写,优化案例(行转列 + 标量子查询改写)

    最近在适配个MySQL应用的项目,各种SQL改成PG兼容的语法真的是脑壳痛,今天遇到个有意思的案例. 原 MySQL SQL语句: SELECT DISTINCT l.MALL_NAME '项目', ...

  3. git中的ole mode 和 new mode提示问题

    git status 显示如下(文件内容其实并没有改变): old mode 100644 new mode 100755 原因是: 使用chmod修改过文件权限后,filemode会有变化. 解决办 ...

  4. String 的 indexOf 与 search 方便的区别

    String 这个对象里面包含许多方法 今天只要讲 indexOf 与 search 1.indexOf stringObject.indexOf(searchvalue,fromindex) 2.s ...

  5. Vue 2.x源码学习:数据响应式改造

    内容乃本人学习Vue2源码的一点笔记,若有错误还望指正. 源码版本: vue: 2.6 vue-loader: 13.x vue-template-compiler: 2.6 相关学习笔记: rend ...

  6. 【学到一个新名词】String interning(字符串驻留/字符串内部化)

    作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢! cnblogs博客 zhihu Github 公众号:一本正经的瞎扯 在阅读 VictoriaMetrics v1.95.1 的 ...

  7. vue通过地址下载文件

    通过a标签 // 创建a标签 const link = document.createElement('a') // download属性 link.setAttribute('download', ...

  8. css零散笔记——修改input样式input:-internal-autofill-selected背景色

    闲聊: 小颖项目中的登录页需将  input  背景色设为透明,小颖将 input  的背景色设置后,发现表单自动填充后还是会有背景色,然后发现 浏览器 自带了背景色: 效果图:           ...

  9. 【Javaweb】做一个房产信息管理系统三(src目录的部署工作【三层框架】各个层含义)

    接下来,我打算进行Java文件的部署工作,但实际上为了得到更多的分数,我们还是应该先做页面 首先我们需要了解对于Javaweb,src下的目录应该如何部署:(三层架构单独开一篇讲) 那么这些都有什么含 ...

  10. Ingress & Ingress Controller & API Gateway

    Ingress Ingress 内部服务如何暴露给集群外部访问 使用NodePort类型的service 将k8s集群中的服务暴露给集群外部访问,最简单的方式就是使用NodePort,类似在docke ...