安全框架Shiro全方位讲解与功能性代码的实现

Apache Shiro

一. 什么是Apache Shiro?
shiro 是基于java的开源的安全管理框架,可以完成认证,授权,会话管理,加密和缓存功能。
二. 为什么要学习 Shiro?
在java 世界中,安全框架有 spring security ,他要依赖于spring,并且比较复杂。shiro比较简单,并且独立。既可以在javase中使用,还可以在javaee中使用,也可以在分布式环境下使用。
三. shiro的结构体系:
在这里插入图片描述
Primary Concerns 主要的内容,--------shiro的四大基石。

  • Authentication
    认证。验证用户的合法性行为,也就是登录认证。
  • Authorization
    授权 。 授予谁具有访问某些资源的权限。
  • Session Manangement
    会话管理。用户登录后的用户信息通过session Management来管理。
  • Cryptography
    加密 。它为我们提供了一些常见的加密算法。并且使用很便捷,实现了数据安全性

Supporting Features --------shiro支持的特性

  • web Support
    对web应用程序支持,可以很方便的集成web应用程序。

  • Caching
    shiro提供了缓存的支持,支持多种缓存,如:ehcache,redis等

  • Concurrenty
    并发支持,支持多个线程并发访问。

  • Test
    测试。

  • Run As
    支持一个用户在允许的前提下使用另外一个身份登录访问。

  • Remember me
    记住我

四. shiro的架构:
在这里插入图片描述

  • Subject 主体:
    一般指用户,subject用来获取主体信息,通过Principals和
    Credentials。

  • Security Manager 安全管理器
    安全管理器是shiro的核心。有它来协调管理shiro各个组件的工作。

  • Authenticator 认证管理器
    负责验证用户身份

  • Authorizer 授权管理器
    负责为合法的用户授权,控制用户可以访问哪些资源。

  • Realms 域
    负责与数据库打交道。

五.接下来我们正式说说各个模块的具体的代码实现。

一. Authentication:用户认证
需要提交身份和凭证给shiro。
Principals:用户的身份信息,是subject的标识属性。能够唯一标识subject。如:电话号码,身份证号码,电子邮箱等等。
Credentials:凭证,也就是密码。只被subject知道的秘密值。

Principals和Credentials最常见的组合就是:用户名/密码。在shiro中
通过usernamePasswordToken来指定。
usernamePasswordToken(传入参数就是username,password)

认证流程代码实现
1.导入依赖:

 <!--Shiro核心框架 -->
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-core</artifactId>
                <version>${shiro.version}</version>
            </dependency>
            <!-- Shiro使用Srping框架 -->
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-spring</artifactId>
                <version>${shiro.version}</version>
            </dependency>
            <!--shiro与整合表现层-->
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-web</artifactId>
                <version>${shiro.version}</version>
            </dependency>
            !-- thymeleaf模板引擎和shiro框架的整合 -->
            <dependency>
                <groupId>com.github.theborakompanioni</groupId>
                <artifactId>thymeleaf-extras-shiro</artifactId>
                <version>${thymeleaf-extras-shiro.version}</version>
            </dependency>

2.编写代码:

2.1 首先先一个shiro配置类
安全管理器(SecurityManager ),会调用认证管理器(Authenticator ),认证管理器里面有认证策略,会调用自定义realm,通过realm来读取数据库中的用户信息,shiro框架会自动跟subject提交登录时传入的token进行比对。实现认证。


 /**
 * Created by Zrj on
 *
 * @DATE: 2020/8/29
 * @TIME: 18:09
 */
@Configuration
public class ShiroConfig {
//因为shiro核心是安全管理器,所以首先要配置一个安全管理器,来管理各个组件的执行
//(认证器,授权器,加密器,会话管理器),然后定义realm将它设置进去。
//最后需要将安全管理器加入到shiro中去。也就是配置一个filter
    @Bean
    public MyRealm MyRealm(){
        return new MyRealm();
    }
    //首先要配置一个安全管理器,来管理各个组件的执行(认证器,授权器,加密器,会话管理器)
    @Bean
    public SecurityManager SecurityManager(MyRealm myRealm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(myRealm);
        return securityManager;
    }
    /**
     * Shiro过滤器的配置
     * 这里可以配置认证规则:
     * anon:无需认证
     * authc: 需要认证
     * 授权规则:
     * perms:必须拥有某个权限才能访问。
     * role:必须拥有某个角色才能访问。
     * rest:必须是restful风格的请求,post,get,delete,put
     * ssl:必须是安全的请求,即https访问。
     * @return
     */
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        //shiro的核心安全接口,需要把它设置进去,进行shiro的管理
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        return shiroFilterFactoryBean;
    }
      /**
     * AOP式方法级权限检查
     */
    @Bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator(){
        DefaultAdvisorAutoProxyCreator creator=new DefaultAdvisorAutoProxyCreator();
        creator.setProxyTargetClass(true);
        return creator;
    }

    /**
     * 开启Shiro注解通知器
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor advisor=new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(securityManager);
        return advisor;
    }
    /**
     * thymeleaf模板引擎和shiro框架的整合
     */
    @Bean
    public ShiroDialect shiroDialect()
    {
        return new ShiroDialect();
    }
}

