Shiro安全框架

发布时间 2023-03-25 13:22:04作者: 读春秋的关二爷

pom.xml

        <!--shiro整合包-->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.10.1</version>
        </dependency>
        <!--thymeleaf-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
            <version>2.7.3</version>
        </dependency>

        <!--整合thymeleaf、shiro-->
        <dependency>
            <groupId>com.github.theborakompanioni</groupId>
            <artifactId>thymeleaf-extras-shiro</artifactId>
            <version>2.1.0</version>
        </dependency>

ShiroConfig

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 shiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager){
        ShiroFilterFactoryBean filterFactoryBean = new ShiroFilterFactoryBean();
        //添加安全管理器
        filterFactoryBean.setSecurityManager(defaultWebSecurityManager);
        //添加shiro的内置过滤器
        /*
        *
        * anon:无需认证就可以访问
        * authc:必须认证了才能访问
        * user:必须拥有 记住我 功能才能使用
        * perms:拥有对某个资源的权限才能访问
        * role:拥有某个角色的权限才能访问
        *
        * */
        /*
        filterMap.put("/user/add","authc");
        filterMap.put("/user/update","authc");
        * */
        //拦截
        Map<String, String> filterMap = new LinkedHashMap<>();
//        filterMap.put("/user/*","authc");
        //授权,正常情况下,没有授权会跳转到未授权页面
        filterMap.put("/user/add","perms[user:add]");
        filterMap.put("/user/update","perms[user:update]");
        filterFactoryBean.setFilterChainDefinitionMap(filterMap);
        //拦截成功后返回的页面设定
        filterFactoryBean.setLoginUrl("/toLogin");
        //未授权页面
        filterFactoryBean.setUnauthorizedUrl("/unAuth");
        return filterFactoryBean;
    }

    //DefaultWebSecurityManager
    @Bean(name = "securityManager")
    public DefaultWebSecurityManager defaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(userRealm);
        return securityManager;
    }
    //创建realm对象
    @Bean
    public UserRealm userRealm(){
        return new UserRealm();
    }

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

UserRealm

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

public class UserRealm extends AuthorizingRealm {
    @Autowired
    UserService userService;
    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//        info.addStringPermission("user:add");
        // 获取登录成功后存入的principal(用户基本信息)
        Subject subject = SecurityUtils.getSubject();
        User principal = (User) subject.getPrincipal();
        //对角色权限进行授权
        info.addStringPermission(principal.getPerms());
        return info;
    }
    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        UsernamePasswordToken userToken = (UsernamePasswordToken) token;
        User user = userService.selectAllByName(userToken.getUsername());
        if (user == null){
            return null; //抛出异常  UnknownAccountException
        }
        //存放session,用于前端判断是否登录
        Subject currentSubject = SecurityUtils.getSubject();
        Session session = currentSubject.getSession();
        session.setAttribute("loginUser",user);
        //密码认证,shiro做~
        return new SimpleAuthenticationInfo(user, user.getPassword(),"");
    }
}

登录请求

//登录请求
    @RequestMapping("/login")
    @ResponseBody
    public Result login(String username, String password){
        //获取当前用户
        Subject subject = SecurityUtils.getSubject();
        //封装用户登录数据
        UsernamePasswordToken token = new UsernamePasswordToken(username,password);
        try {
            subject.login(token);
            SysUser principal = (SysUser) subject.getPrincipal();
            if (principal.getStatu() == 0){
                return Result.fail(500,"用户被禁用,请联系管理员处理",null);
            }else {
                return Result.succ(200,"登录成功",null);
            }
        } catch (UnknownAccountException e) {
            return Result.fail(400,"用户不存在",null);
        } catch (IncorrectCredentialsException e) {
            return Result.fail(400,"密码错误",null);
        }
    }