了解Shiro会话管理和加密的方式

目录

什么是Shiro会话管理

一、会话管理的定义与功能

二、Shiro会话管理的核心组件

三、Shiro会话管理的实现方式

四、Shiro会话管理的配置与使用

什么是缓存

一、缓存的作用

二、缓存的类型

三、缓存的替换策略

四、缓存的应用场景

五、缓存的注意事项

怎么实现加密

一、添加Shiro依赖

二、配置Shiro

三、创建自定义Realm

四、配置HashedCredentialsMatcher

五、用户注册时加密密码


什么是Shiro会话管理

Shiro会话管理是一种用于管理用户会话信息的机制,它提供了完整的企业级会话管理功能,且不依赖于底层容器(如Tomcat)。以下是对Shiro会话管理的详细解释:

一、会话管理的定义与功能

会话管理在人机交互中,是保持用户的整个会话活动的互动与计算机系统跟踪过程。Shiro会话管理主要涉及用户从登录系统到注销系统之间所经过的时间内的信息管理,包括会话的创建、维护、删除、失效、验证等工作。

Shiro会话管理提供了以下主要功能:

  1. 会话管理:管理所有用户的会话信息,确保用户在多次交互过程中都能被正确识别。
  2. 会话事件监听:监听会话的创建、过期及停止事件,以便在会话状态发生变化时执行相应的操作。
  3. 会话存储/持久化:将会话信息存储在持久化存储介质中(如数据库、Redis等),以便在服务器重启或故障恢复后能够恢复会话信息。
  4. 容器无关的集群:支持在分布式系统或集群环境中进行会话同步,确保用户在不同服务器之间切换时能够保持会话状态。
  5. 失效/过期支持:设置会话的有效期,并在会话过期时执行相应的操作(如删除会话、重定向到登录页面等)。
  6. 对Web的透明支持:直接替换Web容器的会话管理,无需对现有代码进行大量修改。
  7. SSO单点登录支持:支持单点登录功能,允许用户在一个地方登录后,即可访问多个相互信任的应用系统而无需再次登录。

二、Shiro会话管理的核心组件

Shiro会话管理的核心组件包括:

  1. SessionManager:会话管理器,负责会话的创建、维护、删除、验证等工作。它是Shiro的核心组件之一,由顶层组件SecurityManager直接管理。
  2. Subject:当前操作的用户,包含了用户的会话信息。通过Subject可以执行登录、注销、获取会话等操作。
  3. Session:用户的会话信息,包含了用户在多次交互过程中所需的数据。Session具有唯一标识符(Session ID),用于区分不同的会话。

三、Shiro会话管理的实现方式

Shiro提供了多种会话管理的实现方式,以满足不同场景的需求:

  1. DefaultSessionManager:用于JavaSE环境的默认实现,支持基本的会话管理功能。
  2. ServletContainerSessionManager:用于Web环境的默认实现,直接使用Servlet容器的会话管理功能。但这种方式依赖于Servlet容器,不利于跨容器移植。
  3. DefaultWebSessionManager:用于Web环境的另一种实现方式,自己维护会话信息,不依赖于Servlet容器的会话管理。这种方式更加灵活,适用于需要自定义会话管理逻辑的场景。

四、Shiro会话管理的配置与使用

在使用Shiro进行会话管理时,需要进行相应的配置:

  1. 配置SessionManager:在Shiro的配置文件中指定使用的SessionManager实现类,并配置相应的属性(如会话过期时间、会话验证间隔等)。
  2. 配置SessionDAO:SessionDAO用于会话的CRUD操作。Shiro提供了多种SessionDAO实现类(如MemorySessionDAO、CachingSessionDAO等),可以根据需求选择合适的实现类并进行配置。
  3. 配置SessionListener:SessionListener用于监听会话事件(如会话创建、过期、销毁等)。可以通过实现SessionListener接口或继承SessionListenerAdapter类来创建自定义的监听器,并将其注册到SecurityManager中。
  4. 配置会话验证调度器:Shiro提供了会话验证调度器(SessionValidationScheduler),用于定期验证会话是否已过期。可以配置调度器的执行间隔和是否启用会话验证等功能。

通过以上配置,可以实现Shiro的会话管理功能,并根据需求进行自定义和扩展。

什么是缓存

