shiro+jwt如何实现单点登录

时间: 2023-03-14 20:27:27 浏览: 33
使用 Shiro JWT 实现单点登录可以分为以下几步: 1. 在服务端配置 Shiro JWT 过滤器,使其能够识别和验证 JWT 令牌。 2. 在用户登录时,服务端生成 JWT 令牌并返回给客户端。 3. 客户端在发起请求时,将 JWT 令牌放在 HTTP 头部的认证信息中,发送给服务端。 4. 服务端通过 Shiro JWT 过滤器验证 JWT 令牌的有效性。如果令牌有效,则允许用户访问;否则,拒绝用户访问。 5. 在服务端和客户端之间的所有请求中,都将带有 JWT 令牌,从而实现单点登录。
相关问题

shiro+jwt如何实现单点登录,代码实例

### 回答1: Shiro 支持使用 JSON Web Token (JWT) 实现单点登录 (SSO)。 实现步骤如下: 1. 在服务端生成 JWT 并返回给客户端。 2. 客户端保存 JWT 并在请求中加上 HTTP Header,如 "Authorization: Bearer JWT"。 3. 服务端收到请求后验证 JWT 的有效性。 4. 如果 JWT 有效,则允许访问请求的资源。 以下是一个使用 Shiro 实现 JWT 验证的示例代码: ```java 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 io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; public class JwtRealm extends AuthorizingRealm { private String secretKey; public JwtRealm(String secretKey) { this.secretKey = secretKey; } @Override public boolean supports(AuthenticationToken token) { return token instanceof JwtToken; } @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { // 这里可以根据 JWT 中的自定义字段来进行权限控制 return null; } @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { JwtToken jwtToken = (JwtToken) token; String jwt = jwtToken.getPrincipal().toString(); Claims claims = Jwts.parser().setSigningKey(secretKey).parseClaimsJws(jwt).getBody(); // 验证 JWT 是否过期 if (claims.getExpiration().before(new Date())) { throw new AuthenticationException("JWT 已过期"); } // 这里可以使用 claims 中的用户信息来创建 SimpleAuthenticationInfo 对象 return new SimpleAuthenticationInfo(jwt, jwt, "j ### 回答2: Shiro JWT是一种基于JSON Web Token(JWT)的认证方式,可以用于实现单点登录(Single Sign-On,SSO)。下面是一个简单的代码示例,展示如何使用Shiro JWT实现单点登录。 首先,需要添加Shiro和JWT的依赖包,可以使用Maven进行管理。在pom.xml文件中添加以下依赖项: ```xml <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.7.1</version> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-api</artifactId> <version>0.11.2</version> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-impl</artifactId> <version>0.11.2</version> <scope>runtime</scope> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-jackson</artifactId> <version>0.11.2</version> <scope>runtime</scope> </dependency> ``` 然后,需要创建一个JWT工具类,用于生成和解析JWT: ```java public class JWTUtil { private static final String SECRET_KEY = "your-secret-key"; private static final long EXPIRATION_TIME = 86400000; // 24 hours public static String createToken(String username) { Date now = new Date(); Date expirationDate = new Date(now.getTime() + EXPIRATION_TIME); return Jwts.builder() .setSubject(username) .setIssuedAt(now) .setExpiration(expirationDate) .signWith(SignatureAlgorithm.HS256, SECRET_KEY) .compact(); } public static String getUsernameFromToken(String token) { Claims claims = Jwts.parser() .setSigningKey(SECRET_KEY) .parseClaimsJws(token) .getBody(); return claims.getSubject(); } } ``` 接下来,在登录成功后生成JWT并返回给客户端: ```java public class LoginController { @PostMapping("/login") public String login(@RequestParam String username, @RequestParam String password) { // 验证用户名和密码 if (authenticateUser(username, password)) { // 生成JWT String token = JWTUtil.createToken(username); return token; } else { return "登录失败"; } } } ``` 在其他需要单点登录的接口中,可以使用Shiro的注解来验证JWT的有效性: ```java public class UserController { @RequiresAuthentication @GetMapping("/user/{id}") public String getUser(@PathVariable String id) { // 处理业务逻辑 return "User " + id; } } ``` 以上就是使用Shiro JWT实现单点登录的简单示例。在实际项目中,还需要结合数据库等存储方式来保存用户信息和JWT的校验过程,以及处理JWT过期等情况。 ### 回答3: 在Shiro中,实现JWT(JSON Web Token)的单点登录,需要以下步骤: 首先,确保已经集成了Shiro和JWT相关的依赖。 然后,定义一个Shiro的自定义Realm,用于验证用户身份和生成JWT。如下示例: ```java public class JWTRealm extends AuthorizingRealm { @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { // 授权逻辑,可根据具体需求进行自定义实现 return null; } @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { JWTToken jwtToken = (JWTToken) token; String jwt = jwtToken.getToken(); // 解析JWT并验证用户身份 String username = JWTUtils.getUsername(jwt); String password = JWTUtils.getPassword(jwt); // 根据用户名查询数据库或其他存储,获取用户信息 // 此处省略数据库查询逻辑 if (username == null || !password.equals("123456")) { throw new IncorrectCredentialsException("用户身份验证失败"); } // 用户身份验证通过,返回AuthenticationInfo对象 SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(username, jwt, getName()); return authenticationInfo; } @Override public boolean supports(AuthenticationToken token) { return token instanceof JWTToken; } } ``` 接下来,配置Shiro的过滤链,让Shiro对请求进行JWT认证和授权的处理。如下示例: ```java public class ShiroConfig { @Bean public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager) { ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(securityManager); shiroFilterFactoryBean.setLoginUrl("/login"); shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized"); // 添加自定义的JWT过滤器 Map<String, Filter> filters = new HashMap<>(); filters.put("jwt", new JWTFilter()); shiroFilterFactoryBean.setFilters(filters); // 配置过滤链 Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>(); filterChainDefinitionMap.put("/login", "anon"); filterChainDefinitionMap.put("/**", "jwt"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); return shiroFilterFactoryBean; } @Bean public DefaultWebSecurityManager securityManager(ShiroRealm shiroRealm) { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(shiroRealm); return securityManager; } @Bean public ShiroRealm shiroRealm() { return new ShiroRealm(); } } ``` 最后,创建一个JWT过滤器,用于处理JWT的验证和登录。如下示例: ```java public class JWTFilter extends AuthenticatingFilter { @Override protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) { String jwt = getTokenFromRequest(request); if (StringUtils.isNotBlank(jwt) && JWTUtils.verifyToken(jwt)) { return new JWTToken(jwt); } return null; } @Override protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { redirectToLogin(request, response); return false; } @Override protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) { if (isLoginAttempt(request, response)) { try { executeLogin(request, response); } catch (Exception e) { e.printStackTrace(); } } return true; } private boolean isLoginAttempt(ServletRequest request, ServletResponse response) { String jwt = getTokenFromRequest(request); return StringUtils.isNotBlank(jwt) && JWTUtils.verifyToken(jwt); } private String getTokenFromRequest(ServletRequest request) { HttpServletRequest httpServletRequest = (HttpServletRequest) request; String jwt = httpServletRequest.getHeader("Authorization"); if (StringUtils.isNotBlank(jwt) && jwt.startsWith("Bearer ")) { return jwt.replace("Bearer ", ""); } return null; } private void redirectToLogin(ServletRequest request, ServletResponse response) { HttpServletResponse httpServletResponse = (HttpServletResponse) response; httpServletResponse.setStatus(HttpStatus.UNAUTHORIZED.value()); } } ``` 这样就实现了使用Shiro和JWT实现单点登录的功能。使用以上代码示例,可根据具体需求进行扩展和自定义。

