权限管理--shiro的简单使用

寵の児 提交于 2020-02-25 23:43:22

权限管理–shiro的简单使用

权限管理

1、什么是权限管理

权限管理属于安全管理的范畴、简单的说就是对用户的访问进行控制

2、什么是身份认证

判断一个用户 是否是合法用户的这个处理过程就叫做身份认证。

最常用的是通过简单的用户名和密码 进行身份认证、如果你的用户名和密码在数据库中存在 、那么说明你是合法的,否则不合法

3、用户名和密码身份认证的流程

在这里插入图片描述

4、关键对象

  1. Subject:主体
    1. 访问该系统的用户、程序、在咋们的上面进行认证的都称为主体
    2. 简单的说、谁去认证那么这个主题就是谁
  2. Primcipal:身份信息
    1. 就是上面的Subject进行身份认证的标识、标识必须具有唯一性
    2. 唯一性的: 手机号、用户名、邮箱地址
    3. 简单说就是你带的申明信息去进行认证那么这个Primcipal就是什么
  3. credential:凭证信息
    1. 密码、安全信息(token)

5、授权流程是什么

在这里插入图片描述

6、基本的权限模型

权限模型是啥?

模型简单的说就相当于是一个套路、这个套路简单的说就是我们在做项目的时候,如果遇到一个项目中 有多种不同身份的用户(角色)使用这个系统, 而且不同身份的这些用户还拥有不同的访问权限的时候 我们在设置数据库的时候的这个套路

商城项目: 平台 买家 卖家 ====> 角色

不同身份的用户还具有不同的访问权限

角色 实际上 就是权限的一个集合

资源:官方的解释:一切能够被计算机识别的图片、文字、文件等等都成为资源

项目开发中所指的这个资源:指的是页面上的所有的按钮、图片、文字、超链接。。。

在这里插入图片描述

7、通用的权限模型

在这里插入图片描述

7.1、表里面到底都有哪些字段

用户表
用户id  用户名  ....
    
角色表
角色id  角色名字   角色描述

用户角色表
用户id   角色id

权限资源表
权限资源id 权限名字 权限的描述 type(per|res) resName  resPath 显示区域的编码  

角色权限表
角色id  权限的id

8、目前市场上通用的权限管理框架

shiro Spring Security OAuth2

Spring Security 这个框架是有依赖性的 Spring

OAuth2:第三方登陆、公众平台

shiro:这个框架有个优点,没有框架的依赖、任何平台都可以用

shiro的简单使用

9、shiro是什么

简单说shiro就是一个负责授权和认证的框架

  • Apache Shiro提供了认证、授权、加密和会话管理功能,将复杂的问题隐藏起来,提供清晰直观的API使开发者可以很轻松地开发自己的程序安全代码。并且在实现此目标时无须依赖第三方的框架、容器或服务,当然也能做到与这些环境的整合,使其在任何环境下都可拿来使用。
  • Shiro将目标集中于Shiro开发团队所称的“四大安全基石”-认证(Authentication)、授权(Authorization)、会话管理(Session Management)和加密(Cryptography):
    • 认证(Authentication):用户身份识别。有时可看作为“登录(login)”,它是用户证明自己是谁的一个行为。
    • 授权(Authorization):访问控制过程,好比决定“认证(who)”可以访问“什么(what)”.
    • 会话管理(SessionManagement):管理用户的会话(sessions),甚至在没有WEB或EJB容器的环境中。管理用户与时间相关的状态。
    • 加密(Cryptography):使用加密算法保护数据更加安全,防止数据被偷窥。

10、shiro能干什么

认证、授权、Cache的管理、Session的管理、rememberMe功能的实现、登陆、退出…

11、shiro的整体架构是什么

在这里插入图片描述

11.1、shiro中常见的名词解释

  1. Subject:登陆的这个用户(用户、程序) 、谁认证那么这个主体就是谁
  2. Principal:用户名(还可以是用户信息的封装)
  3. Credential:密码
  4. Token:令牌(用户名+密码的封装)----进行进行认证的封装对象
    1. 这个的对象并不是前后分离的这个token
  5. Security Manager:安全管理器(只要使用了shiro框架那么这个对象都是必不可少的)
  6. Authenticator:认证器(主要做用户身份认证、简单跟你说就是用来登陆的时候做身份校验的)
  7. Authrizer:授权器(简单的说就是用来做用户的授权的)
  8. Realm:用户认证和授权的时候 和数据库交互的对象(这里面干的事情就是从数据库查询数据 封装成token然后取进行认证和授权)

