SpringBoot整合Shiro

Shiro的基本概念
三个核心组件:Subject, SecurityManager 和 Realms.
Subject:即“当前操作用户”。但是,在Shiro中,Subject这一概念并不仅仅指人,也可以是第三方进程、后台帐户(Daemon Account)或其他类似事物。它仅仅意味着“当前跟软件交互的东西”。
Subject代表了当前用户的安全操作,SecurityManager则管理所有用户的安全操作。
SecurityManager:它是Shiro框架的核心,典型的Facade模式,Shiro通过SecurityManager来管理内部组件实例,并通过它来提供安全管理的各种服务。
Realm: Realm充当了Shiro与应用安全数据间的“桥梁”或者“连接器”。也就是说,当对用户执行认证(登录)和授权(访问控制)验证时,Shiro会从应用配置的Realm中查找用户及其权限信息。
从这个意义上讲,Realm实质上是一个安全相关的DAO:它封装了数据源的连接细节,并在需要时将相关数据提供给Shiro。当配置Shiro时,你必须至少指定一个Realm,用于认证和(或)授权。配置多个Realm是可以的,但是至少需要一个。
Shiro内置了可以连接大量安全数据源(又名目录)的Realm,如LDAP、关系数据库(JDBC)、类似INI的文本配置资源以及属性文件等。如果系统默认的Realm不能满足需求,你还可以插入代表自定义数据源的自己的Realm实现。

Shiro的三大核心API
1、subject:用户主体
2、SecurityManager:安全管理器(管理所有的subject,关联Realm)
3、Realm:连接数据的桥梁(连接数据库)

Maven导包

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

认证和授权

package com.Configation;

import com.Mapper.UserAccount;
import com.Service.UserAccountService;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

public class MyRealm extends AuthorizingRealm {
    @Autowired
    UserAccountService service;
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //获取登录用户名
        String name = (String) principalCollection.getPrimaryPrincipal();
        //查询用户名称
        User user = loginService.getUserByName(name);
        //添加角色和权限
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        for (Role role : user.getRoles()) {
            //添加角色
            simpleAuthorizationInfo.addRole(role.getRoleName());
            //添加权限
            for (Permissions permissions : role.getPermissions()) {
                simpleAuthorizationInfo.addStringPermission(permissions.getPermissionsName());
            }
        }
        return simpleAuthorizationInfo;
     
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("-------执行了--------");
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        UserAccount userAccount = service.GetUser(token.getUsername());
        if(userAccount != null){
            //若密码不正确则返回IncorrectCredentialsException异常
            return new SimpleAuthenticationInfo(userAccount,userAccount.getPassword(), getName());
        }
        //若用户名不存在则返回UnknownAccountException异常
        return null;
    }
}

ShiroConfig配置

package com.Configation;

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;

@Configuration
public class ShiroConfig {
    /**
     * 创建ShiroFilterFactoryBean
     */
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        //设置安全管理器
        shiroFilterFactoryBean.setSecurityManager(securityManager);

        //添加Shiro内置过滤器
        /**
         * Shiro内置过滤器,可以实现权限相关的拦截器
         * 常用的有:
         * 	anon:无需认证就能访问
         authc:必须认证才能访问 filterMap.put("/test", "anon");
         //        filterMap.put("/login", "anon");
         //        filterMap.put("/*", "authc");
         user:必须拥有 “记住我” 功能才能使用
         perms:拥有对某个资源的权限才能访问
         role: 拥有对某个角色权限才能访问
         */
        LinkedHashMap<String, String> filterMap = new LinkedHashMap<String,String>();
//		filterMap.put("/add", "authc");
//		filterMap.put("/update", "authc");
        //放行的用户放在前面
//
        //修改登录页面
        shiroFilterFactoryBean.setLoginUrl("/toLogin");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
        return shiroFilterFactoryBean;
    }

    /**
     * 创建DefaultWebSecurityManager
     */
    @Bean(name="securityManager")
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("MyRealm") MyRealm myRealm) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //关联Realm
        securityManager.setRealm(myRealm);
        return securityManager;
    }

    /**
     * 创建Realm对象(第一步)
     * @Bean 将方法返回的对象放入Sprin环境进行管理
     */
    @Bean(name="MyRealm")
    public MyRealm myRealm() {
        return new MyRealm();
    }


} 

LoginController

因为我这个是前后的分离的项目,所有和别的博主写法不一样!

 @PostMapping("/Login")
    public Result Login(@RequestBody Map<String,String> map){
        /**
         * 使用shiro编写认证操作
         */
        //获取subject
        Subject subject = SecurityUtils.getSubject();
        //封装用户数据
        UsernamePasswordToken token = new UsernamePasswordToken(map.get("Username"), map.get("Password"));
        //执行登录方法
        try {
            subject.login(token);
            //如果没有异常,登录成功
            return new Result(200,"登录成功!");
        }catch (UnknownAccountException e){
            //如果有异常,登录失败,如果发生UnknownAccountException,说明用户名不存在
            return new Result(400,"用户名不存在");
        }catch (IncorrectCredentialsException e){
            //如果发生IncorrectCredentialsException,说明密码错误
            return new Result(400,"密码错误");
        }}
上一篇:Duplicate class xx.xx.XX found in modules xx1-1.0 (xx.xx:mm1:1.0),... and xx2-1.0 (xx.xx:mm2:1.0)


下一篇:shiro(四)项目开发中的配置、