java判断用户是否在某一个区域登录_使用 JWT 技术,简单快速实现系统间的单点登录...

  • 一、JWT定义及其组成
  • 二、认证过程
  • 三、java代码实现

单点登录(single sign on),简称sso。它的定义是多个应用系统间,只需要登录一次就可以访问所有相互信任的应用系统。下面介绍用jwt技术如何来实现单点登录。

一、JWT定义及其组成

JWT(JSON WEB TOKEN)是一个非常轻巧的规范,这个规范允许我们使用jwt在客户端和服务器之间传递安全可靠的信息。

JWT由3个部分组成,分别是头部、载荷、签名。

头部部分

{
  "alg": "HS256",
  "typ": "JWT"
}

alg描述的是签名算法。

载荷部分

{
  "iss": "发行者",
  "sub": 主题",
  "aud": “观众”,

  "exp":"过期时间",

  "iat":"签发时间"

以下可以添加自定义数据

    "userid":"11111",

    “realname":"真实姓名",

    "email":"",
}

Base64算法是可逆的,不可以在载荷部分保存用户密码等敏感信息。如果业务需要,也可以采用对称密钥加密。

签名部分

HMACSHA256(Base64(Header) + "." + Base64(Payload),  secret)

签名的目的是用来验证头部和载荷是否被非法篡改。

验签过程描述:读取Header部分并Base64解码,得到签名算法。根据以上方法算出签名,如果签名信息不一致,说明是非法的。

二、认证过程

下面我们从一个实例来看如何运用JWT机制实现认证:

登录

第一次认证:第一次登录,用户从浏览器输入用户名/密码,提交后到服务器的登录处理的Action层(Login Action);

Login Action调用认证服务进行用户名密码认证,如果认证通过,Login Action层调用用户信息服务获取用户信息(包括完整的用户信息及对应权限信息);

返回用户信息后,Login Action从配置文件中获取Token签名生成的秘钥信息,进行Token的生成;

生成Token的过程中可以调用第三方的JWT Lib生成签名后的JWT数据;

完成JWT数据签名后,将其设置到COOKIE对象中,并重定向到首页,完成登录过程;

v2-9c7694c098e75579e15900b8a08110d0_b.jpg

请求认证

v2-34aea2d3da67854760471989e3424d52_b.jpg

基于Token的认证机制会在每一次请求中都带上完成签名的Token信息,这个Token信息可能在COOKIE 中,也可能在HTTP的Authorization头中;

客户端(APP客户端或浏览器)通过GET或POST请求访问资源(页面或调用API);

认证服务作为一个Middleware HOOK 对请求进行拦截,首先在cookie中查找Token信息,如果没有找到,则在HTTP Authorization Head中查找;

如果找到Token信息,则根据配置文件中的签名加密秘钥,调用JWT Lib对Token信息进行解密和解码;

完成解码并验证签名通过后,对Token中的exp、nbf、aud等信息进行验证;全部通过后,根据获取的用户的角色权限信息,进行对请求的资源的权限逻辑判断;

如果权限逻辑判断通过则通过Response对象返回;否则则返回HTTP 401;

三、java代码实现

1、用户登录:

用户登录验证通过后添加以下代码

String token = JwtUtil().generateToken(userName);
Cookie cookie = new Cookie("autotoken", token);
response.addCookie(cookie);

2、调用http请求

后续的http请求认证都带上token

3、应用系统认证

编写一个过滤器,对每一个请求进行解码认证

 String authToken = request.getHeader(this.tokenHeader);
 if (jwtTokenUtil.validateToken(authToken) {

 }

来源:http://rrd.me/enqP7
作者:君之见

:-D 搜索微信号(ID:芋道源码),可以获得各种 Java 源码解析、原理讲解、面试题、学习指南。

:-D 并且,回复【书籍】后,可以领取笔者推荐的各种 Java 从入门到架构的 100 本书籍。

:-D 并且,回复【技术群】后,可以加入专门讨论 Java、后端、架构的技术群。

v2-e569146e9ee9ecf71c2589f241a5d1d7_b.jpg
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个基本的Java代码实现JWT单点登录的示例: 1. 添加依赖 在 Maven 项目中添加以下依赖: ``` <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.1</version> </dependency> ``` 2. 生成 JWT Token ``` import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import java.util.Date; public class JwtUtils { private static final String SECRET_KEY = "YOUR_SECRET_KEY"; private static final long EXPIRATION_TIME = 86400000; // 24小时 public static String generateToken(String username) { Date now = new Date(); Date expiration = new Date(now.getTime() + EXPIRATION_TIME); return Jwts.builder() .setSubject(username) .setIssuedAt(now) .setExpiration(expiration) .signWith(SignatureAlgorithm.HS256, SECRET_KEY) .compact(); } // 验证 Token 是否有效 public static boolean validateToken(String token) { try { Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token); return true; } catch(Exception ex) { return false; } } // 从 Token 中获取用户名 public static String getUsernameFromToken(String token) { return Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody().getSubject(); } } ``` 3. 验证 JWT Token 在需要验证用户身份的地方,可以使用以下代码验证 JWT Token: ``` import javax.servlet.http.HttpServletRequest; import org.springframework.web.filter.OncePerRequestFilter; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.Claims; import io.jsonwebtoken.SignatureException; public class JwtAuthenticationFilter extends OncePerRequestFilter { private static final String SECRET_KEY = "YOUR_SECRET_KEY"; private static final String TOKEN_PREFIX = "Bearer"; private static final String HEADER_STRING = "Authorization"; @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { String header = request.getHeader(HEADER_STRING); if(header == null || !header.startsWith(TOKEN_PREFIX)) { chain.doFilter(request, response); return; } String token = header.replace(TOKEN_PREFIX, "").trim(); try { Claims claims = Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody(); request.setAttribute("username", claims.getSubject()); } catch(SignatureException ex) { response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); return; } chain.doFilter(request, response); } } ``` 4. 配置 Spring SecuritySpring Security 配置类中添加以下配置: ``` import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; @Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private JwtAuthenticationFilter jwtAuthenticationFilter; @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .authorizeRequests() .antMatchers("/login").permitAll() .anyRequest().authenticated() .and() .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("admin").password(passwordEncoder().encode("admin123")).roles("ADMIN"); } @Override @Bean public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } } ``` 以上就是一个基本的Java代码实现JWT单点登录的示例。需要注意的是,SECRET_KEY 应该是一个随机的字符串,不要泄露给其他人。此外,在实际应用中,应该使用数据库或其他存储来保存用户信息,而不是在配置文件中硬编码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值