借鉴jfinal-shiro-plugin在jfinal中嵌入shiro并支持注解

举报
KevinQ 发表于 2022/04/16 13:11:42 2022/04/16
【摘要】 对于支持注解的强迫症在上一篇文章jfinal中stateless模式嵌入shiro验证中我们已经成功嵌入了shiro,但是呢,有个小缺陷,并没有支持shiro的注解,例如,如下方式并不能触发权限验证:@RequiresPermissions("all")public void test() { renderText("测试");}在我们看来,以及在《Effective Java》的作...

对于支持注解的强迫症

在上一篇文章jfinal中stateless模式嵌入shiro验证中我们已经成功嵌入了shiro,但是呢,有个小缺陷,并没有支持shiro的注解,例如,如下方式并不能触发权限验证:

@RequiresPermissions("all")
public void test() {
    renderText("测试");
}

在我们看来,以及在《Effective Java》的作者看来,注解都是非常优雅的一种实现方式。如果不使用注解,要实现上述代码的功能,需要怎么做呢?

不使用注解的方式

如果不使用注解,就需要我们在代码中具体指明其执行逻辑,就上面的例子来说,没有注解而具有同样功能的代码如下:

	public void test() {
		Subject s = SecurityUtils.getSubject();
		s.checkPermission("all");
		renderText("测试");
	}

即需要我们手动的来获取对象以及执行对象的检查权限方法。

对于shiro注解的支持

这里我们找到了jfinal-shiro-plugin是支持注解的,因此,首先我们按照jfinal-shiro-plugin的方式,将其所有代码搬移过来。(在文章jfinal中stateless模式嵌入shiro验证中已经阐述了搬移的原因:即jfinal4.8对于jfinal-shiro-plugin无法兼容,执行报错)

在搬移了其源码后,首先按照jfinal-shiro-plugin的方式,在程序入口进行配置,包括拦截器与插件,具体代码如下:

/**
	 * 配置全局拦截器
	 */
	public void configInterceptor(Interceptors me) {
        // 这里可能还会有别的拦截器
		me.add(new ShiroInterceptor());
	}

配置插件:

/**
	 * 配置插件
	 */
	public void configPlugin(Plugins me) {

		// 这里可能还会有数据库,redis,定时等插件
		Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
		org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance();
		SecurityUtils.setSecurityManager(securityManager);

		ShiroPlugin shiroPlugin = new ShiroPlugin(this.routes);
		me.add(shiroPlugin);
	}

上面代码中shiroPlugin构造函数中的routes需要我们对程序入口做一点小小的改造:

Routes routes = null;

/**
	 * 配置路由
	 */
	public void configRoute(Routes me) {
		
        me.add("/", IndexController.class, "/index");
        // 其他路由
		this.routes = me;
	}

核心:每次调用首先执行subject.login()

需要对shiro的拦截器做一点小小的修改:

public void intercept(Invocation ai) {
    	/////////////////自己添加的代码
		String token = ai.getController().getHeader("token");
		if (StrKit.notBlank(token)) {
			Subject s = SecurityUtils.getSubject();
			JWTToken jwtToken = new JWTToken(token);
			s.login(jwtToken);
		}
    	//////////////////

		AuthzHandler ah = ShiroKit.getAuthzHandler(ai.getActionKey());
		// 存在访问控制处理器。
		if (ah != null) {
			Controller  c = ai.getController();
			try {
				// 执行权限检查。
				ah.assertAuthorized();
            }
        }
    	// 这里省略了ShiroInterceptor的其他代码
}

我们首先在拦截器入口添加一个获取token已经调用shiro登录的方法,以便后续shiro能够成功的获取到当前登录对象,以及做权限验证等等。

这里的验证方式完全可以自定义,我们所使用的方式是登录的时候获取完全随机的token串,并将其设置到redis中,每次验证登录,从redis中根据token获取对象信息。

当然,也可以参考JWT方式,对登录人信息加密与解密来获取用户信息。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

举报
请填写举报理由
0/200