spring-boot整合shiro安全框架

spring-boot整合shiro安全框架

文章目录

20、Shiro安全框架

Shiro跟springSecurity一样都是安全框架。springSecurity用得多点,Shiro可定制强一点

Shiro的三个核心:

  • 1、用户:Subject
    2、管理所有用户:Shiro SecurityManager
  • 3、认证授权:Realm 【在该类里写认证授权交给2管理】

核心的操作:

  • SecurityUtils.getSubject() 【得到subject这个核心对象】
  • subject.getPrincipal() 【得到封装的用户信息】
  • UsernamePasswordToken(username, password) 【将表单提交的进行封装为一个token供认证使用】
  • subject.getSession() 【得到session】
  • currentuser.hasRole(“”) 【加权限】
  • currentuser.logout() 【当前用户退出】
  • currentuser.getPrincipal() 【得到当前用户信息】
  • subject.logout(); 【注销】

**环境:**导入相关依赖

<!--shiro 单独的导入这一个包即可-->
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring</artifactId>
    <version>1.2.4</version>
</dependency>
<!--thymeleaf-->
<dependency>
    <groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf-spring5</artifactId>
</dependency>
<dependency>
    <groupId>org.thymeleaf.extras</groupId>
    <artifactId>thymeleaf-extras-java8time</artifactId>
</dependency>
<!--thymeleaf  shiro-->
<dependency>
    <groupId>com.github.theborakompanioni</groupId>
    <artifactId>thymeleaf-extras-shiro</artifactId>
    <version>2.1.0</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>
<!--mysql  驱动-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>
<!--mybatis  整合数据库使用-->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.2.2</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>
<!--druid数据源-->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.0.16</version>
</dependency>

20.1 userRealm 【在后面的shiroConfig配置类中会用到】

package com.qiumin.springbootshiro.config;

import com.qiumin.springbootshiro.pojo.userPojo;
import com.qiumin.springbootshiro.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.springframework.beans.factory.annotation.Autowired;

public class userRealm extends AuthorizingRealm {
    @Autowired
    //数据库接口
    private userService userService;

    @Override
    //授权
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        System.out.println("执行了=>授权doGetAuthorizationInfo()");
        Subject subject = SecurityUtils.getSubject();
        //得到当前用户
        userPojo currentUser = (userPojo) subject.getPrincipal();
        //添加权限
        info.addStringPermission(currentUser.getPerms());
        return info;
    }

    @Override
    //认证
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.out.println("执行了=>认证doGetAuthenticationInfo()");
        //转换token
        UsernamePasswordToken usertoken = (UsernamePasswordToken)token;
        userPojo user = userService.selectUserByName(usertoken.getUsername());
        //判断是否登录时使用
        Subject subject = SecurityUtils.getSubject();
        Session session = subject.getSession();
        session.setAttribute("user",user);
        if(user!=null){
            //认证
            return new SimpleAuthenticationInfo(user,user.getPassword(),"");
        }else {
            return null;
        }
    }
}
  • 结合mybatis从数据库中取的用户、密码、权限。login.user

20.2 shiroConfig

package com.qiumin.springbootshiro.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{

    //ShiroFilterFactoryBean
    @Bean
    public  ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("SecurityManager") DefaultWebSecurityManager defaultWebSecurityManager){
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        //设置管理器
        bean.setSecurityManager(defaultWebSecurityManager);
        Map<String, String> filtermap = new LinkedHashMap<>();
        //必须先写授权再写下面的拦截
        filtermap.put("/qiu/update","perms[user:update]");
        filtermap.put("/qiu/add","perms[user:add]");
        filtermap.put("/qiu/delete","perms[user:delete]");
        //拦截
        filtermap.put("/qiu/*","authc");
        bean.setFilterChainDefinitionMap(filtermap);
        //设置登录页
        bean.setLoginUrl("/tologin");
        //设置未授权页面
        bean.setUnauthorizedUrl("/noauth");
        return bean;
    }

    //DefaultWebSecurityManager,管理realm
    @Bean(name = "SecurityManager")
    public DefaultWebSecurityManager getSecurityManager(@Qualifier("userRealm") userRealm userRealm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(userRealm);
        return securityManager;
    }

    //创建自定义的realm对象,继承AuthorizingRealm即可,交给AuthorizingRealm
    @Bean(name="userRealm")
    public userRealm userRealm(){
        return new userRealm();
    }

    //整合thymeleaf
    @Bean
    public ShiroDialect getShiroDialect(){
        return new ShiroDialect();
    }
}

