从 JWT 令牌中提取信息时存在非法 base64url 字符:“ ”

问题描述 投票:0回答:1

尝试解码 JWT 令牌以从令牌中提取信息时出现错误 喜欢

非法的base64url字符:''

这是我的服务类,当尝试执行声明时没有输出并抛出错误

我正在尝试验证用户是否在登录时生成了 jwt 令牌,当我尝试使用需要验证用户的不同服务时,我想从 JWT 令牌中提取用户信息并将其与数据库进行匹配

package com.example.RentCar.Services;

import java.security.Key;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;

import com.example.RentCar.DTOS.UserRequestDTO;
import com.example.RentCar.Models.User;
import com.example.RentCar.Repository.UserRepository;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;


import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.security.Keys;

@Service
public class JwtServicesImpl implements JwtServices {
    private UserRequestDTO userRequestDTO;
    //private final UserRepository userRepository;
   // @Value("${token.signing.key}")
    private String jwtSigningKey = "413F4428472B4B6250655368566D5970337336763979244226452948404D6351";


    @Override
    public String extractUserName(String token) {
        return extractClaim(token, Claims::getSubject);
    }
    @Override
    public String generateToken(User user) {
        return generateToken(new HashMap<>(), user);
    }



    @Override
    public boolean isTokenValid(String token, UserServicesImpl userServices) {
        final String email = extractUserName(token);
        UserDetails user = (userServices.loadUserByUsername(email));
        String email2 = user.getUsername();
        return (email.equals(email2) && !isTokenExpired(token));
    }
    private <T> T extractClaim(String token, Function<Claims, T> claimsResolvers) {
        final Claims claims = extractAllClaims(token);
        System.out.println(claims); //not printing
        return claimsResolvers.apply(claims);
    }

    private String generateToken(Map<String, Object> extraClaims, User user) {

        return Jwts.builder().setClaims(extraClaims).setSubject(user.getUserEmail())
                .setIssuedAt(new Date(System.currentTimeMillis()))
                .setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 24))
                .signWith(getSigningKey(), SignatureAlgorithm.HS256).compact();
    }
    private boolean isTokenExpired(String token) {
        return extractExpiration(token).before(new Date());
    }

    private Date extractExpiration(String token) {
        return extractClaim(token, Claims::getExpiration);
    }

    private Claims extractAllClaims(String token) {
        return Jwts.parserBuilder().setSigningKey(getSigningKey()).build().parseClaimsJws(token)
                .getBody();
    }

    private Key getSigningKey() {
       // System.out.println(jwtSigningKey);
        byte[] keyBytes = Decoders.BASE64.decode(jwtSigningKey);
        return Keys.hmacShaKeyFor(keyBytes);
    }
}
```
below is the error

io.jsonwebtoken.io.DecodingException: Illegal base64url character: ' '
    at io.jsonwebtoken.io.Base64.ctoi(Base64.java:221)
    at io.jsonwebtoken.io.Base64.decodeFast(Base64.java:270)
    at io.jsonwebtoken.io.Base64Decoder.decode(Base64Decoder.java:36)
    at io.jsonwebtoken.io.Base64Decoder.decode(Base64Decoder.java:23)
    at io.jsonwebtoken.io.ExceptionPropagatingDecoder.decode(ExceptionPropagatingDecoder.java:36)
    at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:288)
    at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:529)
    at io.jsonwebtoken.impl.DefaultJwtParser.parseClaimsJws(DefaultJwtParser.java:589)
    at io.jsonwebtoken.impl.ImmutableJwtParser.parseClaimsJws(ImmutableJwtParser.java:173)
    at com.example.RentCar.Services.JwtServicesImpl.extractAllClaims(JwtServicesImpl.java:76)
    at com.example.RentCar.Services.JwtServicesImpl.extractClaim(JwtServicesImpl.java:55)
    at com.example.RentCar.Services.JwtServicesImpl.extractUserName(JwtServicesImpl.java:34)
    at com.example.RentCar.Controllers.UserController.ModifyAddress(UserController.java:36)
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
    at java.base/java.lang.reflect.Method.invoke(Method.java:578)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:884)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1081)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:974)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1011)

Expecting should be like can claims or extract information from token

java spring-boot jwt base64 base64url
1个回答
0
投票

正如 Jon Skeet 所说,你的 jwtSigningKey 以十六进制编码,在 getSigningKey() 中,你告诉 Java 用 Base64 对其进行解码。

使用 Base64 编码密钥或使用 Hex 解码。

参见https://stackoverflow.com/a/140861/21538342

© www.soinside.com 2019 - 2024. All rights reserved.