Springboot集成shiro

Springboot集成shiro

项目目录

在这里插入图片描述

1,shiro简介:

subject:用户主体

security:安全管理器

Realm:shiro连接数据的桥梁

2,springboot集shiro

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

3,自定义realm类

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

public class UserRealm extends AuthorizingRealm {

    /*
    * 执行授权逻辑
    * */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("执行授权逻辑");
        return null;
    }

    /*
    * 执行认证逻辑
    * */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("执行认证逻辑");
       
        String name = "wangxin";
        String password = "123456";

        UsernamePasswordToken token = (UsernamePasswordToken)authenticationToken;
        //1.判断用户名
        if(!token.getUsername().equals(name)){
            return null;//shiro低层会抛出UnknownAccountException异常
        }
        //2.判断密码
        return new SimpleAuthenticationInfo("",password,"");
    }
}

4,编写shiro配置类

import org.apache.shiro.mgt.DefaultSecurityManager;
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;

@Configuration
public class shiroConfig {
    /*
    * 创建ShiroFilterFactoryBean
    *
    */
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager")DefaultWebSecurityManager securityManager){
        ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
        //设置安全管理器
        factoryBean.setSecurityManager(securityManager);
         /*
        * shiro内置过滤器,
        * 常用过滤器
        * anon:无需认证(登录),可以访问
        * authc:必须认证才可以访问
        * user:如果使用rememeber me就可以直接访问
        * perms:有资源权限才可以访问
        * role:必须得到角色权限才可以访问
        * */
        Map<String,String> filter = new LinkedHashMap<>();
        filter.put("/user/add","authc");
        filter.put("/user/update","authc");
        //默认跳转login.jsp
        //修改跳转的页面
        shiroFilterFactoryBean.setLoginUrl("/user/tologin");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filter);
        return factoryBean;
    }
    /*
    * 创建DefaultWebSecurityManager
    * */
    @Bean(name = "securityManager")
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm")UserRealm userRealm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(userRealm);
        return securityManager;
    }
    /*
    *
    * 创建realm
    * */
    @Bean(name ="userRealm")
    public UserRealm getrealm(){
        return new UserRealm();
    }
}

5,整合Mybatis实现登录认证

(1)导入依赖

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.6</version>
</dependency>

<dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.1.19</version>
</dependency>

<dependency>
       <groupId>org.mybatis.spring.boot</groupId>
       <artifactId>mybatis-spring-boot-starter</artifactId>
       <version>1.1.1</version>
</dependency>

(2)配置application.yml

datasource:
  driver-class-name: com.mysql.jdbc.Driver
  username: root
  password: root
  url: jdbc:mysql://localhost:3306/db_cqb?serverTimezone=UTC
  type: com.alibaba.druid.pool.DruidDataSource
  initialSize: 5
  minIdle: 5
  maxActive: 20
  maxWait: 60000
  timeBetweenEvictionRunsMillis: 60000
  minEvictableIdleTimeMillis: 300000
  validationQuery: SELECT 1 FROM DUAL
  testWhileIdle: true
  testOnBorrow: false
  testOnReturn: false
  poolPreparedStatements: true
  maxPoolPreparedStatementPerConnectionSize: 20
  filters: stat,wall
  connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000

mybatis:
  type-aliases-package: com.godx.entity

(3) 编写user实体类

public class User {
    private Integer id;
    private String username;
    private String password;
    private String role;
    public User(){}

    public User(Integer id, String username, String password, String role) {
        this.id = id;
        this.username = username;
        this.password = password;
        this.role = role;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getRole() {
        return role;
    }

    public void setRole(String role) {
        this.role = role;
    }
}

(4) 编写UserMapper接口

public interface UserMapper {
    public User findByName(String username);
    public User findById(Integer id);
}

(5)编写UserMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.godx.mapper.UserMapper">
    <select id="findByName" resultType="user">
            select * from user where username = #{username};
    </select>
    <select id="findById" resultType="user">
            select * from user where id = #{id};
    </select>
</mapper>


(6)编写UserService接口和UserServiceImpl实现类

import com.godx.entity.User;

public interface UserService {
    public User findByName(String username);
    public User findById(Integer id);
}


import com.godx.entity.User;
import com.godx.mapper.UserMapper;
import com.godx.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;
    @Override
    public User findByName(String username) {
       User user = userMapper.findByName(username);
       return user;
    }
}

(7)编写UserController类

import com.godx.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
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.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.sql.SQLOutput;

@Controller
@RequestMapping("/user")
@Api(tags = "user")
public class UserController {
    @Autowired
    private UserService userService;

    @RequestMapping("/hello")
    public String hello(){
        return "test";
    }

