美文网首页
Shiro入门

Shiro入门

作者: 忒无聊了叭 | 来源:发表于2020-03-13 11:49 被阅读0次

Shiro

什么是Shiro?

Apache Shiro 是一个Java的安全框架。

关于shiro的相关概念:

  • subject:主体,可以是用户也可以是程序,主体要访问系统,系统需要对主体进行认证、授权。

  • securityManager:安全管理器,主体进行认证和授权都 是通过securityManager进行。

  • authenticator:认证器,主体进行认证最终通过authenticator进行的。

  • authorizer:授权器,主体进行授权最终通过authorizer进行的。

  • sessionManager:web应用中一般是用web容器对session进行管理,shiro也提供一套session管理的方式。

  • SessionDao: 通过SessionDao管理session数据,针对个性化的session数据存储需要使用sessionDao。

  • cache Manager:缓存管理器,主要对session和授权数据进行缓存,比如将授权数据通过cacheManager进行缓存管理,和ehcache整合对缓存数据进行管理。

  • realm:域,领域,相当于数据源,通过realm存取认证、授权相关数据。

三大对象

Subject 用户

SecurityManger 管理

Realm 连接数据

shiro启动器

        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.4.1</version>
        </dependency>

shiro整合springBoot2与mybatis入门案例

实现登录拦截,认证,授权,整合thymeleaf

部分依赖

        <!--连接数据库-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.18</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.21</version>
        </dependency>
        <!--集成mybatis-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.1</version>
        </dependency>
        <!--lombok插件-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
        </dependency>

数据库

1584028525939.png

以下是主要代码

实体类User
package com.shiro.shiro.Pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
    import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {

    private int id;
    private String name;
    private String pwd;
    private String perms;
}

自定义UserRealm

package com.shiro.shiro.Config;

import com.shiro.shiro.Pojo.User;
import com.shiro.shiro.Service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.apache.tomcat.util.descriptor.web.FilterMap;
import org.springframework.beans.factory.annotation.Autowired;

public class UserRealm extends AuthorizingRealm {

    @Autowired
    UserService userService;

    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("执行了授权=》doGetAuthorizationInfo");

        //授权
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//        info.addStringPermission("user:add");
        //从认证中拿到当前用户的对象,相当于间接从数据库中取出来的
        Subject subject = SecurityUtils.getSubject();
        User user = (User) subject.getPrincipal();  //拿到认证中存入的user对象

        //根据数据库表中的perms确定该用户的权限
        info.addStringPermission(user.getPerms());
        return info;
    }

    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.out.println("执行了认证=》doGetAuthenticationInfo");
        //取出用户信息
        UsernamePasswordToken userToken = (UsernamePasswordToken) token;
        User user = userService.selectUserByName(userToken.getUsername());
        if (user==null){
            return null;        //这里会自动的抛出控制层中那个用户名错误异常
        }
        //将当前登录的用户信息存放在对象的session中(这里的作用是为了让前台是否显示登录)
        Subject currentSubject = SecurityUtils.getSubject();
        Session session = currentSubject.getSession();
        session.setAttribute("loginUser",user);

        //可以进行加密,两种方式md5和md5盐值加密,md5是可逆的,第二种不可逆更安全
        //将密码交给shiro进行验证就可以
        return new SimpleAuthenticationInfo(user,user.getPwd(),"");
    }
}

shiroConfig

package com.shiro.shiro.Config;
import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;
import java.util.Map;

@Configuration
public class ShiroConfig {

    //shiro的三大核心对象,依次从下往上写
    //shiroFilterFactory
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager){
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        //设置安全管理器
        bean.setSecurityManager(defaultWebSecurityManager);
        //添加shiro的内置过滤器
        /*
        anno:无需认证就可以实现
        authc:必须认证才可以实现
        user:必须拥有记住我功能才能用
        perms:拥有某个资源的权限才能访问
        role:拥有某个角色权限才能访问
         */
        Map<String, String> filterMap = new LinkedHashMap<>();
        //添加和修改必须认证才可以实现
        filterMap.put("/user/add","authc");
        filterMap.put("/user/update","authc");
        //授权管理,正常情况下,如果没有跟后面的字符串,会告诉你没有权限
        filterMap.put("/user/add","perms[user:add]");
        filterMap.put("/user/update","perms[user:update]");
        //如果没有权限,设置登录请求
        bean.setLoginUrl("/toLogin");
        //未授权请求跳转
        bean.setUnauthorizedUrl("/noauth");
        bean.setFilterChainDefinitionMap(filterMap);
        return bean;
    }

    //DafaultWebSecurityManger:第二步
    @Bean(name = "securityManager")
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //关联realm
        securityManager.setRealm(userRealm);
        return securityManager;
    }

    //创建realm对象,需要自定义类:第一步
    @Bean()
    public UserRealm userRealm(){
        return new UserRealm();
    }

    //整合ShiroDialect:用来整合thymeleaf与shiro
    @Bean
    public ShiroDialect getShiroDialect(){
        return new ShiroDialect();
    }
}

