shiro

Shiro 三大核心组件:
1.Subject                   
2.Security Manager (核心)                   
3.Realm

3.Realm  进行用户账号密码校验(可以去数据库 或者 shiro.ini 文件)

在这里插入图片描述


工作原理:
1:用户通过账号密码登录,账号信息包装在Subject中去请求 SecurityManager 
2:SecurityManager 将账号信息通过Realm进行认证(Realm直接取数据库或	文件的		数据)
3: SecurityManager 校验通过将进行授权,授权后的数据再次封装在Subject中
4:也就是说Subject最后封装的是用户信息和权限信息,全局直接取就行

***javaEE项目核心展示:  *******

首先目录结构
在这里插入图片描述

pom:**********************************
   <dependencies>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-core</artifactId>
            <version>1.4.1</version>
        </dependency>
    </dependencies>
main:**********************************

 public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入账号:");
        String username= sc.nextLine();
        System.out.println("请输入密码:");
        String password= sc.nextLine();

        // 1. 创建安全管理器
        DefaultSecurityManager securityManager = new DefaultSecurityManager();
        //2.创建Realm
        IniRealm iniRealm = new IniRealm("classpath:shiro.ini");//Realm 的数据
        //3.将Realm 设置给安全管理器
        securityManager.setRealm(iniRealm);
        //4.将Realm 设置给SecurityUtis工具类
        SecurityUtils.setSecurityManager(securityManager);
        //5.通过SecurityUtis工具类获取subject对象
        Subject subject = SecurityUtils.getSubject();

        //【认证流程】
        //a.将认证账号和密码封装到token对象中
        UsernamePasswordToken token = new UsernamePasswordToken(username,password);
        //b.通过subject对象调用login方法进行认证申请
        boolean b =false;
        try {
            subject.login(token);
            b=true;
        }catch (IncorrectCredentialsException e){//账号密码错误
            b=false;
        }
        System.out.println(b?"登陆成功":"登陆失败");


        //【授权流程】
        // 检查用户是否有这个角色
        System.out.println(subject.hasRole("seller"));


        //判断是否有某个权限
        boolean pemitted = subject.isPermitted("order-del");
        System.out.println(pemitted);
    }

shiro.ini ***********************
[users]
zhangsan=123456,seller
lisi=666666,ckmgr
admin=123123,admin

[roles]
admin=*
seller=order-add,order-del,order-list
ckmgr=ck-add,ck-del,ck-list








五.基于javaSE应用-Shiro基本使用
1.创建maven项目
2.导入Shiro依赖库
<dependencies>
    <dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-core</artifactId>
        <version>1.4.1</version>
    </dependency>
</dependencies>


3.创建Shiro配置文件
在resource下创建shiro.ini文件
在文件中完成用户,角色及权限的配置

[users]
zhangsan=123456,seller
lisi=666666,ckmgr
admin=123123,admin

[roles]
admin=*
seller=order-add,order-del,order-list
ckmgr=ck-add,ck-del,ck-list

六.Shiro的基本使用
核心应用:
public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    System.out.println("请输入账号:");
    String username= sc.nextLine();
    System.out.println("请输入密码:");
    String password= sc.nextLine();

    // 1. 创建安全管理器
    DefaultSecurityManager securityManager = new DefaultSecurityManager();
    //2.创建Realm
    IniRealm iniRealm = new IniRealm("classpath:shiro.ini");//Realm 的数据
    //3.将Realm 设置给安全管理器
    securityManager.setRealm(iniRealm);
    //4.将Realm 设置给SecurityUtis工具类
    SecurityUtils.setSecurityManager(securityManager);
    //5.通过SecurityUtis工具类获取subject对象
    Subject subject = SecurityUtils.getSubject();

    //【认证流程】
    //a.将认证账号和密码封装到token对象中
    UsernamePasswordToken token = new UsernamePasswordToken(username,password);
    //b.通过subject对象调用login方法进行认证申请
    boolean b =false;
    try {
        subject.login(token);
        b=true;
    }catch (IncorrectCredentialsException e){//账号密码错误
        b=false;
    }
    System.out.println(b?"登陆成功":"登陆失败");


    //【授权流程】
    // 检查用户是否有这个角色
    System.out.println(subject.hasRole("seller"));


    //判断是否有某个权限
    boolean pemitted = subject.isPermitted("order-del");
    System.out.println(pemitted);
}