注意点:

  • 所有的授权的操作必须在拦截之前。
  • 必须注入bean。
  • @Qualifier(“userRealm”)指定bean,里面默认为方法的驼峰命名,也可配合 @Bean(name=“userRealm”)一起使用。
  • userRealm DefaultWebSecurityManager ShiroFilterFactoryBean
  • 没有默认的请求,使用的请求在controller中必须要有对应的请求。
  • map.put()填值。

20.3 shiroController

package com.qiumin.springbootshiro.controller;

import com.qiumin.springbootshiro.pojo.userPojo;
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.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class shiroController {

    @RequestMapping("/login")
    public String login(String username, String password, Model model){
        //得到subject
        Subject subject = SecurityUtils.getSubject();
        //封装数据用户和密码
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        try {
            //登录进入认证授权,即userRealm中的认证授权方法
            subject.login(token);
            return "index";
        }catch (UnknownAccountException e){
            model.addAttribute("msg","用户名错误");
            return "login";
        }catch (IncorrectCredentialsException e){
            model.addAttribute("msg","密码错误");
            return "login";
        }

    }
	//注销请求
    @RequestMapping("/loginOut")
    private String loginOut(){
        Subject subject = SecurityUtils.getSubject();
        //注销后返回index
        subject.logout();
        return "index";
    }
    @RequestMapping("/noauth")
    public String toNoauth(){
        return "noauth";
    }

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

    @RequestMapping({"/","/index","/index.html"})
    public String toIndex(){
        return "index";
    }

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

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

    @RequestMapping("/qiu/delete")
    public String toDelete(){
        return "delete";
    }
}

注意点:

  • 请求需对应shiroConfig中的请求。 【例如:去登录页、注销等操作】
  • Subject subject = SecurityUtils.getSubject();
  • UsernamePasswordToken token = new UsernamePasswordToken(username, password);
  • subject.login(token); 当shiroConfig返回null时登录失败
  • subject.logout(); 注销

20.4 shiro整合thymeleaf

依赖

<!--thymeleaf  shiro-->
<dependency>
    <groupId>com.github.theborakompanioni</groupId>
    <artifactId>thymeleaf-extras-shiro</artifactId>
    <version>2.1.0</version>
</dependency>

导入命名空间

<html lang="en" xmlns:th="http://www.thymeleaf.org"
      xmlns:shiro="http://www.thymeleaf.org/thymeleaf-extras-shiro">


<!--session.user后台的数据不为空时显示注销按钮,表示已有用户登录 【subject的session】-->
<hr>
<div th:if="${session.user!=null}">
用户名:<span th:text="${session.user.getName()}"></span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    <a th:href="@{/loginOut}"><span>注销</span></a>
</div>
<hr>
<div th:if="${session.user==null}">
    <a th:href="@{/tologin}"><span>登录</span></a>
</div>
  • session.user后台的数据不为空时显示注销按钮,表示已有用户登录,否则显示登录按钮 【subject的session】

    add
  • shiro:hasPermission=“user:add” 用户有该权限显示

ref=“@{/tologin}”>登录

```

  • session.user后台的数据不为空时显示注销按钮,表示已有用户登录,否则显示登录按钮 【subject的session】

    add
  • shiro:hasPermission=“user:add” 用户有该权限显示

qiumin

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值