springboot整合shiro小demo的笔记

SpringBoot整合Shiro

1.SpringBoot和Shiro的介绍

  • SpringBoot:

Spring的三大核心思想:IOC(控制反转),DI(依赖注入),AOP(面向切面编程)。

SpringBoot简化了基于Spring的应用开发,Spring需要大量的xml配置文件。

  • 关于Shiro:

这图比较经典吧,官方拿来的图,介绍了主要功能和辅助功能

在这里插入图片描述

Shiro主要面向Shiro开发团队所谓的“应用安全的四大基础” ——认证,授权,会话管理与密码加密:

  • 认证: 或“登录”,用以验证用户身份。
  • 授权: 访问控制, 比如决定谁可以访问某些资源。
  • 会话管理: 管理用户相关的session,即使是在非web或EJB应用中。
  • **加密:**可以非常方便地使用(各种)加密算法保证数据的安全。

Shiro还包含了一些其他功能以支持不同的应用环境,其中:

  • 对Web的支持: Shiro自带的支持Web的API可以很容易地保证web应用的安全。
  • 缓存:缓存在Apache Shiro的API中是“一等公民”,可以保证操作的快速高效。
  • 并发: Apache Shiro的并发功能支持开发多线程的应用。
  • 测试:对测试的支持可以帮助你编写单元测试与集成测试。
  • “以…(身份)运行”(Run As):允许一个用户使用另外某个用户的身份(执行操作),这个功能常用于管理场景中(比如“以管理员身份运行”)。
  • “自动登陆”(Remember Me):可以跨会话记住用户身份,只在某些特殊情况下才需要强制登录。

2.搭建SpringBoot环境

这个还用写吗…IDEA创建就完事儿了。

3.用thymeleaf作为模板

pom引入jar包

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

 	<properties>
        <java.version>1.8</java.version>
     <!-- 修改thymeleaf版本,为3.0以上,使得html语法宽松-->
        <thymeleaf.version>3.0.2.RELEASE</thymeleaf.version>
     <!--这个版本也要加上,否则报错视图解析器问题-->
        <thymeleaf-layout-dialect.version>2.0.4</thymeleaf-layout-dialect.version>
    </properties>

4.整合SpringBoot+Shiro

4.1过滤器设置url访问权限

导入jar

pom.xml

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

创建配置类:

package com.shiro.demo.shiro;

import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
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 {
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager){
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        //添加Shiro内置过滤器
        /**
         * Shiro内置过滤器,可以实现权限相关的拦截器
         *    常用的过滤器:
         *       anon: 无需认证(登录)可以访问
         *       authc: 必须认证才可以访问
         *       user: 如果使用rememberMe的功能可以直接访问
         *       perms: 该资源必须得到资源权限才可以访问
         *       role: 该资源必须得到角色权限才可以访问
         */
        Map <String,String> map = new LinkedHashMap();
        //登录页无需认证
        map.put("/login","anon");
        map.put("/testThymleaf","anon");
        //其他所有页面,都需要认真
        map.put("/*/**","authc");
        shiroFilterFactoryBean.setLoginUrl("/login");
        //设置规则
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        return shiroFilterFactoryBean;
    }

    @Bean(name="securityManager")
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
        DefaultWebSecurityManager dwsm = new DefaultWebSecurityManager();
        dwsm.setRealm(userRealm);
        return dwsm;
    }

    @Bean(name="userRealm")
    public UserRealm userRealm(){
        return new UserRealm();
    }
}

创建自定义Reaml

package com.shiro.demo.shiro;

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("执行认证逻辑");
        return null;
    }
}

controller类:

package com.shiro.demo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class UserController {

    @RequestMapping("/testThymleaf")
    public String TestThymleaf (Model model){
        model.addAttribute("name","陈亮");
        return "test";

    }

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

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

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

4.2编写认证逻辑

在自定义realm中编写逻辑

  @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("执行认证逻辑");
        String username = "chen";
        String password = "123";
        UsernamePasswordToken token = (UsernamePasswordToken)authenticationToken;
        //用户名不存在
        if( !token.getUsername().equals(username)){
            return null;
        }
        //用户名存在
        //校验密码
       return new SimpleAuthenticationInfo("",password,"");
    }

