shrio教程初级(四)shiro基础(认证)

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: 一、前言 前面我们通过url拦截器实现了权限验证,功能齐全,开发难度也不大。但是为了更好的进行开发权限,开发我们选择shrio,终于扯上正题了是不是?当你学习shrio你会发现,都是一样的。

一、前言

前面我们通过url拦截器实现了权限验证,功能齐全,开发难度也不大。但是为了更好的进行开发权限,开发我们选择shrio,终于扯上正题了是不是?当你学习shrio你会发现,都是一样的。嘎嘎

shiro使用广泛,shiro可以运行在web应用,非web应用,集群分布式应用中越来越多的用户开始使用shiro。简单好用用的人就多了哦。

二、shrio基础

首先一样来个图:

2.1看图说话

定要细心品味,结合url拦截器权限。。。

subject:用户或者程序,可以是任何语言编写。(这个跟uel拦截器一样)

securityManager:安全管理器,对全部的 subject 进行安全管理,它是 shiro 的核心,负责对所有的 subject 进行安全管理。通过 SecurityManager 可以完成 subject 的认证、授权等,实质上 SecurityManager 是通过 Authenticator 进行认证,通过 Authorizer 进行授权,通过 SessionManager 进行会话管理等。它自身只是一个接口。

Authentic:认证器, Authenticator是一个接口, shiro 提供 ModularRealmAuthenticator实现类,通过ModularRealmAuthenticator基本上可以满足大多数需求,也可以自  定义认证器。(相当于ur权限l的登录拦截器哦)

Authorizer: Authorizer即授权器,用户通过认证器认证通过,在访问功能时需要通过授权器判断用户是否有此功能的操作权限(相当于url权限系统的权限拦截器)。

sessionManager: 即会话管理, shiro 框架定义了一套会话管理,它不依赖 web 容器的 session ,所以 shiro 可以使用在非 web 应用上,也可以将分布式应用的会话集中在一点管理,此特性可使它实现单点登录。(相当于ur权限系统里面自带的httpsession,而它可以独立)

sessionDao: SessionDAO即会话 dao ,是对 session 会话操作的一套接口,比如要将 session 存储到数据库,可以通过 jdbc 将会话存储到数据库。

realms:领域相 当于 datasource 数据源, securityManager 进行安全认证需要通过 Realm 获取用户权限数据,比如:如果用户身份数据在数据库那么 realm 就需要从数据库获取用户身份信息。(相当于ur权限系统里面自带的mysql,而它还支持验证)

注意:不要把realm理解成只是从数据源取数据,在realm中还有认证授权校验的相关的代码。

cacheManager: CacheManager即缓存管理,将用户权限数据存储在缓存,这样可以提高性能。

Cryptography:Cryptography即密码管理,shiro提供了一套加密/解密的组件,方便开发。比如提供常用的散列、加/解密等功能。MD5即是散列(相当于ur权限系统里面MD5)


就这么完美的解释,反正都是来自网络,而且专业简单的解释。

二、shrio的jar包

   <!--======================================shrio=================================================-->
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-core</artifactId>
      <version>1.2.4</version>
    </dependency>
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-web</artifactId>
      <version>1.2.4</version>
    </dependency>
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-spring</artifactId>
      <version>1.2.4</version>
    </dependency>
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-ehcache</artifactId>
      <version>1.2.4</version>
    </dependency>
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-quartz</artifactId>
      <version>1.2.4</version>
    </dependency>

或者就ok
<dependency>
  <groupId>org.apache.shiro</groupId>
  <artifactId>shiro-all</artifactId>
  <version>1.2.4</version>
</dependency>

三、shrio的ini认证程序实例

项目分析


项目结构:

3.1加入jar包

加入上面的jar包core包即可以
再加入日志文件与包
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.0</version>
        </dependency>

        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.1.3</version>
        </dependency>

3.3 编写ini文件

shrio-frist.ini

