Realm是shiro比较核心的接口,简单说它的实现类就是校验用户输入的账号信息的地方.如果想自定义实现一般的配置文件如下:

<!--自定义Realm 继承自AuthorizingRealm -->
<bean id="userRealm" class="xxx.UserRealm">
<!-- 自定义比对器 -->
<property name="credentialsMatcher" ref="myCredentialsMatcher"></property>
</bean>
<!-- 自定义匹配器 继承自SimpleCredentialsMatcher -->
<bean id="myCredentialsMatcher" class="xxx.MyCredentialsMatcher"></bean>

其中类的关键代码:

public class UserRealm extends AuthorizingRealm {

    public UserRealm() {
super();
}
@Override
protected AuthorizationInfo doGetAuthorizationInfo(
PrincipalCollection principals) {
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
//这里返回的就是你自定义Token中getPricipal返回的用户信息对象.
Object user = principals.getPrimaryPrincipal();
......
return authorizationInfo; } @Override
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken authcToken) throws AuthenticationException {
Object user = authcToken.getPrincipal();
//从数据库中查找用户的信息
UserInfo info = Dao.selectUser(user);
...
//按照用户的输入的principal信息去数据库中查询,然后封装出比对信息.下面的info.getPwd()代表的就是Credentials信息,一般指的密码
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user, info.getPwd(), getName());
return authenticationInfo;
}
//自定义matcher,这里就是对比用户的输入的信息封装成的token和按照用户输入的principal(一般就是用户名)从数据库中查询出的信息封装的info信息,一般就是比对他们的Credentials
public class MyCredentialsMatcher extends SimpleCredentialsMatcher { @Override
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
Object tokenCredentials = getCredentials(token);
Object accountCredentials = getCredentials(info);
return super.equals(tokenCredentials, accountCredentials);
}
}

这里红色的doGetAuthenticationInfo方法是用来按照用户输入的principal信息从数据库中查询,并将结果作为一个比对信息,比对2者的Credentials信息是否一致,比对时将调用比对器的doCredentialsMatch方法进行比对,所以我们可以在realm中配置自定义的比对器,重写此方法来达到自定义比对方法,实现特殊的比对逻辑.尤其是token中封装自定义对象时

.如果一致则登录成功.而绿色的doGetAuthorizationInfo方法则是作为获取当前用户的角色权限相关信息的方法,此方法中要根据用户信息查询出相关的角色权限信息并封装进去.有了此信息之后就可以根据角色和权限信息进行访问权限的控制了.

一般直接使用usernamePasswordToken即可,但是由于此默认实现一般存储的为字符串的principal和Credentials信息,如有必要改为存储自定义对象,则可以自定义token来实现,关键代码:

/* 这里必须说一下,必须要继承UsernamePasswordToken,因为realm实现中有个suports方法,会判断token是否被支持,默认的情况下是只支持UsernamePasswordToken的.如需要完全自定义,则需要单独再realm配置中添加上新的自定义token的类型支持.  */
public class MyUserToken extends UsernamePasswordToken {
//这个自定义的属性可以是对象.
private Object user; public MyUserToken() {
} public MyUserToken(Objectuser) {
this.user = user;
}
@Override
public Object getPrincipal() {
//账号信息
return user;
} @Override
public Object getCredentials() {
//校验的信息,其实一般就是指密码
return user.getPwd();
} }

在用户登录时关键代码:

       Subject currentUser = SecurityUtils.getSubject();
UserInfo user = new UserInfo();
user.setName("aaa");
user.setPwd("123");
MyUserToken token = new MyUserToken(user);
currentUser.login(token);
if (currentUser.isAuthenticated()) {
//登录成功
}else{
//失败
}

总体的思路为使用自定义的token类将用户输入的信息封装,然后采用token进行login操作.此时shiro将使用token中携带的用户信息调用Realm中自定义的doGetAuthenticationInfo方法进行校验比对.比对成功则登录成功,并会自动将相关角色权限信息封装进去.

