SpringBoot集成Shiro组件
项目使用的springboot 版本是 2.7.15
全部 pom.xml

<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.15</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>demo-2</artifactId> <version>0.0.1-SNAPSHOT</version> <name>demo-2</name> <description>demo-2</description> <properties> <java.version>11</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring-boot-web-starter</artifactId> <version>1.12.0</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.26</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.68</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
注意添加 如下依赖,在上面 已经 有了
<dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring-boot-web-starter</artifactId> <version>1.12.0</version> </dependency>
DefaultConfig.java 配置
package com.example.demo2.config; import com.example.demo2.filter.JwtFilter; import com.example.demo2.filter.MyFormAuthenticationFilter; import org.apache.shiro.SecurityUtils; import org.apache.shiro.cache.MemoryConstrainedCacheManager; import org.apache.shiro.mgt.DefaultSessionStorageEvaluator; import org.apache.shiro.mgt.DefaultSubjectDAO; import org.apache.shiro.realm.Realm; import org.apache.shiro.realm.text.TextConfigurationRealm; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.servlet.Filter; import java.util.LinkedHashMap; import java.util.Map; @Configuration public class DefaultConfig { @Bean public Realm realm(){ TextConfigurationRealm realm = new TextConfigurationRealm(); realm.setUserDefinitions("admin=123,admin\n chenchao=123,user"); realm.setRoleDefinitions("admin=read,write\n user=read"); return realm; } @Bean public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager) { ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); Map<String, Filter> filterMap = new LinkedHashMap<>(16); filterMap.put("jwt",new JwtFilter()); filterMap.put("myFilter",new MyFormAuthenticationFilter()); shiroFilterFactoryBean.setFilters(filterMap); Map<String,String> chainDefinition = new LinkedHashMap<>(); chainDefinition.put("/api/passport/*","myFilter"); chainDefinition.put("/api/**", "jwt"); // all paths are managed via annotations shiroFilterFactoryBean.setFilterChainDefinitionMap(chainDefinition); // or allow basic authentication, but NOT require it. // chainDefinition.addPathDefinition("/**", "authcBasic[permissive]"); shiroFilterFactoryBean.setSecurityManager(securityManager); shiroFilterFactoryBean.setLoginUrl("/api/passport/login"); return shiroFilterFactoryBean; } @Bean public DefaultWebSecurityManager defaultWebSecurityManager(UserRealm userRealm) { DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager(); // 使用自定义Realm defaultWebSecurityManager.setRealm(userRealm); // 关闭Shiro自带的session DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO(); DefaultSessionStorageEvaluator defaultSessionStorageEvaluator = new DefaultSessionStorageEvaluator(); defaultSessionStorageEvaluator.setSessionStorageEnabled(true); subjectDAO.setSessionStorageEvaluator(defaultSessionStorageEvaluator); defaultWebSecurityManager.setSubjectDAO(subjectDAO); // 设置自定义Cache缓存 defaultWebSecurityManager.setCacheManager(new MemoryConstrainedCacheManager()); //3.将securityManager绑定到运行环境 SecurityUtils.setSecurityManager(defaultWebSecurityManager); return defaultWebSecurityManager; } }
UserRealm.java 登录获取用户信息和验证权限时会用到
package com.example.demo2.config; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.SimpleAuthenticationInfo; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import org.springframework.stereotype.Component; @Component public class UserRealm extends AuthorizingRealm { @Override public boolean supports(AuthenticationToken token) { System.out.println(token.toString()); return true; } @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { System.out.println(principalCollection.getRealmNames().toString()); return null; } @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { System.out.println(authenticationToken.getPrincipal().toString()); return new SimpleAuthenticationInfo("admin","123","userRealm"); } }
登录控制器
PassportController.java
package com.example.demo2.controller; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.subject.Subject; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/api/passport") public class PassportController { @PostMapping("login") public String login(){ Subject subject = SecurityUtils.getSubject(); subject.login(new UsernamePasswordToken("admin","123")); System.out.println("subject.isAuthenticated() = " + subject.isAuthenticated()); return "success"; } }
测试业务控制器
package com.example.demo2.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/api/test") public class TestController { @GetMapping("/one") public String one(){ return "one"; } }
JwtFilter.java 过滤器
package com.example.demo2.filter; import com.alibaba.fastjson.JSONObject; import lombok.extern.slf4j.Slf4j; import org.apache.shiro.SecurityUtils; import org.apache.shiro.subject.Subject; import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletResponse; import java.io.PrintWriter; @Slf4j public class JwtFilter extends BasicHttpAuthenticationFilter { @Override protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { log.info("========={}=========","onAccessDenied"); Subject subject = SecurityUtils.getSubject(); // 是否登录 已登录返回 true 否则返回 false boolean authenticated = subject.isAuthenticated(); // 判断是否拥有权限 如果无权限 则 抛出 UnauthorizedException 异常 // subject.checkPermission("path"); if (!authenticated){ HttpServletResponse httpServletResponse = (HttpServletResponse) response; httpServletResponse.setStatus(200); httpServletResponse.setContentType("application/json;charset=utf-8"); PrintWriter out = httpServletResponse.getWriter(); JSONObject json = new JSONObject(); json.put("state","401"); json.put("msg","登录已失效,请重新登录!"); out.println(json); out.flush(); out.close(); } return authenticated; } }
普通过滤器
package com.example.demo2.filter; import org.apache.shiro.web.filter.authc.FormAuthenticationFilter; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; public class MyFormAuthenticationFilter extends FormAuthenticationFilter { @Override protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { return true; } }
备注 默认的内置过滤器
过滤器名称 | 过滤器类 | 描述 |
anon | org.apache.shiro.web.filter.authc.AnonymousFilter | 匿名过滤器 |
authc | org.apache.shiro.web.filter.authc.FormAuthenticationFilter | 如果继续操作,需要做对应的表单验证否则不能通过 |
authcBasic | org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter | 基本http验证过滤,如果不通过,跳转屋登录页面 |
logout | org.apache.shiro.web.filter.authc.LogoutFilter | 登录退出过滤器 |
noSessionCreation | org.apache.shiro.web.filter.session.NoSessionCreationFilter | 没有session创建过滤器 |
perms | org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter | 权限过滤器 |
port | org.apache.shiro.web.filter.authz.PortFilter | 端口过滤器,可以设置是否是指定端口如果不是跳转到登录页面 |
rest | org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter | http方法过滤器,可以指定如post不能进行访问等 |
roles | org.apache.shiro.web.filter.authz.RolesAuthorizationFilter | 角色过滤器,判断当前用户是否指定角色 |
ssl | org.apache.shiro.web.filter.authz.SslFilter | 请求需要通过ssl,如果不是跳转回登录页 |
user | org.apache.shiro.web.filter.authc.UserFilter | 如果访问一个已知用户,比如记住我功能,走这个过滤器 |
标签:
springboot
, shiro
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)