上面一章说到shiro的认证和授权最底层就是调用realm的getAuthorizationInfo(获取用户的角色和资源)和getAuthenticationInfo(校验账号密码是否正确)两个方法。

如果我们要从数据库中查询用户和他的权限信息,我们可以使用shiro提供给我们的JdbcRealm

JdbcRealm

添加jar

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.25</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>0.2.23</version>
</dependency>

classpath环境下新建shiro-jdbc.ini如下配置
这里我们采用了阿里巴巴的数据源,注入到jdbcRealm的dataSource变量中,并且将这个jdbcRealm注入到securityManager,有点类似于spring的注入。

下面的sql放在github上对应的章节根目录下,导入即可,数据库密码填写自己数据库密码

jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm
dataSource=com.alibaba.druid.pool.DruidDataSource
dataSource.driverClassName=com.mysql.jdbc.Driver
dataSource.url=jdbc:mysql://localhost:3306/shiro
dataSource.username=root
dataSource.password=123456
jdbcRealm.dataSource=$dataSource
#注入securityManager的realm
securityManager.realms=$jdbcRealm

测试代码:

ShiroUtils.login("classpath:shiro-jdbc.ini","zhang","123456");
Subject subject = SecurityUtils.getSubject();
//是否通过认证
System.out.println(subject.isAuthenticated());

其中ShiroUtils的登录方法(这个以后直接略过):

    public static void login(String configPath,String username,String password){
Factory<SecurityManager> factory =new IniSecurityManagerFactory(configPath);
//得到安全管理器
SecurityManager securityManager = factory.getInstance(); SecurityUtils.setSecurityManager(securityManager); Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken(username, password); try {
subject.login(token);
} catch (AuthenticationException e) {
e.printStackTrace();
}
}

最后输出true。

因为jdbcRealm里面的sql都是固定的,所以我们表结构都要按照JdbcRealm里面创建对应的表。下面是JdbcRealm里面各种查询的sql(salt是密码加密,后面介绍加密再说,我们这里直接用明文密码)

表里面数据分别如下

接着测试代码添加如下:

        System.out.println(subject.hasRole("role1"));

        System.out.println(subject.isPermitted("user:create"));

最后输出true,false

为什么角色role1获取到了,permission没有获取到呢。

原因是JdbcRealm里面有个permissionsLookupEnabled默认是false,所以不会查询对应的资源权限,我们在配置文件中打开这个查询。

#打开permission查询
jdbcRealm.permissionsLookupEnabled=true

再查询就是true了。

自定义Realm

1 新增MyRealm类直接继承AuthorizingRealm.

public class MyRealm extends AuthorizingRealm {

    //认证信息,
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken upToken = (UsernamePasswordToken) token; String username = upToken.getUsername();
String password = new String(upToken.getPassword());
//模拟用户名密码是否正确
if(!"zhang".equals(username)){
throw new UnknownAccountException();
}
if(!"123456".equals(password)){
throw new IncorrectCredentialsException();
}
return new SimpleAuthenticationInfo(username,password,getName()); } //授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
//获取用户名
String username = (String)getAvailablePrincipal(principals);
//模拟从数据库查询出来对应的角色和权限
Set<String> roles = new HashSet<String>();
roles.add("role_1");
roles.add("role_2"); Set<String> permissions = new HashSet<String>();
permissions.add("user:create");
permissions.add("user:delete"); SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.setRoles(roles);
info.setStringPermissions(permissions);
return info;
} }

2,classpath文件下新建shiro-myrealm.ini配置文件

myrealm= com.nfcm.shiro.Realm.MyRealm
securityManager.realms=$myrealm

3,测试

        ShiroUtils.login("classpath:shiro-myrealm.ini","zhang","123456");

        Subject subject = SecurityUtils.getSubject();
//是否通过认证
System.out.println(subject.isAuthenticated());
//是否有role1角色
System.out.println(subject.hasRole("role_1")); System.out.println(subject.isPermitted("user:create"));

到这里全部测试通过。

github代码地址

https://github.com/cmniefei/shiroparent

