Shiro框架的知识点一网打尽,生命不息,学习不止

简介: Shiro框架的知识点一网打尽,生命不息,学习不止

Shiro框架介绍

Shiro是一个开源的安全框架,它提供了身份认证、授权和加密等功能。Shiro具有灵活的扩展性和可配置性,可以与各种Java应用程序集成。本文将介绍Shiro框架的基本原理、主要功能和特点、使用场景以及与其他框架的比较,最后给出一个Shiro应用举例。

一、什么是shiro框架

Shiro是一个安全框架,它提供了身份认证、授权和加密等功能。Shiro的核心组件包括Realm、SecurityManager和Cache等。Realm用于管理用户和对象,SecurityManager用于控制用户访问权限,Cache用于管理会话和缓存数据。

二、shiro的工作原理

Shiro的工作原理如下:

  1. 用户通过登录请求到达SecurityManager进行身份认证。
  2. SecurityManager验证用户的身份信息,如果验证成功则生成一个Token并返回给客户端。
  3. Token被客户端保留并在后续请求中作为身份凭证传递给各个服务端点。
  4. 服务端点对Token进行验证,如果验证成功则允许用户访问相应的资源,否则拒绝访问。
  5. 如果用户需要执行敏感操作(如修改密码),则需要进行加密处理以保证安全性。

三、shiro的主要功能和特点

Shiro的主要功能和特点如下:

  1. 灵活的认证和授权机制:Shiro支持多种认证方式(如基于数据库的用户名密码认证、LDAP认证、OAuth2认证等),同时支持多种授权方式(如基于角色的访问控制、基于资源的访问控制等)。
  2. 强大的缓存机制:Shiro内置了缓存机制,可以缓存用户的认证信息、会话信息和授权信息等,从而提高系统的性能和响应速度。
  3. 易于集成:Shiro提供了丰富的API和文档,可以方便地与其他框架或工具集成,如Spring、Hibernate、Apache Tomcat等。
  4. 可扩展性强:Shiro提供了丰富的插件和扩展点,可以根据具体需求定制自己的安全策略和实现。
  5. 安全性高:Shiro内置了多种安全机制,如加密、防止跨站点脚本攻击、防止会话劫持等,可以保护系统不受各种安全威胁。

四、shiro的使用场景

Shiro适用于各种Java应用程序的安全控制,下面是一些Shiro适用的场景:

  1. Web应用程序:Shiro可以为Web应用程序提供身份认证和授权功能,从而保护Web应用程序的安全性和可靠性。
  2. RESTful API:Shiro可以为RESTful API提供身份认证和授权功能,从而保护API的数据安全和隐私性。
  3. 分布式系统:Shiro可以为分布式系统提供身份认证和授权功能,从而保护系统的安全性和一致性。
  4. 单点登录系统:Shiro可以为单点登录系统提供身份认证和授权功能,从而简化用户的登录流程和提高系统的可用性。
  5. 企业级应用:Shiro可以为企业级应用提供身份认证和授权功能,从而保护企业的安全性和合规性。

五、shiro与其他框架的比较

Shiro与其他安全框架相比具有以下优点:

  1. 灵活性:Shiro提供了灵活的扩展性和可配置性,可以根据具体需求定制自己的安全策略和实现。
  2. 性能优化:Shiro内置了缓存机制,可以提高系统的性能和响应速度。
  3. 易用性:Shiro提供了丰富的API和文档,可以方便地与其他框架或工具集成。
  4. 安全性高:Shiro内置了多种安全机制,可以保护系统不受各种安全威胁。
  5. 可扩展性强:Shiro提供了丰富的插件和扩展点,可以根据具体需求定制自己的安全策略和实现。

相比之下,其他安全框架可能存在以下缺点:

  1. 不够灵活:其他安全框架可能缺乏灵活性,无法满足某些特殊需求。

六、shiro应用举例

下面是一个使用Shiro框架的Java Web应用程序示例:

1. 引入Shiro和相关依赖:

<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-core</artifactId>
    <version>1.8.0</version>
</dependency>

2. 创建Shiro的配置:

public class MyShiroConfig {
    private static SecurityManager securityManager = null;
    public static SecurityManager getSecurityManager() {
        if (securityManager == null) {
            DefaultSecurityManager securityManager = new DefaultSecurityManager();
            securityManager.setRealm(new MyRealm()); // 设置自定义Realm
            SecurityUtils.setSecurityManager(securityManager);
            return securityManager;
        }
        return securityManager;
    }
}

3. 创建Realm:

public class MyRealm extends AuthorizingRealm {
    // 模拟用户和角色信息
    private static Map<String, String> userMap = new HashMap<>();
    private static Map<String, Set<String>> roleMap = new HashMap<>();
    static {
        userMap.put("admin", "123456");
        roleMap.put("admin", new HashSet<>(Arrays.asList("admin")));
        userMap.put("user", "123456");
        roleMap.put("user", new HashSet<>(Arrays.asList("user")));
    }
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        String username = (String) principals.getPrimaryPrincipal();
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        authorizationInfo.setRoles(roleMap.get(username));
        return authorizationInfo;
    }
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String username = (String) token.getPrincipal();
        String password1 = userMap.get(username);
        if (password1 == null) {
            throw new UnknownAccountException();
        }
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(username, password1, getName());
        return authenticationInfo;
    }

4. 配置访问控制

public class MyFilterChainDefinition {
    private static Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
    static {
        filterChainDefinitionMap.put("/admin/**", "roles[admin]");
        filterChainDefinitionMap.put("/user/**", "roles[user]");
        filterChainDefinitionMap.put("/login", "anon");
        filterChainDefinitionMap.put("/**", "authc");
    }
    public static Map<String, String> getFilterChainDefinitionMap() {
        return filterChainDefinitionMap;
    }
}

