Shiro 框架详解

您所在的位置:网站首页 shiro密码加密 Shiro 框架详解

Shiro 框架详解

2023-05-17 20:37| 来源: 网络整理| 查看: 265

Shiro 是一款轻量级的 Java 安全框架,提供了身份认证、授权、加密和会话管理等功能。它可以集成到任何 Java Web 应用程序中,并且易于使用和扩展。Shiro 的设计理念是简洁而灵活,不仅可以应用于 Web 应用程序,还可以应用于命令行、移动设备和分布式系统等各种应用场景。

1. Shiro 的概述

Shiro 是一个开源的 Java 安全框架,由 Apache 开发和维护。Shiro 可以帮助开发人员快速实现安全特性,包括身份认证、授权、加密和会话管理等。Shiro 的目标是简化 Java 安全编程,并提供更好的开发体验。

Shiro 的主要特点如下:

易于学习和使用:Shiro 设计简单,易于学习和使用。 灵活性高:Shiro 可以适用于任何应用场景,支持多种应用程序类型。 安全性高:Shiro 的安全性能比较优越,提供了多种方式来保护应用程序的安全性。 扩展性好:Shiro 框架提供了可扩展性插件机制,可以方便地扩展框架的功能,满足不同的需求。 企业级支持:Shiro 是从 Apache 基金会获得支持的框架,拥有众多企业用户。 2. Shiro 的基本组件

Shiro 的基本组件包括 Subject、SecurityManager 和 Realms 等。下面我们分别介绍一下这些组件的作用和作用。

Subject

Subject 代表当前用户,是 Shiro 框架中最重要的组件之一。Subject 封装了用户的所有信息,包括身份(用户名和密码)和角色等。在一个应用程序中,可能有多个 Subject,每个 Subject 可以访问应用程序中的资源。

用户可以通过 Subject 登录应用程序,并执行诸如访问资源、修改个人配置等操作。Shiro 提供了简单易用的方法来管理用户的登录和退出行为,以及 Session 管理等。

SecurityManager

SecurityManager 是 Shiro 的核心组件,负责管理和协调整个应用程序的安全机制。它的主要职责是认证、授权、加密和会话管理等。

SecurityManager 将应用程序中的所有安全操作委托给适当的 Realms 进行处理,并存储和管理有关用户身份、角色和权限等信息。SecurityManager 还可以配置多个 Realms,以便应用程序可以集成不同的认证和授权方案。

Realm

Realm 是 SecurityManager 中负责处理用户身份认证和授权的组件。Shiro 支持多种不同类型的 Realm,包括 JDBC Realm、LDAP Realm、Active Directory Realm 等。

每个 Realm 负责验证用户的身份,并获取用户的权限信息,以便 SecurityManager 可以根据这些信息进行访问控制和授权。Realm 还可以实现缓存机制,提高系统性能。

3. Shiro 的权限控制

Shiro 提供了灵活的权限控制机制,可以对应用程序中的资源进行细粒度的访问控制。Shiro 的权限控制基于角色和权限的概念,其中:

角色是用户的一组角色,可以表示用户在系统中的不同身份; 权限是用户针对某个资源或操作所具有的权限。

Shiro 的权限控制机制包括以下几个步骤:

用户登录系统,通过 Subject 实例获取当前用户信息; 当用户进行某个操作时,Shiro 会根据用户请求的资源和操作类型,检查该用户是否具有执行该操作的权限。 如果用户具备该权限,则允许用户进行操作;否则,Shiro 会拒绝用户的请求,并返回相应的错误信息。

Shiro 支持多种方式来授权,包括基于角色和基于权限。角色授权是将用户分配到不同的角色,每个角色具有特定的权限,从而实现对用户的授权。权限授权是直接为用户授权某个资源或操作,从而实现对用户的授权。

4. Shiro 的会话管理

会话管理是 Web 应用程序中一个非常重要的安全特性。Shiro 提供了丰富的会话管理功能,包括 Cookie 管理、Session 管理和集群会话管理等。

Shiro 的会话管理机制包括以下几个步骤:

当用户登录系统时,Shiro 会自动创建一个 Session 对象,并将其关联到用户身份信息上,以便在整个应用程序生命周期内管理用户的会话状态。 用户进行某个操作时,Shiro 会检查该用户是否具有执行该操作的权限,并根据情况更新 Session 中的状态信息。 当用户退出系统时,Shiro 会清除用户的 Session 数据,并删除相关的 Session 记录。

Shiro 还支持集群会话管理,可以通过配置将会话信息存储在数据库、Redis 或其他数据源中,以便在分布式应用程序中进行会话管理。

5. Shiro 的加密与解密

Shiro 支持多种加密和解密算法,包括 MD5、SHA、AES 等。Shiro 不仅提供了简单易用的加密和解密 API,还提供了安全的密码管理和哈希函数实现。

在 Shiro 中,需要对密码进行加密和解密时,可以使用 Shiro 内置的加密和解密工具类。例如,我们可以使用 CredentialsMatcher 进行密码验证,或者使用 SimpleHash 类进行密码加密。

Shiro 的密码加密和解密功能的主要目的是保护用户的个人信息和隐私,防止其被黑客攻击和非法访问,从而提高系统的安全性。

6. Shiro 的集成开发

Shiro 可以与各种 Web 框架和数据源集成,以满足不同应用场景的需求。Shiro 的集成开发可以分为以下三个步骤:

