springboot整合shiro实现前后端分离,兼容最新的jakarta的依赖包(片尾推荐当前最好用的权限框架)

发布时间:2023年12月21日
1.简单的用法如下ini realm方式
//1.创建数据源Realm
       DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
            Ini ini = Ini.fromResourcePath("classpath:shiro.ini");
        defaultSecurityManager.setRealm(new MyRealm());
defaultSecurityManager.setRealm(new IniRealm(ini));
  //2、安全管理器
      SecurityUtils.setSecurityManager(defaultSecurityManager);
//        //3.创建主体
   Subject subject = SecurityUtils.getSubject();
AuthenticationToken userToken = new UsernamePasswordToken("admin", "123456");
    try {
        //4.认证
          subject.login(userToken);
2、整合步骤
1.添加依赖、适配jakarta的依赖包
<!-- 引入适配jakarta的依赖包 -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-core</artifactId>
            <classifier>jakarta</classifier>
            <version>1.11.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-web</artifactId>
            <classifier>jakarta</classifier>
            <version>1.11.0</version>
            <exclusions>
                <exclusion>
                    <groupId>org.apache.shiro</groupId>
                    <artifactId>shiro-core</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
2、添加配置类
package com.example.spring_shiro.config;

import com.example.spring_shiro.data.MyRealm;
import jakarta.servlet.Filter;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.realm.Realm;
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.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

@Configuration
public class ShiroConfig {
    //1.设置realm

    @Autowired
    private  JWTFilter jwtFilter;
    @Bean
    public MyRealm getRealm(HashedCredentialsMatcher credentialsMatcher) {
        MyRealm myRealm = new MyRealm();
        myRealm.setCredentialsMatcher(credentialsMatcher);
        return myRealm;
    }

    //2.管理安全管理器
    @Bean
    public DefaultWebSecurityManager defaultWebSecurityManager(Realm realm) {
        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
        defaultWebSecurityManager.setRealm(realm);
        return defaultWebSecurityManager;

    }

    //3.配置shiro 过滤器

    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager securityManager) {
        ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
        factoryBean.setSecurityManager(securityManager);
        Map<String, String> filterChainDefinitionMap = new HashMap<>();

        Map<String, Filter> filterMap = new HashMap<>();
        //这个地方其实另外两个filter可以不设置,默认就是

//        filterMap.put("jwt", jwtFilter);

//        factoryBean.setFilters(filterMap);

//        filterChainDefinitionMap.put("/hello", "anon");
        filterChainDefinitionMap.put("/user/login", "anon");
        filterChainDefinitionMap.put("/user/logout", "authc");
        filterChainDefinitionMap.put("/**", "authc");
//
//        filterChainDefinitionMap.put("/login", "anon");
        filterChainDefinitionMap.put("/**", "authc");
//        factoryBean.setLoginUrl("/unauth");
        factoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return factoryBean;
    }


    @Bean
    public HashedCredentialsMatcher getHashedCredentialsMatcher() {
        HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
        credentialsMatcher.setHashAlgorithmName("md5");
        credentialsMatcher.setHashIterations(1024);

        return credentialsMatcher;

    }

    // 开启shiro注解的支持
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(securityManager);
        return advisor;
    }

    // 开启aop注解支持
    @Bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator defaultAAP = new DefaultAdvisorAutoProxyCreator();
        defaultAAP.setProxyTargetClass(true);
        return defaultAAP;
    }

}

3、realm 认证、加密以及数据库逻辑
package com.example.spring_shiro.data;


import com.example.spring_shiro.pojo.PermissionData;
import com.example.spring_shiro.pojo.User;
import com.example.spring_shiro.services.UserServices;
import lombok.extern.slf4j.Slf4j;
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.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

@Slf4j
public class MyRealm extends AuthorizingRealm {


    @Autowired
    private UserServices userServices;