controller中调用login方法,并捕获相关异常

@RequestMapping("/login")
public String login(String userName,String password,Model model){
    //1.获取subject
    Subject subject = SecurityUtils.getSubject();
    //2.获取token
    UsernamePasswordToken token = new UsernamePasswordToken(userName,password);

    try {
        //3.执行登录方法,获取自定义Realm做认证
        subject.login(token);
        //没有异常,登录成功,重定向 跳到到指定页面
        return "redirect:/testThymleaf";
    }catch (UnknownAccountException e){//用户名不存在
        //捕获相对应的异常,给出不同信息
        model.addAttribute("msg","用户名不存在");
        return "login";
    }catch (IncorrectCredentialsException e){//密码错误
        model.addAttribute("msg","密码错误");
        return "login";

    }


}

4.3认证逻辑加入mybatis

导入相关依赖

<!-- SpringBoot的Mybatis启动器 -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.1.1</version>
        </dependency>

        <!-- druid连接池 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.0.9</version>
        </dependency>

        <!-- mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

配置application.properties

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.password=root
spring.datasource.username=root
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
mybatis.type-aliases-package=com.shiro.demo

创建mapper接口,和mapper.xml,service,service实现类~~~巴拉巴拉

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">
<!-- 该文件存放CRUD的sql语句 -->
<mapper namespace="com.shiro.demo.mapper.UserMapper">

    <select id="findByName" parameterType="string" resultType="user">
	SELECT 	id,
		NAME,
		PASSWORD
		FROM
		user where name = #{name}
	</select>

   <!-- <select id="findById" parameterType="int" resultType="user">
		SELECT 	id,
		NAME,
		PASSWORD,
		perms
		FROM
		user where id = #{value}
	</select>-->
</mapper>

UserMapper


package com.shiro.demo.mapper;

import com.shiro.demo.entity.User;

public interface UserMapper {
    public User findByName(String name);
}

注意:启动类加注解,扫描mapper接口,mapper接口上不需要家注解。

@SpringBootApplication
@MapperScan("com.shiro.demo.mapper")
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}

注意:用新版本IDEA开发时,如果你的mapper.xml放在java目录下,而不是在resources下,需要往pom.xml加入以下配置

<build>
	<resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.xml</include>
            </includes>
        </resource>
        <resource>
            <directory>src/main/resources</directory>
        </resource>
    </resources>
</build>

4.3过滤器加入权限过滤

在ShiroFilterFactoryBean过滤器中,设置url访问权限

//设置权限
map.put("/user/add","perms[user:add]");
//设置无权限提示页面
shiroFilterFactoryBean.setUnauthorizedUrl("/toUnauth");

controller:

@RequestMapping("/toUnauth")
public String toUnauth (){
    return "Unauth";
}

再加一个Unauth.html页面

4.4自定义Realm中加入授权

UserRealm:

public class UserRealm extends AuthorizingRealm {
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) 
    {
        System.out.println("执行授权逻辑");
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.addStringPermission("user:add");
        return info;
    }
}

和数据库关联进行授权:

UserReaml:

 @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("执行授权逻辑");
        //获取Subject
        Subject subject = SecurityUtils.getSubject();
        //获取Principal,认证的时候设置了Principal为User对象
        User user =(User) subject.getPrincipal();
        //创建授权类
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //查数据库,查权限,并授权
        info.addStringPermission(userService.findById(user.getId()).getPerms());
        return info;
    }

就是加了一个数据库查询而已,其他没啥不同的。写上Service、mapper接口、mapper.xml即可

4.5shiro权限标签

pom.xml导入依赖坐标:

<!-- thymeleaf整合shiro标签 -->
<dependency>
			<groupId>com.github.theborakompanioni</groupId>
			<artifactId>thymeleaf-extras-shiro</artifactId>
			<version>2.0.0</version>
</dependency>

在ShiroCongfig配置类注入一个bean

@Bean
    public ShiroDialect getShiroDialect(){
        return new ShiroDialect();
    }

修改HTML,加入shiro标签,

<div shiro:hasPermission="user:add">
    增加用户:<a href="/user/add">增加</a><br>
</div>
<div shiro:hasPermission="user:update">
    修改用户:<a href="/user/update">修改</a>
</div>
  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值