#用户信息配置
[users]
zhangsan=111
ycy=222

3.4 编写测试类

 
  
我们根据项目流程一步步来编写我们的测试程序,
 
  
即是:读取ini或者xml文件----创建securityManager----加入运行环境----生成一个sbject---登录(加入taken)---退出
 
  

  • 1、通过ini配置文件创建securityManager
  • 2、调用subject.login方法主体提交认证,提交的token
  • 3securityManager进行认证,securityManager最终由ModularRealmAuthenticator进行认证。
  • 4ModularRealmAuthenticator调用IniRealm(realm传入token) ini配置文件中查询用户信息
  • 5IniRealm根据输入的tokenUsernamePasswordToken)从 shiro-first.ini查询用户信息,根据账号查询用户信息(账号和密码)
  • 如果查询到用户信息,就给ModularRealmAuthenticator返回用户信息(账号和密码)
  • 如果查询不到,就给ModularRealmAuthenticator返回null
  • 6ModularRealmAuthenticator接收IniRealm返回Authentication认证信息 如果返回的认证信息是nullModularRealmAuthenticator抛出异常(org.apach e.shiro.authc.UnknownAccountException
  • 如果返回的认证信息不是null(说明inirealm找到了用户),对IniRealm返回用户密码 (在ini文件中存在)和 token中的密码 进行对比,如果不一致抛出异常(org.apache.shiro.authc.IncorrectCredentialsException
    • 注意:1、是realm调用token信息,进行验证。
    • 2、securityManager是调用ModularRealmAuthenticator进行认证返回AuthenticationInfo认证信息

authenticationTest.java
package co.ycy.authenticator;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.util.Factory;
import org.junit.Test;

/**
 * Created by Administrator on 2015/10/15 0015.
 * 认证测试
 */
public class authenticationTest {
    //用户登录和退出
    @Test
    public void testLoginAndLoginOut(){
        //创建一个securityManager 通过ini文件创建
        Factory<SecurityManager> securityManagerFactory=new IniSecurityManagerFactory("classpath:shrio-frist.ini");
//        XMLSecurityManager
        //创建SecurityManager
        SecurityManager securityManager=  securityManagerFactory.getInstance();
        //将SecurityManager创建到生成环境中
        SecurityUtils.setSecurityManager(securityManager);
        //从SecurityUtils 构建一个subject
        org.apache.shiro.subject.Subject subject=SecurityUtils.getSubject();
        //认证提交认证token
        UsernamePasswordToken usernamePasswordToken=new UsernamePasswordToken("ycy","222");
        //执行认证提交认证
        try {
            subject.login(usernamePasswordToken);
        }catch(AuthenticationException ex){
            ex.printStackTrace();
        }
        System.out.println("是否通过认证:" + subject.isAuthenticated());
        //退出
        subject.logout();
        System.out.println("是否通过认证:" + subject.isAuthenticated());
    }
}

3.5 测试结果


四、shrio的ini认证-realms自定义

我们知道realm就是数据源,即是我们经常说的各种数据库,但是我们前面例子用的是ini文件,我们现在来模拟一下用数据。(模拟)

4.1编写自定义realm

自定义realm,继承我们的AuthorizingRealm。因为AuthorizingRealm就是我们realm的一个实现类

<span style="font-size:12px;">package com.ycy.realm;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

/**
 * Created by Administrator on 2015/10/15 0015.
 * 自定义数据源
 */
public class CustomRealm extends AuthorizingRealm{

    //用户认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
       //authenticationToken为用户输入信息
        String userCode=(String)authenticationToken.getPrincipal();
        //模拟数据库操作查询用户
        if(!userCode.equals("ycy")){
            return null;
        }
        //查询密码为111
        String password="222";

        SimpleAuthenticationInfo info=new SimpleAuthenticationInfo(userCode,password,"customRealm");

        return info;
    }
    //用户授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        return null;
    }


}</span>