七.SpringBoot整合Shiro


yml:
spring:
  datasource:
    druid:
      url: jdbc:mysql://127.0.0.1:3306/shiro
      driver-class-name: com.mysql.cj.jdbc.Driver
      #如果数据库是8.x com.mysql.cj.jdbc.Driver
      username: root
      password: root
      initial-size: 1
      min-idle: 1
      max-active: 20
mybatis:
  mapper-locations: classpath:mappers/*Mapper.xml
  type-aliases-package: com.shiro.beans

pom:
<!--lombok-->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>
<!--druid-->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.1.10</version>
</dependency>
<!--mysql-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.47</version>
</dependency>
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.0.1</version>
</dependency>



shiro的config配置文件******核心
//数据库读取方式
@Bean
public JdbcRealm geJdbcRealm(DataSource dataSource){
    JdbcRealm jdbcRealm = new JdbcRealm();
    //jdbcrealm 会自己在数据库查数据,前提是数据表结构满足jdbcrelam规范
    //DataSource  从哪来的  ,是我们配置好的duride数据源,他会自动装配到spring容器
    jdbcRealm.setDataSource(dataSource);
    //jdbcRealm默认开启认证,需要手动开启授权功能
    jdbcRealm.setPermissionsLookupEnabled(true);//PermissionsLookupEnabled  权限开启已启用
    return jdbcRealm;
}

//数据库读取方式
@Bean
public  DefaultWebSecurityManager getDefaultWebSecurityManager(JdbcRealm jdbcRealm){
    DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
    //security 要完成校验就需要 realm
    securityManager.setRealm(jdbcRealm);
    return securityManager;
}



@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager) {
    ShiroFilterFactoryBean filter = new ShiroFilterFactoryBean();
    //过滤器就是shiro进行权限校验的核心,进行认证和权限是需要SecurityManager
    filter.setSecurityManager(securityManager);

    //过滤器设置拦截规则
    //anon   匿名用户可访问(任何人都行)
    //authc  认证用户可访问(登陆过的)
    //user   使用RememberMe的用户可访问
    //perms  对应权限可访问
    //role   对应的角色可访问
    Map<String,String> filterMap = new HashMap<String, String>();
    filterMap.put("/","anon"); //根路径不拦截
    filterMap.put("/login.html","anon");//登录界面不拦截
    filterMap.put("/regist.html","anon");//注册界面不拦截
    filterMap.put("/user/login","anon");//登录路由不拦截
    filterMap.put("/user/regist","anon");//注册路由不拦截
    filterMap.put("/static/**","anon");//静态文件不拦截
    filterMap.put("/**","authc");// 除了以上的不拦截,其他的都有需要登陆后才能访问
filterMap.put("/exit","logout");// 退出(并且在页面配置a href =“exit”)


    filter.setFilterChainDefinitionMap(filterMap);

    //设置登陆页面
    filter.setLoginUrl("/login.html");
    //设置未授权访问页面
    filter.setUnauthorizedUrl("/login.html");
    return  filter;
}

filterMap.put("/exit","logout");// 退出(并且在页面加 a href =“exit”)
不需要走 controller层



若要html中支持shiro需要导入这个依赖
<!--  thymeleaf      -->
<dependency>
    <groupId>com.github.theborakompanioni</groupId>
    <artifactId>thymeleaf-extras-shiro</artifactId>
    <version>2.0.0</version>
</dependency>


在html中引入thymeleaf 模板
<html xmlns:th="http://www.thymeleaf.org"
      xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
html中常用的shiro标签,这个就是调用subject是否登录
<shiro:guest>
    欢迎游客,<a href="login.html">登录</a>
</shiro:guest>
<shiro:user> //用户登陆的信息
    欢迎你,[<shiro:principal/>] //用户名
</shiro:user>


授权:
操作数据之前,进行权限检查,有两种做法,
1.用户登录后只显示他能看到的菜单,通过页面的标签判断
<shiro:hasPermission name=”sys:c:save”>
<a href=”#”>入库</a>
</shiro:hasPermission>

2.过滤器授权,显示所有菜单,看他有权限访问这个菜单吗(防止自己主动输入路径越权访问)
2.1配置类控制好
只要访问c_add页面,必须有sys:c:save权限
filterMap.put("/c_add.html","perms[sys:c:save]");

跳转未授权页面
filter.setUnauthorizedUrl("/lesspermission.html");

  2.2配置spring对shiro注解控制权限的支持(访问路径的权限)
//让注解加载执行,就是让控制权限的注解加入到这个类中让他处理
@Bean
public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator(){
    DefaultAdvisorAutoProxyCreator autoProxyCreator = new DefaultAdvisorAutoProxyCreator();
    autoProxyCreator.setProxyTargetClass(true);
    return autoProxyCreator;

}

//注解加载器,在注解上控制权限,需要在这里生效注解
@Bean
public AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager){
    AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
    advisor.setSecurityManager(securityManager);
    return  advisor;
}

//添加注解
//如果没有sys:k:find ,就不让访问这个路径
@RequiresPermissions("sys:k:find")
@RequestMapping("list")
public String list(){
    System.out.println("--------------》查询客户信息");
    return "customer_list";
}

权限不足抛异常,
spring配置全局异常错误

//全局异常处理类
@ControllerAdvice
public class GlobalExceptionHandler {

    //抛出 AuthorizationException 这个异常走这个方法
    @ExceptionHandler
    public String doException(Exception e){
        if(e instanceof AuthorizationException){
            return "lesspermission";
        }
        return null;
    }
}


2.3代码控制权限,从subject中取出权限进行控制
@RequestMapping("list")
public String list(){
    Subject subject = SecurityUtils.getSubject();
    if(subject.isPermitted("sys:k:find")){
        System.out.println("--------------》查询客户信息");
        return "customer_list";
    }else{
        return "lesspermission";
    }

}



缓存:
跟权限有关的界面,每次点击都需要访问 realm 中的doGetAuthorticationInfo 进行查询跟权限相关的角色和权限信息
1.导入依赖
开启缓存的支持
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>

将shiro的缓存读进来
<dependency>
    <groupId>net.sf.ehcache</groupId>
    <artifactId>ehcache</artifactId>
    <version>2.10.6</version>
</dependency>

shiro的缓存,
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-cache</artifactId>
    <version>1.4.1</version>
</dependency>

2.配置缓存策略
在resource 下创建一个 ehcache.xml的文件 	
<?xml version="1.0" encoding="utf-8" ?>

<encache updateCheck="false" dynamicConfig="false">

<diskStore path="D:\cache" />

<cache name="users" timeToLiveSeconds="300" maxEntriesLocalHeap="1000"/>
<defaultCache name="defauleCache"
              maxElementsInMemory="10000"
              eternam="false"
              timeToIdleSeconds="120"
              timeLiveSeconds="120"
              overflowToDisk="100000"
              diskPersistent="false"
              diskExpiryTheadIntervalSecond="120"
              memoryStoreEvictionPolicy="LRU"/>
            <!--  缓存淘汰策略 算法
              LRU  最近最少使用
              FIFO 先进先出
              LFU  最少使用
              -->
</encache>


3 shiro.config配置文件
@Bean
public EhCacheManager getEhCacheManager(){
    EhCacheManager ehCacheManager = new EhCacheManager();
    ehCacheManager.setCacheManagerConfigFile("classpath:ehcache.xml");
    return ehCacheManager;
}

@Bean
public  DefaultWebSecurityManager getDefaultWebSecurityManager(MyRealm myRealm){
    DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
    //security 要完成校验就需要 realm
    securityManager.setRealm(myRealm);
    //设置缓存
    securityManager.setCacheManager(getEhCacheManager());
    return securityManager;
}


session 管理器:
shiro 默认管理了session 可以自定义设置超时时间:


1.设置session过期时间:
@Bean
public DefaultSessionManager getDefaultSessionManager(){
    DefaultSessionManager sessionManage = new DefaultSessionManager();
    System.out.println("---------------"+sessionManage.getGlobalSessionTimeout());
    sessionManage.setGlobalSessionTimeout(15*1000);//15return sessionManage;
}

2.加入到SecurityManager:

//设置session过期时间
securityManager.setSessionManager(getDefaultSessionManager());

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值