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. 体验VS2015 Update 2 的 Android 和 Python

    趁着假期不用加班,又遇到build 2016的劲爆消息--Xamarin免费集成到VS中 所以立马把vs升级到update 2体验一下下(之前也体验过). 在安装的时候也是只勾选了部分,不需要太多(全 ...

  2. 【Win10开发】Toast通知——前台激活

    上篇文章我们将了大体的Toast通知的模板及实例展示,那么,这篇文章就来讲讲Toast的前台激活. 首先是xaml界面,很简单,我们放一个Button和TextBlock,TextBlock用来显示T ...

  3. Android ViewPager滑动背景渐变

    原理 总 布局为RelativeLayout或者FrameLayout,在这里我们用的是RelativeLayout.先设置背景图片,宽度和高度都 fill_parent,在设置viewpager,v ...

  4. php判断数据库中某个字段是否有值去执行excel表格写入操作

  5. form表单中enctype="multipart/form-data"的作用

    在我们使用php导入和导出excel表格的时候经常会见到 enctype="multipart/form-data",哪他的作用是什么呢? ENCTYPE="multip ...

  6. svn忽略某个文件提交

    svn忽略配置文件提交:TortoiseSVN->Unversion and add to ignore_list (config.php(recursiverly)) 正如官方指南所言:Tor ...

  7. 《TypeScript 中文入门教程》 1、基础数据类型

    转载:https://github.com/MyErpSoft/TypeScript-Handbook/blob/master/pages/zh-CHS/Basic%20Types.md 概述 为了让 ...

  8. 06-图1 列出连通集 (25分)(C语言邻接表实现)

    题目地址:https://pta.patest.cn/pta/test/558/exam/4/question/9495 由于边数E<(n*(n-1))/2 所以我选用了邻接表实现,优先队列用循 ...

  9. Netty(五)序列化protobuf在netty中的使用

    protobuf是google序列化的工具,主要是把数据序列化成二进制的数据来传输用的.它主要优点如下: 1.性能好,效率高: 2.跨语言(java自带的序列化,不能跨语言) protobuf参考文档 ...

  10. TouchPoint.js – 可视化展示 HTML 原型点击效果

    TouchPoint.js 是一个用于 HTML 原型展示的 JavaScript 库(作为UX过程的一部分),通过视觉表现用户在屏幕上的点击.TouchPoint 是高度可定制,非常适合屏幕录制,用 ...