Spring Boot整合Shiro

Spring Boot整合Shiro

关于Shiro的一些介绍就快速入门在另一篇博客中:传送门

首先话不多说创建一个Spring Boot工程

勾选模块如下:

Spring Boot整合Shiro

pom.xml文件

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.7.1</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.6</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.4</version>
        </dependency>
        <dependency>
            <groupId>com.github.theborakompanioni</groupId>
            <artifactId>thymeleaf-extras-shiro</artifactId>
            <version>2.0.0</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

搭建经典三层架构

dao层,service层,controller层,在mapper.xml中编写sql语句

讲道理这个还不熟悉建议缓缓,先熟悉了SpirngBoot再继续往下学习,建议熟练掌握SSM框架搭建,具体步骤参考这个:SSM

Spring Boot就是SSM的简化版,它的自动配置简直不要太香,熟练SSM轻松上手Spring Boot,另附一份Spring Boot整合Mybatis的步骤:Spring Boot & Mybatis

另外这个项目源代码已经上传到GitHub中;需要自行下载:传送门

整合Shiro

编写config

Spring Boot整合Shiro

package com.lzx.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;

/**
 * @Author 小先生
 * @Date 2021年05月04日14:43
 */
@Configuration
public class ShiroConfig {

    //ShiroFilterFactoryBean
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("defaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager){
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        //配置DefaultWebSecurityManager,设置安全管理器
        bean.setSecurityManager(defaultWebSecurityManager);

        //添加shiro的内置过滤器
        /*
        * anon:无需认证就可以访问呢
        * authc:必须认证才能访问
        * user:必须拥有 记住我 功能才能用(一般不用)
        * promise:拥有对某个资源的权限才能访问
        * role:拥有某个角色的权限才能访问
        * */

        Map<String, String> filterMap = new LinkedHashMap<>();
        //这个目录下的可以被所有人访问
//        filterMap.put("/user/add","anon");

        //认证才能访问
//        filterMap.put("/user/add","authc");
//        filterMap.put("/user/update","authc");
        //支持通配符  修改:放在授权的后面
//        filterMap.put("/user/*","authc");

        //授权  注意:授权要放在拦截的前面
        //[user:add]user用户,add权限才能访问
        filterMap.put("/user/add","perms[user:add]");
        filterMap.put("/user/update","perms[user:update]");

        filterMap.put("/user/*","authc");

        bean.setFilterChainDefinitionMap(filterMap);

        //设置登录请求
        bean.setLoginUrl("/toLogin");

        //设置未授权页面
        bean.setUnauthorizedUrl("/noauth");

        return bean;
    }


    //DefaultWebSecurityManager
    @Bean
    public DefaultWebSecurityManager defaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //关联UserRealm
        securityManager.setRealm(userRealm);
        return securityManager;
    }


    //创建realm对象,需要自定义类
    @Bean
    public UserRealm userRealm(){
        UserRealm userRealm = new UserRealm();
        return userRealm;
    }


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

}
package com.lzx.config;

import com.lzx.pojo.User;
import com.lzx.service.UserServiceImpl;
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;

/**
 * @Author 小先生
 * @Date 2021年05月04日14:45
 * 自定义的UserRealm
 */


public class UserRealm extends AuthorizingRealm {
    @Autowired
    UserServiceImpl userService;

    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("授权++++++++++");

        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

        //授权所有页面
//        info.addStringPermission("user:add");
//        info.addStringPermission("user:update");

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

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

        return info;
    }

    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.out.println("认证++++++++++");

        //用户名,密码;数据库取
//        String name="root";
//        String password="123456";



        UsernamePasswordToken userToken=(UsernamePasswordToken)token;

        //连接数据库
        User user = userService.queryUserByName(userToken.getUsername());
        if (user==null){
            //没有这个用户
            return null;
        }
        
        //登录成功九江user放到session中,交由前端进行判断
        Subject currentSubject = SecurityUtils.getSubject();
        Session session = currentSubject.getSession();
        session.setAttribute("loginUser",user);


        return new SimpleAuthenticationInfo(user,user.getPwd(),"");








//        //用户名认证
//        if (userToken.getUsername().equals(name)){
//            //抛出异常,vUnknownAccountException
//            return null;
//        }
//        //密码认证,shiro自己处理
//        return new SimpleAuthenticationInfo("",password,"");





    }
}

代码中基本都有注释
首先ShiroConfig里面注册了四个Bean

/**
 * @Author 小先生
 * @Date 2021年05月04日19:54
 */
public class Test {
    
        //ShiroFilterFactoryBean
        @Bean
        public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("defaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager){
            ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
            //配置DefaultWebSecurityManager,设置安全管理器
            bean.setSecurityManager(defaultWebSecurityManager);
            return bean;
        }

        //DefaultWebSecurityManager
        @Bean
        public DefaultWebSecurityManager defaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
            DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
            //关联UserRealm
            securityManager.setRealm(userRealm);
            return securityManager;
        }


        //创建realm对象,需要自定义类
        @Bean
        public UserRealm userRealm(){
            UserRealm userRealm = new UserRealm();
            return userRealm;
        }


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

    }

第四个是整合thymeleaf,其余三个层层引用

UserRealm继承了AuthorizingRealm

/**
 * @Author 小先生
 * @Date 2021年05月04日19:54
 */
public class Test extends AuthorizingRealm {

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        return null;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        return null;
    }
}
doGetAuthorizationInfo里面写的是授权的内容
doGetAuthenticationInfo里面写的是认证信息

另外这是需要和数据库连接,因此需要@Autowired service层

Shiro的大部分内容都在realm中书写。认证模块中可以通过连接数据库对用户名和密码进行验证,在controller层中书写对应代码跳转相应的界面

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

授权模块则可以对用户进行授权,Shiro拥有9个过滤器(参考Shiro快速入门

总结

这是对Shiro的初步使用,具体工作环境要远比这个复杂很多,慢慢积累吧!

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

上一篇:springboot 整合 shiro 安全框架


下一篇:教你 Shiro + SpringBoot 整合 JWT