4.1ini文件

这个ini文件是制定我们的realms,而不再是指定数据
shrio-realm.ini

#用户信息配置
[main]
#自定义realm
cutomRealm= com.ycy.realm.CustomRealm
#自定义realm注入到securityManager中(标签语言)
securityManager.realms=$cutomRealm

4.3 测试

测试程序一样没有变,只是现在执行认证的时候进行的是我们自己定义的realm的认证

//用户登录和退出(自定义realm)
    @Test
    public void testCustomRealm(){
        //创建一个securityManager 通过ini文件创建
        Factory<SecurityManager> securityManagerFactory=new IniSecurityManagerFactory("classpath:shrio-realm.ini");
//        XMLSecurityManager
        //创建SecurityManager
        SecurityManager securityManager=  securityManagerFactory.getInstance();
        //将SecurityManager创建到生成环境中
        SecurityUtils.setSecurityManager(securityManager);
        //从SecurityUtils 构建一个subject
        org.apache.shiro.subject.Subject subject=SecurityUtils.getSubject();
        //认证提交认证token
        UsernamePasswordToken usernamePasswordToken=new UsernamePasswordToken("ycy","222");
        //执行认证提交认证
        try {
            subject.login(usernamePasswordToken);
        }catch(AuthenticationException ex){
            ex.printStackTrace();
        }
        System.out.println("是否通过认证:" + subject.isAuthenticated());
        //退出
        subject.logout();
        System.out.println("是否通过认证:" + subject.isAuthenticated());
    }

测试结果一样,就不用贴图了。

四、shrio的ini认证-realms自定义(加密)

只需要在realm里面写入加密就ok

4.1了解shrio的MD5加密

package com.ycy.test;

import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.crypto.hash.SimpleHash;

/**
 * Created by Administrator on 2015/10/15 0015.
 */
public class MD5Test {
    public static void main(String[] args) {
        //原始密码
        String source="111";
        //盐
        String salt="ycy";
        //散列次数
        int hashInterration=1;//MD5(****)一次
        Md5Hash md5Hash=new Md5Hash(source,salt,hashInterration);
        String password_md5=md5Hash.toString();
        System.out.println("111加盐MD5加密后为:"+password_md5);
        //散列加密2
        SimpleHash simpleHash=new SimpleHash("md5",source,salt,hashInterration);
        System.out.println("111加盐MD5加密后为:"+simpleHash.toString());
        //96c26c8872da9d2534bf7c31f499425d
    }
}

4.2 修改ini文件

[main]
#定义凭证匹配
credentialsMatcher=org.apache.shiro.authc.credential.HashedCredentialsMatcher
#定义散列算法
credentialsMatcher.hashAlgorithmName=md5
#散列次数
credentialsMatcher.hashIterations=1
#自定义realm
customRealm= com.ycy.realm.CustomRealm2
customRealm.credentialsMatcher=$credentialsMatcher
securityManager.realms=$customRealm


4.3修改自定义realm

package com.ycy.realm;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;

/**
 * Created by Administrator on 2015/10/15 0015.
 * 自定义数据源
 */
public class CustomRealm2 extends AuthorizingRealm{

    //用户认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //authenticationToken为用户输入信息
        String userCode=(String)authenticationToken.getPrincipal();
        //模拟数据库操作查询用户
        if(!userCode.equals("ycy")){
            return null;
        }
        //查询密码为111
        //数据库111 MD5加盐ycy 加密后为96c26c8872da9d2534bf7c31f499425d
        String password="96c26c8872da9d2534bf7c31f499425d";

        String salt="ycy";

        SimpleAuthenticationInfo info=new SimpleAuthenticationInfo(userCode,password, ByteSource.Util.bytes(salt),"customRealm");

        return info;
    }
    //用户授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        return null;
    }


}

4.4测试

