JwtTokenPlugin--基于JwtToken的权限认证插件

最近做的项目都是前后端分离的,需要做一种无状态的认证机制,于是用上了jwtToken这种标准,来进行认证,介于shiro里面的东西太多,没空研究,而且需求用不到那么多特性,开发了一款基于JwtToken的一个Jfinal认证插件,以及权限,角色访问控制。

地址:https://git.oschina.net/Danjinsong/JFinal-JwtTokenPlugin.git

使用方法 :

  • 添加插件

  • @Override
    public void configPlugin(Plugins me) {
        me.add(new JwtTokenPlugin(UserService.me));                                /**配置权限拦截插件*/
    }
  • 让Model实现IJwtAble接口

/**
 * 我有故事,你有酒么?
 * JKhaled created by yunqisong@foxmail.com 2017/9/5
 * FOR : 简单实现
 */
public class User implements IJwtAble {

    private String userName;

    private String password;

    private List<String> _roles;

    private List<String> _forces;

    /**
     * 当前用户的角色
     *
     * @return
     */
    @Override
    public List<String> getRoles() {
        // 使用的时候写通过数据库查询返回给插件一个角色集合
        return get_roles();
    }

    /**
     * 当前用户的权限
     *
     * @return
     */
    @Override
    public List<String> getForces() {
        // 使用的时候写通过数据库查询返回给插件一个角色集合
        return get_forces();
    }

    /**
     * 上次修改密码时间
     *
     * @return
     */
    @Override
    public Date getLastModifyPasswordTime() {

        return new Date(System.currentTimeMillis() - 60L * 1000L * 60L * 24);
    }



    public String getUserName() {
        return userName;
    }

    public User setUserName(String userName) {
        this.userName = userName;
        return this;
    }

    public String getPassword() {
        return password;
    }

    public User setPassword(String password) {
        this.password = password;
        return this;
    }

    public User setRoles(List<String> roles) {
        this._roles = roles;
        return this;
    }

    public User setForces(List<String> forces) {
        this._forces = forces;
        return this;
    }

    public List<String> get_roles() {
        return _roles;
    }

    public List<String> get_forces() {
        return _forces;
    }
}
  • 让你的Service实现登录接口

  • /**
     * 我有故事,你有酒么?
     * JKhaled created by yunqisong@foxmail.com 2017/9/5
     * FOR : 简单实现
     */
    public class UserService implements IJwtUserService {
        public static final UserService me = new UserService();
    
        private UserService() {
        }
    
        private static Kv store = Kv.create();
    
        static {
            store.set("admin",
                    new User().setForces(Arrays.asList("登录后台", "管理用户"))
                            .setRoles(Arrays.asList("管理员", "普通用户")).setUserName("admin").setPassword("123456")
            ).set("user",
                    new User().setForces(Arrays.asList("前台登录", "发布文章"))
                            .setRoles(Arrays.asList("普通用户")).setUserName("user").setPassword("123456")
            );
        }
    
        @Override
        public IJwtAble login(String userName, String password) {
            User user = (User) store.get(userName);// 假装登录验证
            if (user != null)
                return user;
            throw new RuntimeException("找不到用户");
        }
    }
  • 通过登录拿Token

  • public void login() {
        User user = getBean(User.class, "");
        String token = JwtKit.getToken(user.getUserName(), user.getPassword());
        renderJson(Ret.by("token", token));
    }

    image.png

  • 验证==

  • 没有登录

  • image.png

  • image.png

  • 通过验证的。

  • 权限验证代码如下


  • /**
     * 我有故事,你有酒么?
     * JKhaled created by yunqisong@foxmail.com 2017/9/5
     * FOR : 简单实现
     */
    public class UserController extends Controller {
    
        public void login() {
            User user = getBean(User.class, "");
            String token = JwtKit.getToken(user.getUserName(), user.getPassword());
            renderJson(Ret.by("token", token));
        }
    
        // 登录认证
        @Before(JwtTokenInterceptor.class)
        public void testLogin() {
            renderJson(Ret.ok());
        }
    
        @Auth(hasRoles = {"管理员"})
        public void testHasRole() {
            renderJson(Ret.ok());
        }
    
        @Auth(hasForces = {"登录后台"})
        public void testHasForce() {
            renderJson(Ret.ok());
        }
    
        @Auth(withRoles = {"管理员", "普通用户"})
        public void testWithRoles() {
            renderJson(Ret.ok());
        }
    
        @Auth(withForces = {"登录后台", "管理用户"})
        public void testWithForces() {
            renderJson(Ret.ok());
        }
    
    }

    注解说明:


  • public @interface Auth {
    
        String[] hasForces() default {};               // 需要的权限 满足一个就可以访问--优先级第三
    
        String[] hasRoles() default {};                // 满足的角色 满足一个就可以访问--优先级第四
    
        String[] withForces() default {};              // 需要的权限 满足全部才可以访问--优先级第一
    
        String[] withRoles()  default {};              // 满足的橘色 满足全部才可以访问--优先级第二
    
    }
