ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

shiro笔记

2022-04-08 21:33:27  阅读:230  来源: 互联网

标签:account Realm 用户 笔记 认证 shiro Shiro


shiro笔记

shiro简述

  • Apache Shiro 是java的一个安全框架
  • Shiro 可以做:认证、授权、加密、会话管理、Web集成、缓存等功能。
  • 官网:http://shiro.apache.org/

功能介绍

  1. Authentication:身份认证/登录,验证用户是不是拥有相应的身份
  2. Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限;
  3. Session Manager:会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通 JavaSE 环境,也可以是 Web 环境的;
  4. Cryptography:加密,保护数据的安全性,如密码加密存储到数据库,而不是明文存储;
  5. Web Support:Web 支持,可以非常容易的集成到Web 环境;
  6. Caching:缓存,比如用户登录后,其用户信息、拥有的角色/权限不必每次去查,这样可以提高效率;
  7. Concurrency:Shiro 支持多线程应用的并发验证,即如在一个线程中开启另一个线程,能把权限自动传播过去;
  8. Testing: 提供 测试 支持
  9. Run As: 允许一个用户假装为另一个用户(如果他们允许)的身份进行访问;
  10. Remember Me:记住我,这个是非常常见的功能,即一次登录后,下次再来的话不用登录了

Shiro与Spring Security对比

共同点: 认证、授权、加密、会话、缓存、remember Me功能...
不同点: Shiro配置和使用比较简单,Spring Sccurity上手复杂.Shiro依赖性低,不需要任何框架和容器,可以独立运行,而Spring Security依赖于Spring容器.

Shiro四大核心功能

Authentication - 身份认证:
一般用于登录:登陆时,验证用户是否拥有相应身份。
Authorization - 访问控制:
验证已认证用户是否拥有某些权限,可以让他进行权限内的操作。
Cryptography - 密码加密:
将密码加密储存到数据库,而不是明文储存,可以保护数据的安全性。
Session Management - 会话管理:
用户登录后就是第一次会话,在会话结束(退出登录)前,他所有的信息都在会话中。

Shiro三个核心组件

Subject-主体:

应用代码直接交互的对象是Subject,也就是说Shiro的对外API核心是Subject。
Subject的所有交互都会委托给SecurityManager(实际的执行者)。

SecurityManager-安全管理器:

SecurityManager是Shiro的核心,负责与Shiro的其他组件进行交互,相当于SpringMVC中DispatcherServlet的角色。
它管理着所有 Subject、且负责进行认证和授权、及会话、缓存的管理,所有具体的交互都通过SecurityManager 进行控制。
SecurityManager是一个单例对象,一个应用中只需要一个SecurityManager.

Realm-域

Shiro从Realm获取安全数据(如用户、角色、权限),
就是说SecurityManager要验证用户身份,那么它需要从Realm获取相应的用户进行比较以确定用户身份是否合法;
也需要从Realm得到用户相应的角色/权限进行验证用户是否能进行操作;
可以把Realm看成DataSource,即安全数据源。

shiro中的认证

身份认证,就是判断一个用户是否为合法用户的处理过程。最常见的简单身份验证方式是通过核对用户输入的用户名和口令,看其是否与系统中存储的该用户的用户名和口令一致,来判断用户身份是否正确。

shiro中认证的关键对象

  • Subject:主体
    访问系统的用户,主体可以是用户、程序等。
  • Principal:身份信息
    是主体进行身份认证的标识,标识必须具有唯一性,如用户名、手机号、邮箱地址等。一个主体可以有多个身份,但是必须有一个主身份(Primary Principal)。
  • credential:凭证信息
    是只有主体自己知道的安全信息,如密码、证书等。

认证流程

image

认证的开发

  1. 创建Spring Boot项目
<dependency>
  <groupId>org.apache.shiro</groupId>
  <artifactId>shiro-core</artifactId>
  <version>1.5.3</version>
</dependency>
  1. 引入shiro配置文件
    配置文件:名称随意,以 .ini结尾,放在resources目录下。

注意:在实际的项目开发中并不会使用这种方式,这种方法可以用来初学时练手!

[users]
king=123456
wang=123456
  1. 开发认证代码
public class ShiroDemo{
	public static void main(String[] args){
		//1.创建安全管理器对象
		DefaultSecurityManager securityManager = new DefaultSecurityManager();
		//2.给安全管理器设置realm
		securityManager.setRealm(new InitRealm("classpath:shiro.ini"));
		//3.SecurityUtils全局安全工具类设置安全管理器
		SecurityUtils.setSecurityManager(securityManager);
		//4.关键对象subject主体
		Subject subject = SecurityUtils.getSubject();
		//5.创建令牌
		UsernamePasswordToken token = new UsernamePasswordToken("king","123456");
		try{
			System.out.println("认证状态"+subject.isAuthenticated());//fasle
			//用户认证
            subject.login(token);
            System.out.println("认证状态"+subject.isAuthenticated());
		}catch(UnknownAccountException e){
			e.printStackTrace();
            System.out.println("认证失败,用户名不存在");
		}catch(IncorrectCredentialsException e){
			e.printStackTrace();
            System.out.println("认证失败,密码错误");
		}
	}
}
  1. 常见的异常类型
  • DisabledAccountException(帐号被禁用)
  • LockedAccountException(帐号被锁定)
  • ExcessiveAttemptsException(登录失败次数过多)
  • ExpiredCredentialsException(凭证过期)等

自定义Realm

通过分析源码可得,

  1. 最终执行用户名比较的的是 在SimpleAccountRealm类 的doGetAuthenticationInfo 方法完成用户名校验。
  2. 最终密码校验是在 AuthenticatingRealm类 的 assertCredentialsMatch方法 中。
    shiro提供的Realm
    image
    根据认证源码认证使用的是SimpleAccountRealm
    image
public class SimpleAccountRealm extends AuthorizingRealm{
	//......省略
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        UsernamePasswordToken upToken = (UsernamePasswordToken) token;
        SimpleAccount account = getUser(upToken.getUsername());

        if (account != null) {

            if (account.isLocked()) {
                throw new LockedAccountException("Account [" + account + "] is locked.");
            }
            if (account.isCredentialsExpired()) {
                String msg = "The credentials for account [" + account + "] are expired";
                throw new ExpiredCredentialsException(msg);
            }

        }

        return account;
    }

    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        String username = getUsername(principals);
        USERS_LOCK.readLock().lock();
        try {
            return this.users.get(username);
        } finally {
            USERS_LOCK.readLock().unlock();
        }
    }
}

接下里,开始自定义realm!

/**
 * 自定义Realm
 */
public class CustomerRealm extends AuthorizingRealm{
	//授权
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        System.out.println("==================");
        return null;
    }
	//认证
	@Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //在token中获取 用户名
        String principal = (String) token.getPrincipal();
        System.out.println(principal);

        //实际开发中应当 根据身份信息使用jdbc mybatis查询相关数据库
        //在这里只做简单的演示
        //假设username,password是从数据库获得的信息
        String username="zhangsan";
        String password="123456";
        if(username.equals(principal)){
            //参数1:返回数据库中正确的用户名
            //参数2:返回数据库中正确密码
            //参数3:提供当前realm的名字 this.getName();
            SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(principal,password,this.getName());
            return simpleAuthenticationInfo;
        }
        return null;
    }
}

标签:account,Realm,用户,笔记,认证,shiro,Shiro
来源: https://www.cnblogs.com/zhangy0119/p/16119706.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有