(3)shiro自定义realm的更多相关文章

  1. 权限框架 - shiro 自定义realm

    上篇文章中是使用的默认realm来实现的简单登录,这仅仅只是个demo,真正项目中使用肯定是需要连接数据库的 首先创建自定义realm文件,如下: 在shiro中注入自定义realm的完全限定类名: ...

  2. shiro自定义Realm

    1.1 自定义Realm 上边的程序使用的是shiro自带的IniRealm,IniRealm从ini配置文件中读取用户的信息,大部分情况下需要从系统的数据库中读取用户信息,所以需要自定义realm. ...

  3. shiro自定义realm支持MD5算法认证(六)

    1.1     散列算法 通常需要对密码 进行散列,常用的有md5.sha, 对md5密码,如果知道散列后的值可以通过穷举算法,得到md5密码对应的明文. 建议对md5进行散列时加salt(盐),进行 ...

  4. shiro自定义realm认证(五)

    上一节介绍了realm的作用: realm:需要根据token中的身份信息去查询数据库(入门程序使用ini配置文件),如果查到用户返回认证信息,如果查询不到返回null.token就相当于是对用户输入 ...

  5. Shiro自定义Realm时用注解的方式注入父类的credentialsMatcher

    用Shiro做登录权限控制时,密码加密是自定义的. 数据库的密码通过散列获取,如下,算法为:md5,盐为一个随机数字,散列迭代次数为3次,最终将salt与散列后的密码保存到数据库内,第二次登录时将登录 ...

  6. Shiro自定义realm实现密码验证及登录、密码加密注册、修改密码的验证

    一:先从登录开始,直接看代码 @RequestMapping(value="dologin",method = {RequestMethod.GET, RequestMethod. ...

  7. shiro中自定义realm实现md5散列算法加密的模拟

    shiro中自定义realm实现md5散列算法加密的模拟.首先:我这里是做了一下shiro 自定义realm散列模拟,并没有真正链接数据库,因为那样东西就更多了,相信学到shiro的人对连接数据库的一 ...

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

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

  9. 自定义shiro的Realm实现和CredentialsMatcher实现以及Token实现

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

随机推荐

  1. netty异步

    通俗理解:http://lingnanlu.github.io/2016/08/16/netty-asyc-callback 异步的小demo:https://blog.csdn.net/coder_ ...

  2. [C++ Primer] : 第12章: 动态内存

    动态内存与只能指针 静态内存用来保存局部static对象, 类static数据成员以及定义在任何函数之外的变量. 栈内存用来保存定义在函数内的非static对象. 分配在静态或栈内存中的对象由编译器自 ...

  3. keepalived的配置详解(非常详细)

    keepalived的配置详解(非常详细) 2017-01-22 15:24 2997人阅读 评论(0) 收藏 举报  分类: 运维学习(25)    转载自:http://blog.csdn.net ...

  4. github for windows 使用

    先在github上申请账号,已有略过. 下载github for windows安装,可以提前安装.NET FRAMEWORK 4.0,否则它会在线下载安装.NET 4. 安装后登录账号,不要急着CL ...

  5. linux vim tutor

    ================================================================================      欢     迎     阅  ...

  6. PHP-redis api 中文说明(转)

    来源 : http://hi.baidu.com/gaolamp/item/1686aac07334bd0f0ad93a9f PHP-redis api 中文说明 phpredis 是 php 的一个 ...

  7. bzoj1196 公路修建问题

    Description OI island是一个非常漂亮的岛屿,自开发以来,到这儿来旅游的人很多.然而,由于该岛屿刚刚开发不久,所以那里的交通情况还是很糟糕.所以,OIER Association组织 ...

  8. VMware 安装Windows sever 2008 R2服务器

    一. 安装包下载: Windows Server 2008 R2 简体中文企业版[server 2008 r2下载] 二. 新建虚拟机 三. 安装Window Server 2008 R2 四. 服务 ...

  9. 1070 Mooncake (25 分)

    1070 Mooncake (25 分) Mooncake is a Chinese bakery product traditionally eaten during the Mid-Autumn ...

  10. seaborn分类数据可视化

    转载:https://cloud.tencent.com/developer/article/1178368 seaborn针对分类型的数据有专门的可视化函数,这些函数可大致分为三种: 分类数据散点图 ...