//用户登录和退出(自定义realm)加密
    @Test
    public void testCustomRealmMd5(){
        //创建一个securityManager 通过ini文件创建
        Factory<SecurityManager> securityManagerFactory=new IniSecurityManagerFactory("classpath:shrio-realm-md5.ini");
//        XMLSecurityManager
        //创建SecurityManager
        SecurityManager securityManager=  securityManagerFactory.getInstance();
        //将SecurityManager创建到生成环境中
        SecurityUtils.setSecurityManager(securityManager);
        //从SecurityUtils 构建一个subject
        org.apache.shiro.subject.Subject subject=SecurityUtils.getSubject();
        //认证提交认证token
        UsernamePasswordToken usernamePasswordToken=new UsernamePasswordToken("ycy","111");
        //执行认证提交认证
        try {
            subject.login(usernamePasswordToken);
        }catch(AuthenticationException ex){
            ex.printStackTrace();
        }
        System.out.println("是否通过认证:" + subject.isAuthenticated());
        //退出
        subject.logout();
        System.out.println("是否通过认证:" + subject.isAuthenticated());


目录
相关文章
|
6月前
|
安全 Java 网络安全
后端进阶之路——综述Spring Security认证,授权(一)
后端进阶之路——综述Spring Security认证,授权(一)
|
11月前
|
安全 Java API
盘点认证框架 : SpringSecurity 基础篇
SpringSecurity 应该是最常见的认证框架了 , 处于Spring体系中使他能快速地上手 , 这一篇开始作为入门级开篇作 , 来浅浅地讲一下SpringSecurity 的整体结构.
|
安全 Java 程序员
阿里开源SpringSecurity:用户+案例+认证+框架
SpringSecurity 相信Spring大家一定不陌生,那么SpringSecurity你又了解多少呢?市面上有关Spring的介绍有很多,那么对于SpringSecurity只有一些简单的有关概念的介绍,如果想深入了解并使用SpringSecurity还是需要下很大的功夫的! 可想而知,SpringSecurity有着强大的功能,但是它同时也有很高的学习成本;毕竟囊括了身份认证的各种场景以及Web安全的大量知识,在官方参考的手册中就数十万字的介绍,且还不包括当中诸多实现细节。问题来了,很多开发人员在面对这样的“庞然大物”的时候也是无从下手的,
65 0
|
存储 缓存 安全
01 Shrio简介
01 Shrio简介
49 0
|
安全 Java 数据安全/隐私保护
马老师手写第二版Spring Security OAuth2.0认证授权教程
先是给大家基本概念,然后是基于Session的认证方式,紧接着会带着大家去快速的上手Spring Security,然后回去给大家详解解释Spring Security应用、然后就是分布式系统认证方案以及OAuth2.0,最后是Spring Security实现分布式系统授权!
|
存储 Java 数据库
三.SpringSecurity基础-认证原理
SpringSecurity基础-认证原理
|
存储 Java 数据库
SpringSecurity基础-认证原理
SpringSecurity是基于Filter实现认证和授权,底层通过FilterChainProxy代理去调用各种Filter(Filter链),Filter通过调用AuthenticationManager完成认证 ,通过调用AccessDecisionManager完成授权,SpringSecurity中核心的过滤器链详细如下:
94 0
|
安全 Java 数据库
SpringSecurity安全框架(课时二十一)
SpringSecurity安全框架(课时二十一)
89 0
|
存储 缓存 安全
Shiro安全框架(1)基础入门案例
学习Shiro的时候,阅读过很多优秀的文章,比如《跟我学Shiro》系列等等。于是结合自己的实际情况,自己整理了一部分。这是第一篇文章,旨在从基础案例出发了解其原理。
165 0
Shiro安全框架(1)基础入门案例
好好编程-物流项目13【登录认证-shiro实现】
我们已经完成了用户的CRUD操作。本文我们来介绍下基于Shiro的登录认证操作。
好好编程-物流项目13【登录认证-shiro实现】