12、shiro的第一个helloworld程序

12.1、导包

  <!--导入shiro的包-->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-all</artifactId>
            <version>1.3.2</version>
        </dependency>

12.2、在resource下创建模拟数据库的文件

shiro.ini —> 只能是以 .ini 结尾的文件,并且idea的读取方式需要设置成 properties方式,否则不生效

[users]
kongming=123
dan=456

12.3、编写测试代码完成用户的认证

	/**
     *  测试shiro是否正常使用
     */
    @Test
    public void shiro1() {
        // 获取安全管理器工厂
        IniSecurityManagerFactory iniSecurityManagerFactory = new IniSecurityManagerFactory("classpath:shiro.ini");
        // 通过安装管理器工厂获取安全管理器
        SecurityManager securityManager = iniSecurityManagerFactory.createInstance();
        // 将安全管理器设置到运行环境中
        SecurityUtils.setSecurityManager(securityManager);
        // 获取当前操作的主体(subject)
        Subject subject = SecurityUtils.getSubject();
        // 此处的 用户名和密码,是由前端传过来的,此处直接赋值,模拟测试数据
        // 利用用户名和密码,创建token
        UsernamePasswordToken token = new UsernamePasswordToken("kongming", "123");
        // 传递token进行验证
        subject.login(token);
        // 输出用户认证状态
        System.out.println("用户的认证状态:" + subject.isAuthenticated());
        // 用户退出
        subject.logout();
        // 再次打印用户认证状态
        System.out.println("用户的认证状态:" + subject.isAuthenticated());
    }
/*
	认证成功:打印出---》 true  false
	认证失败:抛出异常:org.apache.shiro.authc.IncorrectCredentialsException: Submitted credentials for token [org.apache.shiro.authc.UsernamePasswordToken - kongming, rememberMe=false] did not match the expected credentials.
*/

13、自定义realm的实现

13.1、导入依赖

java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
/*
	出现这个错误的原因是: 缺少日志支持的依赖,需要导入 log4j 和 commons-logging 这2个依赖
*/
		<!-- log4j -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>

		<dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
            <version>1.18.10</version>
        </dependency>

13.2、创建实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {

    private String username;
    private String password;

}

13.3、自定义realm

UserRealm.java

package com.fu.shiro.realm;

import com.fu.shiro.pojo.User;
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;

public class UserRealm extends AuthorizingRealm {
    @Override
    public String getName() {
        return "UserRealm";
    }

    /**
     * 认证
     * @param authenticationToken 令牌
     * @return 返回认证信息
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        // 1. 通过token获取用户名
        String username = (String) authenticationToken.getPrincipal();
        // 2. 通过用户名到数据库查询用户信息
        // User user = userService.getUserByName(user);
        // 如果查不到用户,直接返回 null,这里模拟 if(null == user)
        if (!username.equals("kongming")) {
            return null;
        }
        //      此处模拟已经查询到用户信息
        User user = new User("kongming", "123");

        // 3. 返回认证信息对象
        return new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), getName());
    }

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

13.4、书写配置

shiro-realm.ini 指定realm的自定义实现类

[main] 
customRealm=com.fu.shiro.realm.UserRealm
securityManager.realms=$customRealm

13.5、测试

	/**
     *  测试 使用自定义realm完成身份认证
     */
    @Test
    public void shiro2() {
        // 获取安全管理器工厂
        IniSecurityManagerFactory iniSecurityManagerFactory = new IniSecurityManagerFactory("classpath:shiro-realm.ini");
        // 通过安装管理器工厂获取安全管理器
        SecurityManager securityManager = iniSecurityManagerFactory.createInstance();
        // 将安全管理器设置到运行环境中
        SecurityUtils.setSecurityManager(securityManager);
        // 获取当前操作的主体(subject)
        Subject subject = SecurityUtils.getSubject();
        // 此处的 用户名和密码,是由前端传过来的,此处直接赋值,模拟测试数据
        // 利用用户名和密码,创建token
        UsernamePasswordToken token = new UsernamePasswordToken("kongming", "123");
        // 传递token进行验证
        subject.login(token);
        // 输出用户认证状态
        System.out.println("用户的认证状态:" + subject.isAuthenticated());
        // 用户退出
        subject.logout();
        // 再次打印用户认证状态
        System.out.println("用户的认证状态:" + subject.isAuthenticated());
    }
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!