springboot项目中使用shiro实现用户登录以及权限的验证

更加高级的验证用户权限:用户表、角色表、权限表。多表联合:https://blog.csdn.net/weixin_43304253/article/details/121124431
建立spring boot项目。
目录结构这个样子的
springboot项目中使用shiro实现用户登录以及权限的验证_第1张图片

项目的jar包依赖

 
        
        
            org.apache.shiro
            shiro-spring
            1.4.1
        

        
            com.github.theborakompanioni
            thymeleaf-extras-shiro
            2.0.0
        


        
        
        
            org.mybatis.spring.boot
            mybatis-spring-boot-starter
            2.1.0
        


        
            org.springframework.boot
            spring-boot-starter-web
        
        
        
            org.springframework.boot
            spring-boot-starter-jdbc
        

        
        
            mysql
            mysql-connector-java
            runtime
        

        
            com.alibaba
            druid
            1.1.6
        

        

        
        
            org.thymeleaf
            thymeleaf-spring5
        

        
            org.thymeleaf.extras
            thymeleaf-extras-java8time
        


        
            org.springframework.boot
            spring-boot-starter-test
            test
        

    

配置文件.properties

#整合mybatis
mybatis.type-aliases-package=com.zheng.pojo
mybatis.mapper-locations=classpath:mybatis/mapper/*.xml

连接数据库的yml文件


thymeleaf:
  prefix: classpath:/templates/  #prefix:指定模板所在的目录
  check-template-location: true  #check-tempate-location: 检查模板路径是否存在
  cache: false  #cache: 是否缓存,开发模式下设置为false,避免改了模板还要重启服务器,线上设置为true,可以提高性能。
  suffix: .html
  encoding: UTF-8
  content-type: text/html
  mode: HTML5



spring:
  datasource:
    username: root
    password: root
    url: jdbc:mysql://localhost:3306/managebook?allowMultiQueries=true&characterEncoding=UTF-8&characterSetResults=UTF-8&zeroDateTimeBehavior=convertToNull&useSSL=false
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource

    #spring boot 默认是不注入这些属性的,需要自己绑定
    #druid 数据源专有配置
    initiaSize: 5
    minIdle: 5
    maxActive: 20
    maxWait: 60000
    timeBetweenEvictionRunsmMillis: 60000
    minEvictableIdleTimeMillis: 300000
    validationQuery: SELECT 1 FROM DUAL
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    poolPreparedStatements: true

    filters: stat,wall,log4j
    maxPoolPrepareStatementPerConnectionSize: 20
    useGlobalDataSourceStat: true
    connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500


实体类

package com.zheng.pojo;

public class User {
    private String name;
    private String password;
    private String perm;

    public User() {

    }

    public User(String name, String password, String perm) {
        this.name = name;
        this.password = password;
        this.perm = perm;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

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

    public String getPerm() {
        return perm;
    }

    public void setPerm(String perm) {
        this.perm = perm;
    }
}

controller层

package com.zheng.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.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller

public class UserController {


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

    //跳转到未授权界面
    @RequestMapping("/ungrant")
    public String ungrant(){
        return "ungrant";
    }

    //跳转到怎加
    @RequestMapping("/admin/add")
    public String addpPage(){
        return "add";
    }

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

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

    



    @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";

        }


    }
}

service层

package com.zheng.service;

import com.zheng.pojo.User;

public interface UserService {
    //查询用户信息
    User login(String name);

}

serviceImpl层

package com.zheng.service.impl;

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

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    UserMapper userMapper;
    @Override
    public User login(String name) {
        return userMapper.login(name);
    }
}

mapper层

package com.zheng.mapper;

import com.zheng.pojo.User;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;

@Mapper    //这个注解表示这个是mybatis的mapeper
@Repository
public interface UserMapper {

    //查询用户信息
    User login(String name);



}

mapper文件层





    
    




前端页面简单的表示(这里制作简单的演示、前端框架也很多)
index.html




    
    首页



add    update



login.html




    
    登录



用户名:
密码:

ungrant.html未授权页面




    
    未授权页面


未授权页面


add.html




    
    增加页面


add


update.html




    
    修改页面


update


效果展示

1、第一种情况、还未登录直接访问首页中的链接
springboot项目中使用shiro实现用户登录以及权限的验证_第2张图片
springboot项目中使用shiro实现用户登录以及权限的验证_第3张图片
2、第二种情况、登录后访问首页中的链接

首先看一下数据库中数据、更加具有说服力
springboot项目中使用shiro实现用户登录以及权限的验证_第4张图片

springboot项目中使用shiro实现用户登录以及权限的验证_第5张图片
springboot项目中使用shiro实现用户登录以及权限的验证_第6张图片
在首页中测试add
springboot项目中使用shiro实现用户登录以及权限的验证_第7张图片
在首页中测试update
springboot项目中使用shiro实现用户登录以及权限的验证_第8张图片

解析说明
过滤器的代码

package com.zheng.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);
        //添加shiro的内置过滤器
        /**
         *  anon:无需认证就可访问  *  authc:必须认证才能访问*  User:必须拥有 记住我 功能才能用
         *  perms:拥有对某个资源的权限才能访问*  role:拥有某个角色权限才能访问
         */
        Map filterMap = new LinkedHashMap<>();
        //授权,正常的情况下,没有授权会跳转到未授权页面
//        filterMap.put("/admin/*","authc");//admin请求下的都需要认证
        filterMap.put("/admin/add", "perms[user:add]");
        filterMap.put("/admin/update", "perms[user:update]");

        bean.setFilterChainDefinitionMap(filterMap);
        //如果没有认证、设置登录的请求
        bean.setLoginUrl("/toLogin");
        //如果没有授权,跳转到未收取页面
        bean.setUnauthorizedUrl("/ungrant");
        return bean;

    }

    //DefaultWebSecurityManager
    @Bean(name = "securitymanager")
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm) {
        DefaultWebSecurityManager securitymanager = new DefaultWebSecurityManager();
        //关联UserRealm
        securitymanager.setRealm(userRealm);
        return securitymanager;


    }

    //创建realm对象,需要自定义安装
    @Bean
    public UserRealm userRealm() {

        return new UserRealm();
    }


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


}

授权和认证

package com.zheng.config;

import com.zheng.pojo.User;
import com.zheng.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.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;


//自定义的UserRealm

public class UserRealm extends AuthorizingRealm {

    @Autowired
    UserService userService;

    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {

        System.out.println("执行了授权");
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//        info.addStringPermission("user:update");

        //拿到当前的登录对象
        Subject subject = SecurityUtils.getSubject();
        User user = (User)subject.getPrincipal();

        //设置当前用户的权限
        info.addStringPermission(user.getPerm());

        return info;

    }

    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        // 第一种方式
        // 获取用户输入的账号和密码(一般只需要获取账号就可以)
        System.out.println("执行了认证");
        UsernamePasswordToken userToken = (UsernamePasswordToken) token;
        //连接真实的数据库

        User user = userService.login(userToken.getUsername());

        //1、思路:在用户表中新增加一个权限字段、然后再次查询数据库获得该用户所具有的权限(该权限为要给集合??????
        if(user == null){
            //没有这个人
            return null;
        }
        //密码认证
        return  new SimpleAuthenticationInfo(user,user.getPassword(),"");

    }
}

关键解说:
springboot项目中使用shiro实现用户登录以及权限的验证_第9张图片

你可能感兴趣的:(spring,boot,java,spring)