Auth注解适用于方法和类,注意:方法上的注解会覆盖掉类上的权限注解。欢迎大家测试,使用

评论区

穿越123

2017-09-06 09:51

牛逼

djs19960601

2017-09-06 10:57

@穿越123 菜的抠脚。。试试看,欢迎反馈bug

圆教授

2017-09-06 12:56

测试http请求用的什么插件呀

JFinal

2017-09-06 13:03

这个实现很简洁, 不知道用在项目中是个什么样子,有例子没?

要输就输给追求

2017-09-06 14:03

看起来使用很简单,先收藏了

djs19960601

2017-09-06 14:32

@JFinal 有的在git上插件中有example包就是例子

djs19960601

2017-09-06 14:32

@圆教授 postman,超级好用

djs19960601

2017-09-06 14:33

@要输就输给追求 下下代码看看,有例子公司项目已经实战了,目前没问题

圆教授

2017-09-06 14:56

@djs19960601 谢谢 , 我试试

guanxb

2017-09-06 15:36

刚刚试了,不错。会不会有Forces和Roles要同时满足的情况

djs19960601

2017-09-06 15:56

@guanxb 这个需求是会有的,可以再增加一个注解。有时间就写出来

guanxb

2017-09-06 16:01

@djs19960601 把权限的4个数组全得到做个交叉验证就可以吧,不加新注解感觉并不太好

JFinal

2017-09-06 16:50

@djs19960601 没注意看 ^_^

djs19960601

2017-09-06 20:17

@guanxb 嗯,我试试看

zzhkiller

2017-09-07 09:32

6666, 我也喜欢这样写比较简单清晰的问题

要输就输给追求

2017-09-07 09:37

@djs19960601 是不是加密配置一样,跨域也不会有问题?

穿越123

2017-09-07 10:12

@djs19960601 你这个分享代码是怎么做的

djs19960601

2017-09-07 11:35

@zzhkiller 谢谢支持

djs19960601

2017-09-07 11:38

@要输就输给追求 token加密采用的jwtToken协议中的公共非对称加密你可以自己设置秘钥,有设置秘钥的构造方法,数据库的加密是你自己的策略你提供一个查询的方法,在接口里面就行。跨域需要自己配置Jfinal的Handler很简单,我到时候在上传一个跨域的范本

djs19960601

2017-09-07 11:39

@穿越123 啥?分享代码就是上传到GitOSChina上啊。我的插件里面提供了一个简单使用示例

穿越123

2017-09-07 15:54

@djs19960601 就你发布代码到jfinal社区代码有颜色是怎么做到的

djs19960601

2017-09-07 17:53

@穿越123 你在发布代码的时候选择波总的富文本编辑器的语言为Java就行了

穿越123

2017-09-08 08:59

@djs19960601 选择语言java就有背景颜色了?

djs19960601

2017-09-08 09:05

@穿越123 发出来就有了

穿越123

2017-09-08 09:06

热门分享

扫码入社