Jwt redis shiro实现单点登录

单点登录是指用户只需要登录一次即可访问多个应用系统,而不需要针对每个应用系统单独登录。实现单点登录的方案很多,其中使用JWT、Redis和Shiro的组合可以实现一个轻量的、安全的单点登录方案。 具体实现步骤如下: 1. 首先,用户在登录系统时输入账号和密码提交登录请求。后端系统验证通过后,生成一个JWT Token,并将Token保存到Redis缓存中。 2. 把JWT Token返回给前端界面,前端将Token保存在浏览器的Cookie中。 3. 当用户访问第二个应用系统时,前端将Cookie中的Token发送到后端进行验证。后端系统从Redis缓存中获取Token,验证通过后返回结果,用户即可访问该应用系统。 4. 在验证过程中,使用Shiro进行权限控制,保障系统安全。 使用JWT、Redis和Shiro实现单点登录的好处是: 1. JWT Token在客户端和服务端之间传输时是加密的,保证了系统的安全性。 2. Redis缓存可以实现分布式缓存,提高系统性能。 3. Shiro封装了常见的安全操作,使用起来简单方便。 综上所述,使用JWT、Redis和Shiro实现单点登录是一种轻量、安全、高效的方案,可以大大提高用户体验和系统安全性。

相关推荐

最新推荐

recommend-type

基于JWT实现SSO单点登录流程图解

主要介绍了基于JWT实现SSO单点登录流程图解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
recommend-type

node-v16.13.1-darwin-arm64.tar.xz

Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。
recommend-type

【前端素材】大数据-大数据可视化系统数据分析通用模版.zip

大数据技术指的是用于处理和分析大规模数据集的技术和工具。以下是一些常见的大数据技术和工具: Hadoop:Apache Hadoop是一个用于分布式存储和处理大规模数据的开源框架。它包括Hadoop Distributed File System(HDFS)用于数据存储和MapReduce用于数据处理。 Spark:Apache Spark是一个快速、通用的集群计算系统,提供了比MapReduce更快的数据处理能力。它支持内存计算和更多复杂的数据处理流程。 NoSQL数据库:NoSQL数据库(如MongoDB、Cassandra等)则更适用于处理这类数据。 数据仓库:数据仓库是一个用于集成和分析大规模数据的存储系统,一些知名的数据仓库包括Snowflake、Amazon Redshift等。 数据湖:数据湖是一个存储结构化和非结构化数据的存储池,用于支持数据分析和机器学习应用。 机器学习:大数据技术也广泛应用于机器学习领域,支持大规模数据的模型训练和预测分析。 流式处理:针对实时数据处理需求,流式处理技术(如Apache Kafka、Apache Flink)可以实时。
recommend-type

