shiro入门学习

shiro

shiro是一个轻量级的安全权限框架,可以完成认证、授权、加密、会话管理、与web集成、缓存等

shiro架构

在这里插入图片描述
在这里插入图片描述

  • Subject:应用代码直接交互的对象就是Subject,也就是说Shiro的对外API核心就是SubjectSubject代表了当前用户,这个用户不一定是一个具体的人,可以代表与当前应用交互的任何东西;与Subject的所有交互都会委托给SecurityManager
  • SecurityManager:安全管理器;即所有与安全相关的操作都会与SecurityManager交互,并且管理者所有Subject;是shiro的核心,它负责与Shiro的其他组件进行交互,它相当于SpringMVC里面DispatcherServlet的角色
  • Realm:Shiro从Realm获取安全数据(如用户、角色、权限)

shiro hello world

Subject currentUser = SecurityUtils.getSubject();
Session session = currentUser.getSession();
currentUser.isAuthenticated()
currentUser.hasRole("xxx")
currentUser.getPrincipal()currentUser.isPermitted("xxx:xxx")

SpringBoot 集成Shiro

1、导入依赖

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

<!--        整合shiro-->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring-boot-starter</artifactId>
            <version>1.7.1</version>
        </dependency>
    </dependencies>

2、创建Shiro配置文件

@Configuration
public class ShiroConfig {
    //ShiroFilterFactoryBean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager){
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        //设置安全管理器
        shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
        return shiroFilterFactoryBean;
    }


    //DefaultWebSecurityManager
    @Bean
    public DefaultWebSecurityManager defaultWebSecurityManager(UserRealm userRealm){
        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();

        //关联UserRealm
        defaultWebSecurityManager.setRealm(userRealm);

        return defaultWebSecurityManager;
    }


    //创建 realm对象
    @Bean
    public UserRealm userRealm(){
        return new UserRealm();
    }

}

3、添加shiro过滤器

@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager){
    ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
    //设置安全管理器
    bean.setSecurityManager(defaultWebSecurityManager);

    //添加shiro过滤器
    /**
     * anon:无需认证
     * authc:必须认证才能访问
     * user:必须拥有记住我,才可以访问
     * perms:拥有对某个资源的权限才能访问
     * role:拥有某个角色权限才能访问
     */
    Map<String, String> filterChainMap = new LinkedHashMap<>();
    filterChainMap.put("/user/add","authc");
    filterChainMap.put("/user/update","authc");
    bean.setFilterChainDefinitionMap(filterChainMap);
    //添加登录页面
    bean.setLoginUrl("/toLogin");
    return bean;
}
  • 如果用户未登录访问需要认证的请求,会跳转到登录页面

4、用户认证

//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
    //测试用户
    String username = "root";
    String password = "root";
    UsernamePasswordToken user = (UsernamePasswordToken) token;
    if (!(user.getUsername().equals(username))){
        return null;//抛出异常 UnKnownAccountException
    }
    System.out.println("执行了认证方法");
    //密码认证,shiro做
    return new SimpleAuthenticationInfo("",password,"");
}

5、用户授权

//添加shiro过滤器
/**
 * anno:无需认证
 * authc:必须认证才能访问
 * user:必须拥有记住我,才可以访问
 * perms:拥有对某个资源的权限才能访问
 * role:拥有某个角色权限才能访问
 */
Map<String, String> filterChainMap = new LinkedHashMap<>();
filterChainMap.put("/user/add","perms[user:add]");
filterChainMap.put("/user/update","authc");
bean.setFilterChainDefinitionMap(filterChainMap);
  • 通过过滤器链或者注解的方式,添加路径和权限的关系,

  • 在Realm类中进行授权操作

    //自定义Realm
    public class UserRealm extends AuthorizingRealm {
    
        //授权
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
            System.out.println("执行了授权方法");
            return null;
        }
    
  • 未通过授权的用户会进入指定的url页面

    bean.setUnauthorizedUrl("/unAuthorize");
    
  • 用户可以获取当前登录的用户信息

    SecurityUtils.getSubject().getPrincipal()
    

6、shiro和Thymeleaf整合

  • 导入依赖

    <!--        shiro整合thymeleaf-->
    <dependency>
        <groupId>com.github.theborakompanioni</groupId>
        <artifactId>thymeleaf-extras-shiro</artifactId>
        <version>2.0.0</version>
    </dependency>
    
  • 编写配置

    //整合thymeleaf--ShiroDialect
    //在配置文件中添加
    @Bean
    public ShiroDialect shiroDialect(){
        return new ShiroDialect();
    }
    
  • 前端测试

    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.thymeleaf.org/thymeleaf-extras-shiro">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <h1>首页</h1>
    <h3 th:text="${msg}"></h3>
    <h3 th:text="${user}"></h3>
    
    <!--根据当前登录的用户的权限,判断是否显示标签-->
    <a shiro:hasPermission="user:add" th:href="@{/user/add}">add</a>
    <a shiro:hasPermission="user:update" th:href="@{/user/update}">update</a>
    </body>
    </html>
    
    guest标签
      <shiro:guest>
      </shiro:guest>
      用户没有身份验证时显示相应信息,即游客访问信息。
    
    user标签
      <shiro:user>  
      </shiro:user>
      用户已经身份验证/记住我登录后显示相应的信息。
    
    authenticated标签
      <shiro:authenticated>  
      </shiro:authenticated>
      用户已经身份验证通过,即Subject.login登录成功,不是记住我登录的。
    
    notAuthenticated标签
      <shiro:notAuthenticated>
      
      </shiro:notAuthenticated>
      用户已经身份验证通过,即没有调用Subject.login进行登录,包括记住我自动登录的也属于未进行身份验证。
    
    principal标签
      <shiro: principal/>
      
      <shiro:principal property="username"/>
      相当于((User)Subject.getPrincipals()).getUsername()。
    
    lacksPermission标签
      <shiro:lacksPermission name="org:create">
     
      </shiro:lacksPermission>
      如果当前Subject没有权限将显示body体内容。
    
    hasRole标签
      <shiro:hasRole name="admin">  
      </shiro:hasRole>
      如果当前Subject有角色将显示body体内容。
    
    hasAnyRoles标签
      <shiro:hasAnyRoles name="admin,user">
       
      </shiro:hasAnyRoles>
      如果当前Subject有任意一个角色(或的关系)将显示body体内容。
    
    lacksRole标签
      <shiro:lacksRole name="abc">  
      </shiro:lacksRole>
      如果当前Subject没有角色将显示body体内容。
    
    hasPermission标签
      <shiro:hasPermission name="user:create">  
      </shiro:hasPermission>
      如果当前Subject有权限将显示body体内容
    
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值