[Shiro]多Realm时,指定登录Realm

来源:互联网 发布:mac mini能玩lol吗 编辑:程序博客网 时间:2024/06/05 17:14

[Shiro]多Realm时,指定登录Realm

之前写过多Realm登录前后台区分问题,实现了当时的需求,可是再下一步的时候,角色与权限校验会失效。为了满足当时的项目需求,又拓展了鉴权源,以及若干功能类。在本人看来,这种方式很Low,玷污了Shiro。
现在有一个较好的方式去实现前后台的认证与鉴权。通过自定义Token类来达到鉴别目的。


Token的介绍

Shiro使用Token作为认证的对象。 在Filter中拦截登录信息创建Token调用登录,或者我们自己在控制器中手动登录。调用登录,会迭代配置的Realm进行验证。

Shiro的FormAuthenticationFilter创建Token

FormAuthenticationFilter中创建Token的方法
FormAuthenticationFilter

最终调用到它的父类AuthenticatingFilter
AuthenticatingFilter

控制器里手动创建Token登录

这里写图片描述

Realm的定义

Shiro在进行登录验证时候,会检查Realm是否支持该Token,如果不支持跳过当前Realm,继续下一个Realm。

    public Class getAuthenticationTokenClass() {        //支持的Token类的class        return authenticationTokenClass;    }    //是否支持该token    //Realm支持的类可以是token的子类或相同    public boolean supports(AuthenticationToken token) {        return token != null &&    getAuthenticationTokenClass().isAssignableFrom(token.getClass());    }

自定义Realm一般会继承AuthorizingRealm来支持登录的验证。

我们可以重写public Class getAuthenticationTokenClass()来支持我们的Token。

自定义Token

Shiro的UsernamePasswordToken源码

public class UsernamePasswordToken implements HostAuthenticationToken, RememberMeAuthenticationToken {    private String username;    private char[] password;    private boolean rememberMe = false;    private String host;    public UsernamePasswordToken() {    }    public UsernamePasswordToken(final String username, final char[] password) {        this(username, password, false, null);    }    public UsernamePasswordToken(final String username, final String password, final String host) {        this(username, password != null ? password.toCharArray() : null, false, host);    }    public Object getPrincipal() {        return getUsername();    }    public Object getCredentials() {        return getPassword();    }    public String getHost() {        return host;    }    public void setHost(String host) {        this.host = host;    }    public boolean isRememberMe() {        return rememberMe;    }    public void setRememberMe(boolean rememberMe) {        this.rememberMe = rememberMe;    }    public void clear() {        this.username = null;        this.host = null;        this.rememberMe = false;        if (this.password != null) {            for (int i = 0; i < password.length; i++) {                this.password[i] = 0x00;            }            this.password = null;        }    }}

UsernamePasswordToken实现了AuthenticationToken(认证)、HostAuthenticationToken(用户ip)、RememberMeAuthenticationToken(记住我)接口。

AuthenticationToken

public interface AuthenticationToken extends Serializable {    /**    *获取登陆用户名    */    Object getPrincipal();    /**     *获取密码     */    Object getCredentials();}

由于Realm检查是否支持Token类的是允许支持验证子类的,我们不能去继承UsernamePasswordToken,需要自己实现一个Token。直接拷贝代码,修改类名就可以。或者根据你的业务需求,重写一部分功能。


每一个自定义Realm对应支持一种Token。就可以使登录验证时不会重复调用Realm多次验证和异常消息的覆盖。

[示例代码] https://git.oschina.net/yihyforever/shiro-realms.git

下一篇,Shiro的缓存及坑点

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 梅菜扣肉勾芡怎么办 有个精神病妈妈怎么办 妈得了精神病该怎么办 思维不正常的人怎么办 妈妈是个精神病怎么办 我老婆有精神病怎么办 在郑州怎么办完税证明 中专没考上大专怎么办 考研两次没考上怎么办 2018造价员取消后怎么办 造价员取消了投标怎么办 造价员考试取消后怎么办 只拿到结业证怎么办 本科只有结业证怎么办 健身后肌肉水肿怎么办 大腿面肌肉疼怎么办 跑步后大腿酸疼怎么办? 运动后大腿胀痛怎么办 尔雅课程没看完怎么办 国家课程校本化怎么办 上海买房限购怎么办 投资公司要求回购股份怎么办 超过应届生落户年龄怎么办 造价员章到期了怎么办 造价员继续教育过期了怎么办 sd卡存储不够怎么办? 进项税大于销项税怎么办 公司扣员工奖金怎么办 墙面大面积有霉怎么办 电脑总是断网怎么办 造价师资格证书丢了怎么办 行测做题速度太慢怎么办 普通话准考证丢了怎么办 信用卡还款逾期了怎么办 淮北建洗煤厂需要怎么办 建设工程不结算怎么办 考监理没有职称怎么办 公开招标两次招标失败怎么办 山东省植保员证怎么办 工伤没开病假单怎么办 邮储银行怎么办金卡