node-v8.3.0.tar.xz

Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。
recommend-type

云计算存储架构dr.pptx

云计算存储架构dr.pptx
recommend-type

RTL8188FU-Linux-v5.7.4.2-36687.20200602.tar(20765).gz

REALTEK 8188FTV 8188eus 8188etv linux驱动程序稳定版本, 支持AP,STA 以及AP+STA 共存模式。 稳定支持linux4.0以上内核。
recommend-type

管理建模和仿真的文件

管理Boualem Benatallah引用此版本:布阿利姆·贝纳塔拉。管理建模和仿真。约瑟夫-傅立叶大学-格勒诺布尔第一大学,1996年。法语。NNT:电话:00345357HAL ID:电话:00345357https://theses.hal.science/tel-003453572008年12月9日提交HAL是一个多学科的开放存取档案馆,用于存放和传播科学研究论文,无论它们是否被公开。论文可以来自法国或国外的教学和研究机构,也可以来自公共或私人研究中心。L’archive ouverte pluridisciplinaire
recommend-type

爬虫与大数据分析:挖掘数据价值,洞察趋势

![python网站爬虫技术实战](https://img-blog.csdnimg.cn/20181107141901441.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2hpaGVsbA==,size_16,color_FFFFFF,t_70) # 1. 爬虫基础与技术** 爬虫,又称网络蜘蛛,是一种自动化的程序,用于从互联网上抓取数据。其工作原理是模拟浏览器行为,通过发送请求并解析响应来获取网页内容。 爬虫技术涉及多种技术,
recommend-type

解释一下下面每句话的含义@RequestMapping(value = "gcGl") public String gcGl(Gcgl gcGl, Model model) { List<Gcgl> list = gcglService.findList(gcGl); if (list!=null&&list.size()>0) { model.addAttribute("gcGl", list.get(0)); }else { model.addAttribute("gcGl", gcGl); } return "modules/tjxx/gc08glForm"; }

这段代码是一个Java方法,用于处理HTTP请求,具体含义如下: - @RequestMapping(value = "gcGl"):这是一个注解,表示该方法会处理名为"gcGl"的请求,即当用户访问该请求时,会调用该方法。 - public String gcGl(Gcgl gcGl, Model model):这是方法的声明,它有两个参数:一个是Gcgl类型的gcGl,另一个是Model类型的model。方法的返回值是一个字符串类型。 - List<Gcgl> list = gcglService.findList(gcGl):这行代码调用了一个名为findList的方法,该方法接受一个
recommend-type

c++校园超市商品信息管理系统课程设计说明书(含源代码) (2).pdf

校园超市商品信息管理系统课程设计旨在帮助学生深入理解程序设计的基础知识,同时锻炼他们的实际操作能力。通过设计和实现一个校园超市商品信息管理系统,学生掌握了如何利用计算机科学与技术知识解决实际问题的能力。在课程设计过程中,学生需要对超市商品和销售员的关系进行有效管理,使系统功能更全面、实用,从而提高用户体验和便利性。 学生在课程设计过程中展现了积极的学习态度和纪律,没有缺勤情况,演示过程流畅且作品具有很强的使用价值。设计报告完整详细,展现了对问题的深入思考和解决能力。在答辩环节中,学生能够自信地回答问题,展示出扎实的专业知识和逻辑思维能力。教师对学生的表现予以肯定,认为学生在课程设计中表现出色,值得称赞。 整个课程设计过程包括平时成绩、报告成绩和演示与答辩成绩三个部分,其中平时表现占比20%,报告成绩占比40%,演示与答辩成绩占比40%。通过这三个部分的综合评定,最终为学生总成绩提供参考。总评分以百分制计算,全面评估学生在课程设计中的各项表现,最终为学生提供综合评价和反馈意见。 通过校园超市商品信息管理系统课程设计,学生不仅提升了对程序设计基础知识的理解与应用能力,同时也增强了团队协作和沟通能力。这一过程旨在培养学生综合运用技术解决问题的能力,为其未来的专业发展打下坚实基础。学生在进行校园超市商品信息管理系统课程设计过程中,不仅获得了理论知识的提升,同时也锻炼了实践能力和创新思维,为其未来的职业发展奠定了坚实基础。 校园超市商品信息管理系统课程设计的目的在于促进学生对程序设计基础知识的深入理解与掌握,同时培养学生解决实际问题的能力。通过对系统功能和用户需求的全面考量,学生设计了一个实用、高效的校园超市商品信息管理系统,为用户提供了更便捷、更高效的管理和使用体验。 综上所述,校园超市商品信息管理系统课程设计是一项旨在提升学生综合能力和实践技能的重要教学活动。通过此次设计,学生不仅深化了对程序设计基础知识的理解,还培养了解决实际问题的能力和团队合作精神。这一过程将为学生未来的专业发展提供坚实基础,使其在实际工作中能够胜任更多挑战。