c/c++语言开发共享jfinal中stateless模式嵌入shiro验证的实现方式

问题起源在前些天的文章中,我们了解到困惑了我们好几天的问题是由于jfinal新版中使用undertowserver方式启动,其嵌入filter的方式有变动,所以导致网上检索到的通过web.xml嵌入f

问题起源

在前些天的文章中,我们了解到困惑了我们好几天的问题是由于jfinal新版中使用undertowserver方式启动,其嵌入filter的方式有变动,所以导致网上检索到的通过web.xml嵌入filter失败。

在不考虑修改undertowserver的情况下,也就意味着我们需要找到一种在undertowserver环境下,嵌入shiro的方式。

今天,我们就来尝试一种通过拦截器来实现的stateless jfinal 嵌入方式。

stateless的理解

个人对stateless的理解就是前后端分离,两次请求互相独立,通过约定的token等内容判断是否是同一个用户。

因此这要求,登录接口需要给用户生成一个随机的token,以便用户后续访问的时候带上。

登录接口

登录接口首先需要我们访问数据库,以及通过特定算法来验证用户名与密码是否匹配。如果匹配,则生成随机的字符串,即token,并保存在redis中,注意,映射关系是token为key,value为用户信息,可以是用户名,也可以是用户id等用户唯一标识。

@clear  public void login() {      string name = getpara("name");      string password = getpara("password");      if ("admin".equals(name)) { // todo 判断密码与用户名是否正确          cache cache = redis.use();          string token = strkit.getrandomuuid();          cache.set("token:" + token, name);          rendertext(token);      } else {          rendertext("用户名与密码错误");      }  }

另外,需要注意的有两点:

  • 接口前调用@clear,即登录接口不应该被拦截验证
  • 系统的登录接口,与shiro中的subject.login应该注意区分,是两个不同的概念。

自定义拦截器

package com.holdoa.core.interceptor;  import com.holdoa.core.controller.basecontroller;  import com.holdoa.core.filter.jwttoken;  import com.jfinal.aop.interceptor;  import com.jfinal.aop.invocation;  import com.jfinal.core.controller;  import com.jfinal.kit.logkit;  import com.jfinal.kit.strkit;  import org.apache.shiro.securityutils;  import org.apache.shiro.aop.methodinvocation;  import org.apache.shiro.authz.authorizationexception;  import org.apache.shiro.authz.aop.annotationsauthorizingmethodinterceptor;  import org.apache.shiro.subject.subject;  import java.lang.reflect.method;  public class myshirointerceptor extends annotationsauthorizingmethodinterceptor implements interceptor {  	       public myshirointerceptor() {          getmethodinterceptors();      }         public void intercept(final invocation inv) {          try {              string token = inv.getcontroller().getheader("token");              if (strkit.isblank(token)) {                  basecontroller b = (basecontroller) inv.getcontroller();                  b.renderapperror("缺少token");                  return;              } else {                  subject s = securityutils.getsubject();                  jwttoken jwttoken = new jwttoken(token);                  s.login(jwttoken);                  inv.invoke();              }          } catch (throwable e) {              if (e instanceof authorizationexception) {                  doprocessuunauthorization(inv.getcontroller());              }              logkit.warn("权限错误:", e);              try {                  throw e;              } catch (throwable throwable) {                  throwable.printstacktrace();              }          }      }         /**       * 未授权处理       *       * @param controller controller       */      private void doprocessuunauthorization(controller controller) {          controller.redirect("/login/nologin");      }  }

上面的代码很长,我们重点看其中的这几行:

string token = inv.getcontroller().getheader("token");  if (strkit.isblank(token)) {      basecontroller b = (basecontroller) inv.getcontroller();      b.renderapperror("缺少token");      return;  } else {      subject s = securityutils.getsubject();      jwttoken jwttoken = new jwttoken(token);      s.login(jwttoken);      inv.invoke();  }  

逻辑可以描述为:获取token,若不为空,将其转换为jwttoken对象,然后调用shiro的登录接口:s.login(jwttoken)

而shiro的login方法会触发自定义realm中的验证接口:

/**  	 * 自定义认证  	 */  	@override  	protected authenticationinfo dogetauthenticationinfo(authenticationtoken auth) throws authenticationexception {  		string token = (string) auth.getcredentials();  		 // 解密获得username,用于和数据库进行对比          string username = jwtutils.getusername(token);          if (username == null || username == "") {              throw new authenticationexception("token 校验失败");          }  		return new simpleauthenticationinfo(token, token, getname());  	}

其中,jwtutils。getusername的具体代码如下,和设置token是对应的:

/**       * @return token中包含的用户名       */      public static string getusername(string token) {  		cache cache = redis.use();  		string username = (string)cache.get(rediskeyprefix.new_oa_manage_token_prefix + token);  		return username;      }

如此,便做到了shiro的嵌入。

遗留问题

目前欠缺的一个问题是,不能实现shiro的注解来进行权限验证,这个问题我们还准备借助shiroplugin来实现,由于jfinal已经升级到4.8了,而shiroplugin目前还停留在支持jfinal 3.x的版本,所以需要我们下载jfianl-shiro-plugin源码做一些修改。

到此这篇关于jfinal中stateless模式嵌入shiro验证的实现方式的文章就介绍到这了,更多相关jfinal shiro验证内容请搜索<计算机技术网(www.ctvol.com)!!>以前的文章或继续浏览下面的相关文章希望大家以后多多支持<计算机技术网(www.ctvol.com)!!>!

需要了解更多c/c++开发分享jfinal中stateless模式嵌入shiro验证的实现方式,都可以关注C/C++技术分享栏目—计算机技术网(www.ctvol.com)!

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/c-cdevelopment/1237701.html

(0)
上一篇 2022年9月10日
下一篇 2022年9月10日

精彩推荐