自定义shiro的Realm实现和CredentialsMatcher实现以及Token实现的更多相关文章

  1. Shiro中Realm

    6.1 Realm [2.5 Realm]及[3.5 Authorizer]部分都已经详细介绍过Realm了,接下来再来看一下一般真实环境下的Realm如何实现. 1.定义实体及关系   即用户-角色 ...

  2. (四)自定义多个Realm以及Authenticator与AuthenticationStrategy

    多Realm配置 #声明一个realm myRealm1=com.github.zhangkaitao.shiro.chapter2.realm.MyRealm1 myRealm2=com.githu ...

  3. 解决自定义Shiro.Realm扩展类不能用注解(@Resource或@Autowire)自动装配的问题

    问题产生原因:加载Realm时其他Spring配置文件(xml)尚未加载,导致注入失败. 解决方法:编写一个设置类把注入工作提前完成. package com.xkt.shiro import org ...

  4. Shiro - 自定义filterChainDefinitions和Realm

    在Spring Context中定义shiroFilter(org.apache.shiro.spring.web.ShiroFilterFactoryBean)时需要为其filterChainDef ...

  5. Shiro笔记(四)Shiro的realm认证

    认证流程: 1.获取当前Subject.调用SecurityUtils.getSubject(); 2.测试当前用户是否已经被认证,即是否已经登录,调用Subject的isAurhenticated( ...

  6. shiro双realm验证

    假设现在有这样一种需求:存在两张表user和admin,分别记录普通用户和管理员的信息.并且现在要实现普通用户和管理员的分开登录,即需要两个Realm——UserRealm和AdminRealm,分别 ...

  7. shiro的Realm

    public class UserRealm extends AuthorizingRealm { private UserService userService = new UserServiceI ...

  8. shiro多realm验证之——shiro实现不同身份使用不同Realm进行验证(转)

    转自: http://blog.csdn.net/xiangwanpeng/article/details/54802509 (使用特定的realm实现特定的验证) 假设现在有这样一种需求:存在两张表 ...

  9. Shiro单Realm加密

    首先,我们要明确认证的流程: 1. 获取当前的 Subject. 调用 SecurityUtils.getSubject(); 2. 测试当前的用户是否已经被认证. 即是否已经登录. 调用 Subje ...

随机推荐

  1. 如何通过cmd开一个本地服务器

    1.首先你要下载安装node.js http://nodejs.cn/download/ 并且根据提示安装在自己的电脑上即可 2.打开cmd管理员窗口输入npm -v 检测node.js是否安装成功: ...

  2. 30分钟?不需要,轻松读懂IL

    先说说学IL有什么用,有人可能觉得这玩意平常写代码又用不上,学了有个卵用.到底有没有卵用呢,暂且也不说什么学了可以看看一些语法糖的实现,或对.net理解更深一点这些虚头巴脑的东西.最重要的理由就是一个 ...

  3. 关于异步执行(Async/await)的理解(转发)

    原文地址: http://blog.jobbole.com/85787/ 同步编程与异步编程 通常情况下,我们写的C#代码就是同步的,运行在同一个线程中,从程序的第一行代码到最后一句代码顺序执行.而异 ...

  4. .Net中的并行编程-2.ConcurrentStack的实现与分析

    在上篇文章<.net中的并行编程-1.基础知识>中列出了在.net进行多核或并行编程中需要的基础知识,今天就来分析在基础知识树中一个比较简单常用的并发数据结构--.net类库中无锁栈的实现 ...

  5. C#动态编译

    C#提供了DynamicObject和IDynamicMetaObjectProvider两种方式实现动态类型,动态类型的好处是类型的公有接口可以在运行时改变. 创建动态类型最简单的方法就是继承Dyn ...

  6. 让服务器iis支持.apk文件下载的设置方法

    随着智能手机的普及,越来越多的人使用手机上网,很多网站也应手机上网的需要推出了网站客户端,.apk文件就是安卓(Android)的应用程序后缀名,默认情况下,使用IIS作为Web服务器的无法下载此文件 ...

  7. Ubuntun CentOS的ISO官方MD5在哪里查看(安装虚拟电脑时出现严重错误的解决方法)

    近日在VirtualBox虚拟机上安装Linux,然后果断的选择了Ubuntu.当我新建虚拟机,一切配置完成之后,启动虚拟机,还没开始安装就提示虚拟电脑出现严重错误,需要关闭.起初以为是配置错了,上网 ...

  8. Linux Ctrl+c与ctrl+z的区别

    提问:CTRL-Z和CTRL-C区别?回答:CTRL-Z和CTRL-C都是中断命令,但是他们的作用却不一样.CTRL-C是强制中断程序的执行,而CTRL-Z的是将任务中断,但是此任务并没有结束,他仍然 ...

  9. Understanding glibc malloc【待译】

    今天尝试用Valgrind调试程序时,发现堆和栈的一些问题没有理解透彻,于是Google了下"Memory Layout C",接着就通过Memory Layout of C Pr ...

  10. box-sizing重置盒子模型计算规则

    目标大纲 一.语法声明 box-sizing : content-box | border-box | inherit 二.属性值说明 content-box 在宽度和高度之外绘制元素的内边距和边框 ...