Controller

package com.shiro.shiro.Controller;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class MyController {

    @RequestMapping({"/","index"})
    public String toIndex(Model model){
        model.addAttribute("msg","Hello World!");
        return "index";
    }

    @RequestMapping("/user/add")
    public String add(){
        return "user/add";
    }

    @RequestMapping("/user/update")
    public String update(){
        return "user/update";
    }

    @RequestMapping("/toLogin")
    public String toLogin(){
        return "login";
    }

    @RequestMapping("/login")
    public String login(String userName,String password,Model model){
        //获取当前用户
        Subject subject = SecurityUtils.getSubject();
        //封装用户的登录数据
        UsernamePasswordToken token = new UsernamePasswordToken(userName,password);

        try {
            subject.login(token);
            return "index";
        }catch (UnknownAccountException e){
            model.addAttribute("msg","用户名不存在或错误!");
            return "login";
        }catch (IncorrectCredentialsException e){
            model.addAttribute("msg","密码错误!");
            return "login";
        }
    }

    @RequestMapping("/noauth")
    @ResponseBody
    public String unauthorized(){
        return "该页面您没有权限可以访问!";
    }
}

首页index

<!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>
</head>
<body>
<h2>首页</h2>
    <!--判断这个用户是否已经登录-->
<div th:if="${session.loginUser==null}">
    <a th:href="@{/toLogin}">登录</a>
</div>
<p th:text="${msg}"></p>

<hr>
    <!--如果含由对应权限的字符串,就显示那个功能-->
<div shiro:hasPermission="user:add">
    <a th:href="@{/user/add}">添加</a>
</div>
<div shiro:hasPermission="user:update">
    <a th:href="@{/user/update}">修改</a>
</div>
</body>
</html>

login

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>登录</title>
</head>
<body>
<p th:text="${msg}" style="color: red"></p>
<form th:action="@{/login}">
    <h3>请先进行登录</h3>
    <p>用户名:<input type="text" name="userName"></p>
    <p>用户名:<input type="password" name="password"></p>
    <p>用户名:<input type="submit"></p>
</form>
</body>
</html>

入门案例gitee仓库
https://gitee.com/shao_zhao_wei/shiro

相关文章

  • Java框架--Shiro入门

    目录 shiro 是什么? shiro 可以解决什么问题? shiro 名词解释&认证流程 shiro 快速入门 ...

  • Shiro官网学习记录

    ​ 官网文档很适合入门,搬运一波入门教程 ​ Shiro框架学习 ​ shiro.ini ​ Quic...

  • Shiro学习笔记

    一 、Shiro入门 1.简介 Apache Shiro 是 Java 的一个安全(权限)框架。 Shiro 可以...

  • shiro1.0_目录

    shiro1.5.3官网地址 大神翻译 目录列表 1. shiro1.1_介绍 2. shiro1.2_入门 3....

  • Shiro入门

    Shiro来控制权限 首先我们需要来创建一个RBAC模型(图片网上找的) 数据库模型建好以后便可进行配置:我们在项...

  • Shiro入门

    Shiro 什么是Shiro? Apache Shiro 是一个Java的安全框架。 关于shiro的相关概念: ...

  • shiro入门

    ApacheShiro是一个功能强大且易于使用的Java安全框架,提供了认证,授权,加密,和会话管理。 Shiro...

  • Shiro入门

    1、项目结构 2、pom.xml 3、读取静态文件的Realm方式 3.1、resources/shiro.ini...

  • SecurityUtils,SecurityManager和Su

    写shiro的入门程序的时候有 SecurityUtils.setSecurityManager(security...

  • 三、入门代码

    快速入门代码https://github.com/apache/shiro/tree/master/samples...

网友评论

      本文标题:Shiro入门

      本文链接:https://www.haomeiwen.com/subject/kluqshtx.html