缓存(Cache)是一种用于存储数据的临时存储器,旨在提高数据访问速度和减少数据访问延迟。缓存通常位于较慢的存储设备(如硬盘)和较快的存储设备(如内存)之间,或者在网络请求和服务器响应之间。以下是缓存的详细解释:

一、缓存的作用

  1. 提高数据访问速度:缓存将数据存储在较快的存储介质中,使得数据的读取和写入速度得以提高。
  2. 减少数据访问延迟:通过缓存,可以减少对原始数据源的访问次数,从而降低数据访问的延迟。
  3. 减轻数据库负载:缓存可以分担数据库的查询压力,减少数据库的访问频率,从而延长数据库的使用寿命和提高其性能。
  4. 提高系统响应能力:缓存使得系统能够更快地响应用户请求,提高用户体验。

二、缓存的类型

  1. 本地缓存:将数据存储在应用服务器的本地内存中。这种缓存方式具有访问速度快、但容量有限的特点。
  2. 分布式缓存:将数据存储在多个服务器节点上,实现数据的共享和负载均衡。这种缓存方式适用于大型分布式系统。
  3. 数据库缓存:将数据库查询结果存储在缓存中,以减少对数据库的访问次数。这种缓存方式通常与数据库管理系统结合使用。
  4. Web缓存:包括浏览器缓存和代理服务器缓存,用于存储Web页面的副本,以减少对Web服务器的请求次数。

三、缓存的替换策略

由于缓存的容量有限,因此需要制定合适的替换策略来管理缓存中的数据。常见的替换策略包括:

  1. 先进先出(FIFO):最早进入缓存的数据最先被淘汰。
  2. 最近最少使用(LRU):最近最少被访问的数据最先被淘汰。
  3. 最不经常使用(LFU):访问频率最低的数据最先被淘汰。
  4. 随机替换:随机选择一个数据项进行替换。

四、缓存的应用场景

  1. 数据库查询优化:将数据库查询结果缓存起来,以减少对数据库的访问次数。
  2. Web页面加速:将Web页面的静态内容(如图片、CSS、JavaScript等)缓存起来,以减少对Web服务器的请求次数。
  3. 分布式系统数据共享:在分布式系统中,通过缓存实现数据的共享和负载均衡。
  4. API调用优化:将API调用的结果缓存起来,以减少对外部服务的请求次数。

五、缓存的注意事项

  1. 缓存一致性:确保缓存中的数据与原始数据源中的数据保持一致。
  2. 缓存过期:设置缓存的过期时间,以避免数据长时间未更新而导致的不一致性问题。
  3. 缓存击穿:防止单个热点数据的高并发访问导致缓存失效,进而直接访问数据库造成压力。
  4. 缓存雪崩:避免大量缓存同时失效导致的高并发访问压力。
  5. 缓存预热:在系统启动或更新时,提前将热点数据加载到缓存中以提高性能。

综上所述,缓存是一种重要的数据优化技术,通过合理利用缓存技术,可以显著提高系统的性能和响应能力。

怎么实现加密

在Shiro中实现加密通常涉及对用户的密码进行加密存储,并在认证过程中验证用户输入的密码是否与存储的加密密码匹配。以下是实现Shiro加密的详细步骤:

一、添加Shiro依赖

首先,在你的项目中添加Shiro相关的依赖。如果你使用的是Maven构建工具,可以在pom.xml文件中添加以下依赖:

<dependencies>  
    <!-- Shiro 核心依赖 -->  
    <dependency>  
        <groupId>org.apache.shiro</groupId>  
        <artifactId>shiro-core</artifactId>  
        <version>你的Shiro版本</version>  
    </dependency>  
    <!-- Shiro Web 依赖 -->  
    <dependency>  
        <groupId>org.apache.shiro</groupId>  
        <artifactId>shiro-web</artifactId>  
        <version>你的Shiro版本</version>  
    </dependency>  
    <!-- Shiro 加密哈希依赖(如果需要) -->  
    <dependency>  
        <groupId>org.apache.shiro</groupId>  
        <artifactId>shiro-crypto-hash</artifactId>  
        <version>你的Shiro版本</version>  
    </dependency>  
</dependencies>

二、配置Shiro

在Spring Boot项目中,你通常需要在配置类中配置Shiro的Bean,包括SecurityManagerShiroFilterFactoryBean等。

1.配置SecurityManager