    //授权

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        log.info(principals.getPrimaryPrincipal().toString());
        String userName = principals.getPrimaryPrincipal().toString();
        PermissionData data = userServices.findUserIdByName(userName);
        if (data == null) {
            throw new IllegalArgumentException("无权限");
        }
        String[] authorities = data.getAuthorityName().split(",");
        log.info(data.getAuthorityName());
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        for (int i = 0; i < authorities.length; i++) {
            log.info(authorities[i]);
            authorizationInfo.addStringPermission(authorities[i]);

        }
        return authorizationInfo;
    }

    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.out.println("token = " + token);
        //1.获取当前用户的用户名字
        String userName = (String) token.getPrincipal();
        User user = userServices.findUserByName(userName);
        if (user == null) {
            throw new AccountException("账号不存在");

        }

//        SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(userName, user.getPassword(), this.getClass().getSimpleName());
        SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(userName, user.getPassword(), ByteSource.Util.bytes("jiangnnayizhou110"), this.getClass().getSimpleName());

        return simpleAuthenticationInfo;
    }
}

4.services 代码
package com.example.spring_shiro.services;

import com.example.spring_shiro.mapper.UserMapper;
import com.example.spring_shiro.pojo.PermissionData;
import com.example.spring_shiro.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class UserServices implements IUserServices {
    @Autowired
    private UserMapper userMapper;

    @Override
    public List<User> findUsersAll() {
        return userMapper.findUsersAll();
    }

    @Override
    public int saveUser(User user) {
        return userMapper.saveUser(user);
    }

    @Override
    public User findUserByName(String userName) {
        return userMapper.findUserByName(userName);
    }

    @Override
    public PermissionData findUserIdByName(String userName) {
        return userMapper.findUserIdByName(userName);
    }


}

5、mapper
package com.example.spring_shiro.mapper;

import com.example.spring_shiro.pojo.PermissionData;
import com.example.spring_shiro.pojo.User;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

@Mapper
public interface UserMapper {

    List<User> findUsersAll();

    int saveUser(User user);

    User findUserByName(String userName);

    PermissionData findUserIdByName(String userName);
}

6、重要的控制器
package com.example.spring_shiro.controller;

import com.example.spring_shiro.encrypt.Md5Utils;
import com.example.spring_shiro.pojo.Result;
import com.example.spring_shiro.pojo.User;
import com.example.spring_shiro.services.IUserServices;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresUser;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@Slf4j
@RequestMapping("/user")
public class UserController {

    @Autowired
    private IUserServices userServices;

    @GetMapping("list")
    @RequiresUser
    public List<User> findAll() {
        return userServices.findUsersAll();
    }

    //创建用户
    @PostMapping("addUser")
    @RequiresPermissions("student:look")
    public User saveUser(User user) {
        String password = user.getPassword();
        password = Md5Utils.md5(password);
        user.setPassword(password);
        //密码加密
        int number = userServices.saveUser(user);
        if (number > 0) {
            return user;
        }
        return null;


    }

    @GetMapping("edit")
    @RequiresPermissions("student:edit")
    public Result edit() {
        return Result.ok("可以编辑");
    }

    @GetMapping("delete")
    @RequiresPermissions("student:delete")
    public Result deleteInfo() {
        return Result.ok("可以删除操作");
    }

    @PostMapping("/login")
    public Result login(User user) {
        String userName = user.getUserName();
        String password = user.getPassword();
        Subject subject = SecurityUtils.getSubject();
        AuthenticationToken userToken = new UsernamePasswordToken(userName, password);
        try {
            subject.login(userToken);
            log.info("成功");
            return Result.ok(userName);
        } catch (UnknownAccountException e) {
            log.info("失败" + "账号没找到" + e.getMessage());
            return Result.error(-1, "账号为未找到");
        } catch (IncorrectCredentialsException incorrectCredentialsException) {
            log.info("失败" + "账号或者密码错误" + incorrectCredentialsException.getMessage());
            return Result.error(-1, "账号或者密码错误");
        }


    }

    @GetMapping("/logout")
    public Result logout() {
        Subject subject = SecurityUtils.getSubject();
        log.info(String.valueOf(subject.isAuthenticated()));
        if (subject.isAuthenticated()) {
            subject.logout();
        }
        return Result.ok("退出成功", null);
    }
}

Sa-Tokenv1.37.0

一个轻量级 java 权限认证框架,让鉴权变得简单、优雅

添加链接描述

文章来源:https://blog.csdn.net/qq_30519365/article/details/135141274
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。