5. 测试

public class TestShiro {
    public static void main(String[] args) {
        SecurityManager securityManager = MyShiroConfig.getSecurityManager();
        SecurityUtils.setSecurityManager(securityManager);
        Subject currentUser = SecurityUtils.getSubject();
        String username = "admin";
        String password2 = "12345612";
        currentUser.login(new UsernamePasswordToken(username, password2)); // 登录
        System.out.println("是否登录成功:" + currentUser.isAuthenticated());
        System.out.println(username + "是否有角色 user:" + currentUser.hasRole("user")); // 返回false
        currentUser.logout(); // 登出
        System.out.println("是否已经登出:" + currentUser.isAuthenticated());
    }
}

在上述示例里,我们模拟了两个用户:admin和user,admin拥有admin角色,user拥有user角色。

访问/admin/**的URL必须要拥有admin角色才能访问,同理,/user/**的URL需要拥有user角色才能访问。

在测试代码中,我们实现了登录和登出操作,并且判断admin用户是否有user角色,最终输出登录状态和是否拥有user角色的判断结果。

七、总结

Shiro框架是一个功能强大的安全框架,它提供了身份认证、授权、加密等多种安全功能。Shiro具有灵活性高、性能好、易用性好等特点,可以满足各种Java应用程序的安全需求。通过本文的介绍,我们了解了Shiro的基本原理、主要功能和特点以及使用场景,希望能够对大家学习和应用Shiro框架有所帮助。

相关文章
|
2月前
|
Java 数据库连接 程序员
从头到尾手把手教你搭建阅读Mybatis源码的环境(程序员必备技能)
从头到尾手把手教你搭建阅读Mybatis源码的环境(程序员必备技能)
128 0
|
10月前
|
XML Java 数据格式
肝了30天总结,史上最全面透彻的Spring核心原理分析和27道高频面试题
在阅读面试题之前,小伙伴们可以先看看我之前发布的系列文章,Spring核心原理包括源码分析和用30个类手写。面试刷题固然很重要,但是知其然知其所以然更重要。
894 4
肝了30天总结,史上最全面透彻的Spring核心原理分析和27道高频面试题
|
8月前
|
Java 程序员 应用服务中间件
【推荐】深入浅出学习Spring框架【上】
【推荐】深入浅出学习Spring框架【上】
41 0
|
29天前
|
XML 缓存 Java
大厂面试攻略:Spring框架核心要点精讲
Java SPI (Service Provider Interface) 是一种服务发现机制,允许在运行时动态加载和发现服务提供者。在数据库驱动加载中,SPI使得数据库驱动能够自动识别和注册,而无需显式加载。 Spring 是一个广泛应用的轻量级框架,核心功能包括依赖注入(DI)和面向切面编程(AOP)。不使用Spring时,开发人员需要手动管理对象的创建和依赖关系,使用Servlet等基础组件完成Web开发,以及手动处理JDBC操作。Spring通过管理Bean的生命周期和依赖关系,简化了企业级应用的开发,降低了代码的侵入性。
34 1
大厂面试攻略:Spring框架核心要点精讲
|
11月前
|
Java 关系型数据库 MySQL
|
8月前
|
存储 监控 Java
【推荐】深入浅出学习Spring框架【中】
【推荐】深入浅出学习Spring框架【中】
28 0
|
10月前
|
Java 网络安全 Spring
SSH框架学习中遇到的问题
SSH框架学习中遇到的问题
36 0
|
11月前
|
缓存 应用服务中间件

热门文章

最新文章

  • 1
    流量控制系统,用正则表达式提取汉字
    25
  • 2
    Redis09-----List类型,有序,元素可以重复,插入和删除快,查询速度一般,一般保存一些有顺序的数据,如朋友圈点赞列表,评论列表等,LPUSH user 1 2 3可以一个一个推
    26
  • 3
    Redis08命令-Hash类型,也叫散列,其中value是一个无序字典,类似于java的HashMap结构,Hash结构可以将对象中的每个字段独立存储,可以针对每字段做CRUD
    25
  • 4
    Redis07命令-String类型字符串,不管是哪种格式,底层都是字节数组形式存储的,最大空间不超过512m,SET添加,MSET批量添加,INCRBY age 2可以,MSET,INCRSETEX
    27
  • 5
    S外部函数可以访问函数内部的变量的闭包-闭包最简单的用不了,闭包是内层函数+外层函数的变量,简称为函数套函数,外部函数可以访问函数内部的变量,存在函数套函数
    23
  • 6
    Redis06-Redis常用的命令,模糊的搜索查询往往会对服务器产生很大的压力,MSET k1 v1 k2 v2 k3 v3 添加,DEL是删除的意思,EXISTS age 可以用来查询是否有存在1
    30
  • 7
    Redis05数据结构介绍,数据结构介绍,官方网站中看到
    21
  • 8
    JS字符串数据类型转换,字符串如何转成变量,+号只要有一个是字符串,就会把另外一个转成字符串,- * / 都会把数据转成数字类型,数字型控制台是蓝色,字符型控制台是黑色,
    19
  • 9
    JS数组操作---删除,arr.pop()方法从数组中删除最后一个元素,并返回该元素的值,arr.shift() 删除第一个值,arr.splice()方法,删除指定元素,arr.splice,从第一
    19
  • 10
    定义好变量,${age}模版字符串,对象可以放null,检验数据类型console.log(typeof str)
    19