配置 SecurityManager:首先,需要在应用程序的配置文件中配置 SecurityManager,以便为应用程序提供统一的身份验证和授权管理。 配置 Realm:其次,需要根据实际需要配置 Realm,以便根据数据库、LDAP 或其他数据源来验证用户身份,并获取用户权限信息。 配置 FilterChain:最后,需要配置 FilterChain,以便拦截访问请求,并根据用户的角色和权限等信息来判断是否允许用户进行访问。

在集成开发时,需要使用 Shiro 提供的相应 API 和插件来集成 Shiro 到应用程序中。具体来说,可以根据不同的框架和数据源选择不同的 Shiro 插件。例如,对于 Spring 应用程序,可以使用 Shiro-Spring 插件;对于数据源,可以使用 Shiro-JDBC 插件或 Shiro-LDAP 插件等。

7. Shiro 配置案例实战演练

首先,在 pom.xml 文件中添加依赖项:

org.springframework.boot spring-boot-starter-web org.mybatis.spring.boot mybatis-spring-boot-starter 2.2.0 org.apache.shiro shiro-core 1.7.1 org.apache.shiro shiro-spring 1.7.1 com.h2database h2 junit junit test

在上述依赖项中,我们引入了 Spring Boot、MyBatis 和 Shiro 的相关依赖项。

然后,我们实现一个 UserMapper 接口来操作用户数据:

@Mapper public interface UserMapper { User selectByUsername(String username); Set selectRolesByUsername(String username); Set selectPermissionsByUsername(String username); }

在该接口中,我们声明了 selectByUsername、selectRolesByUsername 和 selectPermissionsByUsername 三个方法,用于查询指定用户名的用户、角色和权限信息。

接下来,我们实现一个 User 实体类:

public class User implements Serializable { private Long id; private String username; private String password; private Boolean enabled; private Set roles; // getters and setters }

在该类中,我们定义了 id、username、password、enabled 和 roles 属性。roles 属性为一个 Set 集合,存储用户所拥有的角色信息。

然后,我们实现一个 Role 实体类:

public class Role implements Serializable { private Long id; private String name; private String description; private Set permissions; // getters and setters }

在该类中,我们定义了 id、name、description 和 permissions 属性。permissions 属性为一个 Set 集合,存储角色所拥有的权限信息。

最后,我们实现一个 Permission 实体类:

public class Permission implements Serializable { private Long id; private String name; private String description; // getters and setters }

在该类中,我们定义了 id、name 和 description 属性,用于存储权限信息。

接下来,我们需要实现 ShiroConfig 类来完成 Shiro 配置:

@Configuration public class ShiroConfig { @Bean public DefaultWebSecurityManager securityManager(Realm realm) { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(realm); return securityManager; } @Bean public Realm realm() { MyShiroRealm myShiroRealm = new MyShiroRealm(); myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher()); return myShiroRealm; } @Bean public CredentialsMatcher hashedCredentialsMatcher() { HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher(); credentialsMatcher.setHashAlgorithmName(Sha256Hash.ALGORITHM_NAME); credentialsMatcher.setStoredCredentialsHexEncoded(false); return credentialsMatcher; } @Bean public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) { ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean(); shiroFilter.setSecurityManager(securityManager); Map filterChainDefinitionMap = new LinkedHashMap(); filterChainDefinitionMap.put("/login", "anon"); filterChainDefinitionMap.put("/logout", "logout"); filterChainDefinitionMap.put("/admin/**", "authc, roles[admin]"); shiroFilter.setFilterChainDefinitionMap(filterChainDefinitionMap); shiroFilter.setLoginUrl("/login"); shiroFilter.setSuccessUrl("/"); shiroFilter.setUnauthorizedUrl("/unauthorized"); return shiroFilter; } }

在该类中,我们通过 @Bean 注解定义了 Shiro 的安全管理器、Realm、CredentialsMatcher 和过滤器链等相关配置。其中,我们使用 MyShiroRealm 来连接数据库,并设置了密码加密算法为 SHA-256。

然后,我们可以定义一个 UserController 类来处理用户相关的请求和操作:

@RestController public class UserController { @Autowired private UserService userService; @PostMapping("/login") public String login(@RequestParam String username, @RequestParam String password) { Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken(username, password); try { subject.login(token); return "login success"; } catch (AuthenticationException e) { return "login failed"; } } @GetMapping("/admin/users") @RequiresRoles("admin") public List getUsers() { return userService.getAllUsers(); } }

在该类中,我们定义了 login 方法用于进行身份认证操作,接受用户名和密码参数,并调用 Shiro 提供的 Subject 对象对用户进行身份认证。如果身份认证成功,则返回字符串 "login success",否则返回 "login failed"。

另外,getUsers 方法用于获取所有用户列表,在访问该 URL 时,需要用户具有 admin 角色权限才能访问。我们可以使用 @RequiresRoles 注解来对该方法进行授权管理。

最后,我们实现一个 UserService 类来操作用户数据:

@Service public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Override public User getByUsername(String username) { return userMapper.selectByUsername(username); } @Override public Set getRolesByUsername(String username) { return userMapper.selectRolesByUsername(username); } @Override public Set getPermissionsByUsername(String username) { return userMapper.selectPermissionsByUsername(username); } @Override public List getAllUsers() { return userMapper.selectAllUsers(); } }

在该类中,我们使用 UserMapper 接口来访问数据库,实现了根据用户名获取用户、获取用户角色和权限以及获取所有用户列表的方法。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3