springboot整合shiro实现前后端分离,兼容最新的jakarta的依赖包(片尾推荐当前最好用的权限框架)
2023-12-21 22:34:14
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
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!