springBoot整合shiro

1新建spring项目

导入依赖:`<?xml version="1.0" encoding="UTF-8"?>

4.0.0

org.springframework.boot
spring-boot-starter-parent
2.3.2.RELEASE


com.myshrio
demo
0.0.1-SNAPSHOT

<name>demo</name>
<description>Demo project for Spring Boot</description>

<properties>
    <java.version>1.8</java.version>
</properties>

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

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>


        <groupId>com.github.pagehelper</groupId>
        <artifactId>pagehelper-spring-boot-starter</artifactId>
        <version>1.2.10</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid-spring-boot-starter</artifactId>
        <version>1.1.10</version>
    </dependency>
    <dependency>
        <groupId>org.xmlunit</groupId>
        <artifactId>xmlunit-core</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
    </dependency>
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>1.3.2</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
        <scope>provided</scope>
    </dependency>


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


</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

2.目录结构

项目文件按结构

3.shiro的配置

1.自定义realm

package com.myshrio.shiro;
import com.myshrio.pojo.Permission;
import com.myshrio.pojo.Role;
import com.myshrio.pojo.User;
import com.myshrio.services.IUserSer;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
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.springframework.beans.factory.annotation.Autowired;

import java.security.Permissions;


public class CustomRealm extends AuthorizingRealm {

    @Autowired
    private IUserSer iUserSer;//用了ioc不用new

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //获取登录用户名
        String name = (String) principalCollection.getPrimaryPrincipal();
        //根据用户名去数据库查询用户信息
        User user = iUserSer.getByName(name);
        //添加角色和权限
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        for (Role role : user.getRoles()) {
            //添加角色
            simpleAuthorizationInfo.addRole(role.getRname());

        }
        //添加权限
        for (Permission permissions :user.getPermissions()) {
            simpleAuthorizationInfo.addStringPermission(permissions.getPname());
        }
        return simpleAuthorizationInfo;
    }
    //用户身份验证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //加这一步的目的是在Post请求的时候会先进认证,然后在到请求
        if (authenticationToken.getPrincipal() == null) {
            return null;
        }
        //获取用户信息
        String name = authenticationToken.getPrincipal().toString();//用户名
        User user =iUserSer.getByName(name);
        if (user == null) {
            //这里返回后会报出对应异常
            return null;
        } else {
            //这里验证authenticationToken和simpleAuthenticationInfo的信息
            SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(name, user.getUpass(), getName());
            return simpleAuthenticationInfo;
        }
    }
}

主要包含用户验证和,权限注入。
2.shiro的配置,我们使用Java代码配置

package com.myshrio.config;
import com.myshrio.shiro.CustomRealm;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;


    @Configuration
    public class ShiroConfig {

        @Bean
        @ConditionalOnMissingBean
        public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
            DefaultAdvisorAutoProxyCreator defaultAAP = new DefaultAdvisorAutoProxyCreator();
            defaultAAP.setProxyTargetClass(true);
            return defaultAAP;
        }

        //将自己的验证方式加入容器
        @Bean
        public CustomRealm myShiroRealm() {
            CustomRealm customRealm = new CustomRealm();
            return customRealm;
        }

        //权限管理,配置主要是Realm的管理认证
        @Bean
        public SecurityManager securityManager() {
            DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
            securityManager.setRealm(myShiroRealm());
            return securityManager;
        }

        //Filter工厂,设置对应的过滤条件和跳转条件
        @Bean
        public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
            ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
            shiroFilterFactoryBean.setSecurityManager(securityManager);
            Map<String, String> map = new HashMap<>();
            //登出
            map.put("/logout", "logout");
            //对所有用户认证
            map.put("/**", "authc");
            map.put("layui/** ","anon");
            map.put("/login.html","anon");//anon直接访问

            //登录
            shiroFilterFactoryBean.setLoginUrl("/login");
            //首页
            shiroFilterFactoryBean.setSuccessUrl("/index");
            //错误页面,认证不通过跳转
            shiroFilterFactoryBean.setUnauthorizedUrl("/error");
            shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
            return shiroFilterFactoryBean;
        }


        @Bean
        public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
            AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
            authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
            return authorizationAttributeSourceAdvisor;
        }
    }


其中关于过滤器配值大加可以参考过滤器配置参数

4.Mybatis

1.实体类
(权限类)

package com.myshrio.pojo;

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

import java.io.Serializable;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Permission implements Serializable {
    private int id;
    private String pname;
    private String description;
}

(用户类)

package com.myshrio.pojo;

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

import java.io.Serializable;
import java.util.List;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User implements Serializable {
    private int id;
    private String uname;
    private  String upass;
    private List<String> user_r;//用户所有角色
    private List<String> role_p;//用户所有权限
    private List<Role> roles;
    private List<Permission> permissions;

}

(角色类)

package com.myshrio.pojo;

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

import java.io.Serializable;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Role implements Serializable {
    private int id;
    private String rname;
    private String description;
}

2.Dao

package com.myshrio.dao;

import com.myshrio.pojo.User;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;
@Mapper
public interface IuserDao {
   User queById (int uid);
    User queByName(String name);
}

说明:本次只写了userDao,之前将permission和role写入user实体类中了(5表联合查询)。
(Mapper.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">

<!--
  mybatis的第二种事件方式
    xml + 接口的方式
      特点:xml中的namespace必须为接口的全路径
        xml中的每个节点的id必须为接口的方法名
-->
<mapper namespace="com.myshrio.dao.IuserDao">

  <select id="queById" resultMap="userMap">
    select * from  userinfo where id=#{uid}
  </select>
    <resultMap id="userMap" type="com.myshrio.pojo.User">
        <id column="id" property="id" />
        <collection property="user_r" column="id"  select="getrname"  />
        <collection property="role_p" column="id"  select="getpname"  />
    </resultMap>
    <select id="getrname" resultType="String">
        SELECT  r.rname
FROM userinfo u INNER JOIN user_r ur ON u.id = ur.uid
INNER JOIN role r ON r.id=ur.rid
INNER JOIN role_p rp ON ur.rid=rp.rid
WHERE u.id=#{uid} GROUP BY ur.rid/*单个用户的所有角色*/

    </select>
    <select id="getpname" resultType="String">
SELECT p.pname,p.description FROM userinfo u
INNER JOIN user_r ur ON u.id = ur.uid
INNER JOIN role r ON r.id=ur.rid
INNER JOIN role_p rp ON ur.rid=rp.rid
INNER JOIN permission p ON rp.pid=p.id
WHERE u.id=#{uid} GROUP BY rp.pid/*单个用户的所有权限*/

    </select>
<!--    ======================================================================================    -->
<select id="queByName" resultMap="userMap1">
    select * from  userinfo where uname =#{uname}
</select>
<resultMap id="userMap1" type="com.myshrio.pojo.User">
    <id column="id" property="id" />
    <result column="uname" property="uname" />
    <collection property="roles" column="uname"  select="getRole"  />
    <collection property="permissions" column="uname"  select="getPermission"  />
</resultMap>
    <select id="getRole" resultType="com.myshrio.pojo.Role">
     SELECT  r.rname,r.description
FROM userinfo u INNER JOIN user_r ur ON u.id = ur.uid
INNER JOIN role r ON r.id=ur.rid
INNER JOIN role_p rp ON ur.rid=rp.rid
WHERE u.uname =#{uname} GROUP BY ur.rid/*单个用户的所有角色*/
    </select>
    <select id="getPermission" resultType="com.myshrio.pojo.Permission">
SELECT p.pname,p.description FROM userinfo u
INNER JOIN user_r ur ON u.id = ur.uid
INNER JOIN role r ON r.id=ur.rid
INNER JOIN role_p rp ON ur.rid=rp.rid
INNER JOIN permission p ON rp.pid=p.id
WHERE u.uname =#{uname} GROUP BY rp.pid/*单个用户的所有权限*/
    </select>
</mapper>

5.controller

package com.myshrio.controller;

import com.myshrio.Util.Md5;
import com.myshrio.pojo.User;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.subject.Subject;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@RestController
    public class LoginController {

        @RequestMapping("/login")
        public String login(User user, HttpServletResponse response) throws IOException {
            if (user.getUpass()==null||user.getUname()==null){
                response.sendRedirect("login.html");//没有输入就到登录界面
            }
            //添加用户认证信息
            Subject subject = SecurityUtils.getSubject();
            UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(
                    user.getUname(),//输入的用户名
                    Md5.getPass(user.getUpass())//获得加密后的密码
            );
            try {
                //进行验证,这里可以捕获异常,然后返回对应信息
                subject.login(usernamePasswordToken);
//            subject.checkRole("admin");
//            subject.checkPermissions("query", "add");
            } catch (AuthenticationException e) {
                e.printStackTrace();
                return "账号或密码错误!";
            } catch (AuthorizationException e) {
                e.printStackTrace();
                return "没有权限";
            }
            return "login success";
        }

        //注解验角色和权限
        @RequiresRoles("admin")
        @RequiresPermissions("delete")
        @RequestMapping("/delete")
        public String delete() {
            return "删除权限!";
        }
    }



(这里只演示delete方法的访问,只有拥有delete权限才可以访问)

6.演示直接访问delete跳到登录

登录
(访问delete)
有delete权限
(换一个普通用户试试)
没有delete权限

代码下载代码

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值