    @RequestMapping("/add")
    public String add(){
        return "addUser";
    }
    @RequestMapping("/tologin")
    public String tologin(){
        return "login";
    }
    @RequestMapping("/update")
    public String upate(){
        return "updateUser";
    }

    @RequestMapping("/login")
    public String login(String username, String password, Model model){
        /*
        * 使用shiro编写用户登录*/
        //1.获取Subject对象
        Subject subject = SecurityUtils.getSubject();
        //2,封装用户数据
        UsernamePasswordToken token = new UsernamePasswordToken(username,password);
        //3,执行登录
        try {
            subject.login(token);
            return "test";
        }catch (UnknownAccountException e){
            model.addAttribute("msg","用户名不存在");
            return "login";
        }catch (IncorrectCredentialsException e){
            model.addAttribute("msg","密码错误");
            return "login";
        }
    }
    /*@ApiOperation(value = "好人",notes = "hr")
    @RequestMapping("/good")
    public String good(){
        return "You are a good man!";
    }*/

}

6,修改UserRealm

 @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("执行认证逻辑");
       /* String name = "wangxin";
        String password = "123456";*/
        UsernamePasswordToken token = (UsernamePasswordToken)authenticationToken;
        User user = userService.findByName(token.getUsername());
        System.out.println(user.getUsername()+"/"+user.getPassword());
        //1.判断用户名
        if(user==null){
            return null;//shiro低层会抛出UnknownAccountException异常
        }
        //2.判断密码
        return new SimpleAuthenticationInfo(user,user.getPassword(),"");
    }

7,Html页面

(1)login.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h3 style="color: red" th:text="${msg}"></h3>
    <form method="post" action="/user/login">
        <div>
            用户名:<input type="text" name="username">
        </div>
        <div>
            密码:<input type="password" name="password">
        </div>
        <div>
            <input type="submit" value="登录">
        </div>
    </form>
</body>
</html>

其他页面简单不放出来了

8,SpringBoot整合Shiro实现用户授权

(1) 使用shiro内置过滤器进行拦截

将原来的ShiroConfig修改成以下

 @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager")DefaultWebSecurityManager securityManager){
        ShiroFilterFactoryBean  shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        //设置安全管理器
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        /*
        * shiro内置过滤器,
        * 常用过滤器
        * anon:无需认证(登录),可以访问
        * authc:必须认证才可以访问
        * user:如果使用rememeber me就可以直接访问
        * perms:有资源权限才可以访问
        * role:必须得到角色权限才可以访问
        * */
        Map<String,String> filter = new LinkedHashMap<>();
        filter.put("/user/add","authc");
        filter.put("/user/update","authc");
        filter.put("/user/hello","authc");

        //授权过滤器
        //注意:当前授权拦截后,shiro会自动跳转到未授权的页面
        //filter.put("/user/add","perms[user:add]");
        
       	//连接数据库动态查询
        filter.put("/user/add","perms[admin]");
        filter.put("/user/update","perms[test]");
        //设置权限不够跳转的页面
        shiroFilterFactoryBean.setUnauthorizedUrl("/user/noAuth");
        //默认跳转login.jsp
        //修改跳转的页面
        shiroFilterFactoryBean.setLoginUrl("/user/tologin");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filter);
        return shiroFilterFactoryBean;
    }

(2)关联数据库动态授权

修改UserRealm

	@Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("执行授权逻辑");
        //给资源进行授权:
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        //获取当前的用户
        Subject subject = SecurityUtils.getSubject();
        User user  = (User) subject.getPrincipal();
        User dbuser = userService.findById(user.getId());
        simpleAuthorizationInfo.addStringPermission(dbuser.getRole());
        return simpleAuthorizationInfo;
    }

9,thymeleaf整合shiro标签

(1)导入依赖

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

<!-- https://mvnrepository.com/artifact/com.github.theborakompanioni/thymeleaf-extras-shiro -->
<dependency>
    <groupId>com.github.theborakompanioni</groupId>
    <artifactId>thymeleaf-extras-shiro</artifactId>
    <version>2.0.0</version>
</dependency>

(2)配置ShiroDialect

在ShiroConfig配置类中加入以下代码

 /*
    *
    * 配置ShiroDialect用于thymeleaf和shiro的标签*/
    @Bean
    public ShiroDialect getShiroDialect(){
        return new ShiroDialect();
    }

(3)test.html页面修改

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div shiro:hasPermission="admin">
<a href="/user/add">用户添加</a>
</div>
<div shiro:hasPermission="test">
<a href="/user/update">用户修改</a>
</div>
</body>
</html>

10,安全退出

(1)UserController添加logout方法

@RequestMapping("/logout")
public String logout(){
    Subject subject = SecurityUtils.getSubject();
    subject.logout();
    return "login";
}

项目源码

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值