@Bean  
public DefaultWebSecurityManager securityManager(ShiroRealm shiroRealm, HashedCredentialsMatcher hashedCredentialsMatcher) {  
    DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();  
    securityManager.setRealm(shiroRealm);  
    securityManager.setCredentialsMatcher(hashedCredentialsMatcher);  
    return securityManager;  
}

2.配置ShiroFilterFactoryBean

@Bean  
public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager) {  
    ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();  
    shiroFilter.setSecurityManager(securityManager);  
    // 配置过滤链定义,如登录页面、无需认证的路径、需要认证的路径等  
    Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();  
    filterChainDefinitionMap.put("/login.html", "anon");  
    filterChainDefinitionMap.put("/**", "authc");  
    shiroFilter.setFilterChainDefinitionMap(filterChainDefinitionMap);  
    return shiroFilter;  
}

三、创建自定义Realm

自定义Realm是实现加密认证的核心部分。你需要创建一个类实现AuthorizingRealm接口,并重写doGetAuthenticationInfodoGetAuthorizationInfo方法。

  1. 重写doGetAuthenticationInfo方法

在这个方法中,你需要对用户输入的密码进行加密,并与数据库中存储的加密密码进行比较。

@Override  
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {  
    UsernamePasswordToken upToken = (UsernamePasswordToken) token;  
    String username = upToken.getUsername();  
      
    // 从数据库中查询用户信息,包括加密后的密码和盐值  
    // User user = userService.findByUsername(username);  
    // 假设从数据库中查询到的加密密码和盐值  
    String encryptedPasswordFromDb = "从数据库查询到的加密密码";  
    ByteSource salt = ByteSource.Util.bytes("从数据库查询到的盐值");  
      
    // 对用户输入的密码进行加密  
    String inputPassword = new String((char[]) token.getCredentials());  
    String encryptedInputPassword = new SimpleHash(  
            "SHA-256", // 哈希算法  
            inputPassword,  
            salt,  
            1024 // 哈希迭代次数  
    ).toString();  
      
    // 比较加密后的密码是否匹配  
    if (!encryptedInputPassword.equals(encryptedPasswordFromDb)) {  
        throw new IncorrectCredentialsException();  
    }  
      
    // 返回认证信息  
    return new SimpleAuthenticationInfo(username, encryptedPasswordFromDb, salt, getName());  
}

     2 重写doGetAuthorizationInfo方法

在这个方法中,你需要实现用户的授权逻辑。

@Override  
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {  
    // 从principals中获取用户名  
    String username = (String) principals.getPrimaryPrincipal();  
      
    // 根据用户名查询用户权限和角色信息  
    // List<String> roles = roleService.findByUsername(username);  
    // List<String> permissions = permissionService.findByUsername(username);  
      
    // 假设查询到的权限和角色信息  
    List<String> roles = Arrays.asList("admin");  
    List<String> permissions = Arrays.asList("read", "write");  
      
    // 返回授权信息  
    SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();  
    authorizationInfo.setRoles(roles);  
    authorizationInfo.setStringPermissions(permissions);  
    return authorizationInfo;  
}

四、配置HashedCredentialsMatcher

在配置SecurityManager时,你需要设置一个HashedCredentialsMatcher,用于指定密码的加密算法和迭代次数。

@Bean  
public HashedCredentialsMatcher hashedCredentialsMatcher() {  
    HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();  
    hashedCredentialsMatcher.setHashAlgorithmName("SHA-256"); // 设置哈希算法  
    hashedCredentialsMatcher.setHashIterations(1024); // 设置哈希迭代次数  
    return hashedCredentialsMatcher;  
}

五、用户注册时加密密码

在用户注册时,你需要对用户输入的明文密码进行加密,并将加密后的密码存储到数据库中。这通常是在用户服务层实现的。

public void registerUser(String username, String password) {  
    // 生成盐值(通常是一个随机数)  
    ByteSource salt = SecureRandomNumberGenerator.getInstance().nextBytes();  
      
    // 对密码进行加密  
    String encryptedPassword = new SimpleHash(  
            "SHA-256", // 哈希算法  
            password,  
            salt,  
            1024 // 哈希迭代次数  
    ).toString();  
      
    // 将用户名、加密后的密码和盐值存储到数据库中  
    // userMapper.insertUser(username, encryptedPassword, salt.toBytes());  
}

通过以上步骤,你就可以在Shiro中实现加密认证了。请注意,在实际应用中,你需要根据自己的业务需求和数据库结构进行相应的调整和优化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值