2.2 自定义realm

//需要继承  AuthorizingRealm类。并实现俩个方法
public class MyRealm extends AuthorizingRealm {

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

    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        UsernamePasswordToken usernamePasswordToken=(UsernamePasswordToken)token;
        String username = usernamePasswordToken.getUsername();
        String password = String.valueOf(usernamePasswordToken.getPassword());
       User user= userService.login(username,password);
       if (user!=null){
           return new SimpleAuthenticationInfo(username,password,getName());
       }
       throw new UnknownAccountException("认证失败");
    }
}

2.3 编写登录类

 @RequestMapping("/doLogin")
 @ResponseBody
    public AjaxResult login(String username, String password){
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        Subject subject = SecurityUtils.getSubject();
        try {
            subject.login(token);
           return AjaxResult.success();
        }catch (Exception e){
            e.getMessage();
        }
        return AjaxResult.fail("用户名或者密码错误");

    }

这里我想说明一下:身份和凭证会放到usernamePasswordToken里面去,
在自定义realm中的认证方法参数就能拿到该token信息。

在身份认证过程中,往往会涉及到加密,shiro内部实现了很多的加密算法。如:MD5,SHA等。并且提供了加盐功能。
MD5演示:

**
 * shiro中提供的md5加密算法
 */
public class MD5Test {

    public static void main(String[] args) {
        //只对密码加密
        Md5Hash md5Hash = new Md5Hash("1111");
        //加盐加密
        Md5Hash md5Hash1 = new Md5Hash("1111","zrj");
        //加盐加散列次数加密
        Md5Hash md5Hash2 = new Md5Hash("1111","zrj",1024);
        SimpleHash shash=new SimpleHash("md5","1111","zrj",1024);
        System.out.println(md5Hash.toString());
        System.out.println(md5Hash1.toString());
        System.out.println(md5Hash2.toString());
        System.out.println(shash.toString());
    }

在这里插入图片描述

一. Authorization:授权
权限粒度:

  • 粗粒度和细粒度
    shiro一般管理的是粗粒度的权限。比如:(菜单,按钮,url)
    一般细粒度的权限是通过业务来控制的。

  • 权限的表示规则:
    资源:操作:实例。 可以用通配符表示
    例如:user:add 表示对user有添加的权限。
    user:* 表示对user有所有操作的权限。
    这种就是细粒度的操作了-- user:delete:100 表示对user表示的第100条记录有删除权限。
    代码实现:

 //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        User user= (User) SecurityUtils.getSubject().getPrincipal();

        //给角色资源进行授权对象
        SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();

        // 角色列表
        Set<String> roles = new HashSet<String>();
        // 功能列表
        Set<String> menus = new HashSet<String>();
        if (user.getId()!=null && 1L ==user.getId()){   //判断是否为管理员,管理员拥有所有权限
            info.addRole("超级管理员");
            info.addStringPermission("*:*:*");
        }else {      //否则的话,根据用户对应的角色,角色对应的权限,查询出来放到授权对象中
            roles = userService.selectRoleByUserId(user.getId());
            menus=menuService.selectPremsByUserId(user.getId());
             //角色加入授权对象
            info.addRoles(roles);
            //权限加入授权对象
            info.addStringPermissions(menus);
        }
        return info;
    }

前台页面就可以根据
标签shiro:hasPermission=“” ,或者shiro:hasRole=“”等等进行按钮以及菜单的权限控制。
后台可以通过,
shiro注解控制到方法级别。例如: @RequiresPermissions("")等等,如果没有对应的权限无法访问。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值