我正在使用 JJWT 库生成 JWT 令牌。我按如下方式生成令牌。我使用虚拟值作为我的密钥。
我们可以假设jwt.security.key=security-key
@Value("${jwt.security.key}")
private String key;
@Value("${ws.issuer}")
private String issuer;
static final long ONE_MINUTE_IN_MILLIS=60000;
static final long TOKEN_DURATION_IN_MIN=30L;
private SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
@Override
public String issueToken(String userName) {
long nowMillis = System.currentTimeMillis();
long expMillis = nowMillis + (ONE_MINUTE_IN_MILLIS * TOKEN_DURATION_IN_MIN);
return Jwts
.builder()
.setId("01")
.setIssuedAt(new Date(nowMillis))
.setHeaderParam("typ","JWT")
.setSubject(userName)
.setIssuer(issuer)
.setExpiration(new Date(expMillis))
.signWith(signatureAlgorithm, key).compact();
}
Run Code Online (Sandbox Code Playgroud)
虽然token可以成功解码。每次我验证 jwt.io 调试器的签名时,总是会导致签名无效。可以在这里看到。
我有一个关于JSON Web Token(JWT)的一般问题.
如果通过黑客攻击或物理访问从客户端窃取JWT(例如,它被存储为cookie或应用程序的数据库),它可以用于发送到服务器,服务器将认为它是合法用户.它是否正确?
是否有任何通用或标准的做法来防范这种情况,例如,通过从客户端一起发送设备/浏览器类型或一些参考代码,服务器检查它是否与生成和存储JWT令牌的其他数据相匹配.(但是,我读到标准的做法是不在服务器上存储任何东西.)
请告知我需要实现Java JWT(JJWT),RESTful Java Jersey和Google Web Toolkit.(我一直在阅读这样的文档:[ https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage]).
谢谢!
我的客户向我发送了一个 JWT,我需要使用他们的公钥验证此 JWT。我正在使用 Java 和 JJWT 框架来验证此令牌。我知道使用 HS256 解码此令牌,但使用 RS256 我不知道。
他们的配置是:
在这里编辑以改进我的问题。我正在使用的 jjwt 解析示例:
Claims String secret = "-----BEGIN CERTIFICATE-----myx5ckey-----END CERTIFICATE-----"
byte[] dataBytes = Base64.getEncoder().encode(secret.getBytes());
byte[] byteKey = Base64.getDecoder().decode(dataBytes);
X509EncodedKeySpec X509publicKey = new X509EncodedKeySpec(byteKey);
KeyFactory kf = KeyFactory.getInstance("RSA");
PublicKey publicKey = kf.generatePublic(X509publicKey);
Claims body = null;
body = Jwts.parser().setSigningKey(publicKey.getEncoded())
.parseClaimsJws(idToken)
.getBody();
java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: invalid key format
at sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:205)
Run Code Online (Sandbox Code Playgroud)
如何使用我显示的 JWKS 信息验证收到的令牌?(上图)
问题是我的应用程序在令牌过期时抛出异常,而我无法捕获该异常。我想捕获该异常并做另一件事。尝试在 catch 块上注释异常语句但没有进展。
例外:
**03-Mar-2018 18:32:16.941 SEVERE [http-nio-1234-exec-26] org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service()
for servlet [Jersey Web Application] in context with path [/uis] threw
exception [io.jsonwebtoken.ExpiredJwtException: JWT expired at
2018-03-03T18:32:03Z. Current time: 2018-03-03T18:32:16Z, a difference
of 13940 milliseconds. Allowed clock skew: 0 milliseconds.] with root
cause io.jsonwebtoken.ExpiredJwtException: JWT expired at
2018-03-03T18:32:03Z. Current time: 2018-03-03T18:32:16Z, a difference
of 13940 milliseconds. Allowed clock skew: 0 milliseconds. at
io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:385)
at
io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:481)
at
io.jsonwebtoken.impl.DefaultJwtParser.parseClaimsJws(DefaultJwtParser.java:541)
at az.naxtel.java.JWTController.isValid(JWTController.java:53) at
az.naxtel.java.JWTController.getManagerFromToken(JWTController.java:37)
at
az.naxtel.api.cc.resource.RedmineJournalResource.getJournalsCount(RedmineJournalResource.java:59)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) …Run Code Online (Sandbox Code Playgroud) 我正在使用jjwtjwt令牌创建。使用本地系统时间设置到期日期时,一切工作正常,即
日期expDate = new Date(new Date()。getTime()+ 180000); //java.util.Date
但是我尝试使用UTC格式的日期时间,并用相同的3分钟到期日期对jwt令牌进行了签名。现在,ExpiredJwtException即使我在创建令牌后也正在进行验证,但是它正在抛出。我正在使用SimpleDateFormat将时区设置为utc。这是我在Java中使用jjwt创建令牌的代码:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date expDate, issDate;
try {
expDate = (Date) simpleDateFormat.parse(sdf.format(new Date().getTime() + 180000));
issDate = (Date) simpleDateFormat.parse(sdf.format(new Date().getTime()));
JwtBuilder builder = Jwts.builder()
.setExpiration(expDate)
.setIssuedAt(issDate)
.setId(id)
.signWith(signingKey, signatureAlgorithm);
jwtToken = builder.compact();
} catch (ParseException ex) {
}
Run Code Online (Sandbox Code Playgroud)
令牌已成功创建。我也可以在线验证内容。expDate比issDate早3分钟。我还通过传递已创建的令牌,在调用令牌后立即调用用于验证令牌的方法。我的验证方法有:
try {
Jwts.parser().setSigningKey(signingKey).parseClaimsJws(token);
log.info("jwt verification success");
} catch (ExpiredJwtException exJwt) {
log.info("expired jwt : \n{}", exJwt.getMessage());
} catch …Run Code Online (Sandbox Code Playgroud) 当在本地启动我的 Quarkus 项目时,mvn quarkus:dev执行使用 JJWT 的函数时没有错误。但是,当我将项目导出到 docker 容器时,它给我一个错误,指出它找不到 DefaultJwtBuilder。
当对我的项目进行 dockerizing 时,我首先执行
./mvnw package -Pnative -Dquarkus.native.container-build=true
如Quarkus 文档中所述,用于在不使用 GraalVM 的情况下创建 Linux 可执行文件。
其次是
docker build -f src/main/docker/Dockerfile.native -t quarkus-quickstart/getting-started .
当使用 Docker Desktop 启动项目时,出现错误。
我的 pom.xml 中的依赖项如下。
<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>
Run Code Online (Sandbox Code Playgroud)
详细的错误信息是
io.jsonwebtoken.lang.UnknownClassException: Unable to load class named [io.jsonwebtoken.impl.DefaultJwtBuilder] from the thread context, current, or system/application ClassLoaders. All heuristics have been exhausted. Class could …Run Code Online (Sandbox Code Playgroud) 好的,我在生成 JWT 时向有效负载添加了几个自定义声明,我可以在我的前端 (javascript) 中将它们拉出来就好了。然后我让我的 javascript 向一个微服务发送一个 ajax 调用,它连同它一起传递 JWT。我想从微服务中的 JWT 中获取我的自定义声明。我正在做以下事情:
Claims claims = Jwts.parser().setSigningKey(Vars.SECRET_KEY).parseClaimsJws(token).getBody();
User user = claims.get("customuser", User.class);
Run Code Online (Sandbox Code Playgroud)
它抛出一个异常。
io.jsonwebtoken.RequiredTypeException: Expected value to be of type: class net.netdatacorp.netdauth.model.User, but was class java.util.LinkedHashMap
at io.jsonwebtoken.impl.DefaultClaims.get(DefaultClaims.java:128)
Run Code Online (Sandbox Code Playgroud)
以下是我的自定义声明在前端 JWT 检查器中的数据显示方式。
{
jti: "83bffbad-7d36-4370-9332-21a84f2a3dce",
iat: 1498241526,
sub: "test",
iss: "www.test.net",
customuser: {
userId: 1,
userCd: "TMM",
firstNm: "Testy",
lastNm: "McTesty",
userNm: "test",
emailAddress: "jacob@test.net",
active: true,
createdDt: 1491355712000,
createdByUserId: 0,
lastUpdateDt: 1498199278000,
lastUpdateByUserId: 0,
lastLoginDt: 1484928016000
}
}
Run Code Online (Sandbox Code Playgroud)
我缺少什么才能拉出我的自定义声明?
我正在尝试创建一个与身份验证服务集成的网关服务。api-网关/pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.16.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.project</groupId>
<artifactId>api-gateway</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>api-gateway</name>
<description>Zuul Gateway</description>
<properties>
<java.version>11</java.version>
<spring-cloud.version>Hoxton.SR9</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Run Code Online (Sandbox Code Playgroud)
对于这个项目,我在构建路径中添加了一个名为“Common”的应用程序。常见应用程序中有 3 个文件。JwtAuthenticationConfig JwtTokenAuthenticationFilter JwtUsernamePasswordAuthenticationFilter 我的工作来源是这个 …
我在休息服务上使用 Spring Boot 和 Spring Security 以及 JWT。我使用了下面链接中的代码: https: //www.javainuse.com/spring/boot-jwt-mysql 它工作正常,但是当我们使用它的令牌进行身份验证时......我们面临以下错误:
io.jsonwebtoken.SignatureException: JWT signature does not match locally computed signature. JWT validity cannot be asserted and should not be trusted.
at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:354) ~[jjwt-0.9.1.jar:0.9.1]
at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:481) ~[jjwt-0.9.1.jar:0.9.1]
at io.jsonwebtoken.impl.DefaultJwtParser.parseClaimsJws(DefaultJwtParser.java:541) ~[jjwt-0.9.1.jar:0.9.1]
at com.isan.config.JwtTokenUtil.getAllClaimsFromToken(JwtTokenUtil.java:46) ~[classes/:na]
at com.isan.config.JwtTokenUtil.getClaimFromToken(JwtTokenUtil.java:41) ~[classes/:na]
at com.isan.config.JwtTokenUtil.getUsernameFromToken(JwtTokenUtil.java:32) ~[classes/:na]
at com.isan.config.JwtRequestFilter.doFilterInternal(JwtRequestFilter.java:44) ~[classes/:na]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.1.jar:5.3.1]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.4.1.jar:5.4.1]
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:103) ~[spring-security-web-5.4.1.jar:5.4.1]
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:89) ~[spring-security-web-5.4.1.jar:5.4.1]
Run Code Online (Sandbox Code Playgroud)
这些是代码:
1-WebSecurityConfig类:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint; …Run Code Online (Sandbox Code Playgroud) 我尝试按照本教程创建我的 JWT: https://developer.okta.com/blog/2018/10/31/jwts-with-java 但是当我将 SignatureAlgorithm 从 HS256 更改为 RS 256 时,我收到以下错误:
The signing key's algorithm 'SHA256withRSA' does not equal a valid HmacSHA* algorithm name and cannot be used with HS512.
这是负责 Jwt 的代码部分:
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.RS256;
byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(SECRET_KEY);
Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());
JwtBuilder builder = Jwts.builder().setId(id)
.setIssuedAt(now)
.setSubject(subject)
.setIssuer(issuer)
.signWith(signingKey);
Run Code Online (Sandbox Code Playgroud)
我使用的 SECRET_KEY 例如是:
-----BEGIN RSA PRIVATE KEY-----
MIICXgIBAAKBgQCtrKVnwse4anfX+JzM7imShXZUC+QBXQ11A5bOWwHFkXc4nTfE
Or3fJjnRSU5A3IROFU/pVVNiXJNkl7qQZK5mYb8j3NgqX8zZJG7IwLJ/Pm2sRW5Q
j32C/uJum64Q/iEIsCg/mJjDLh1lylEMEuzKgTdWtoeLfxDBL2AJ20qXzQIDAQAB
AoGBAKNXi0GpmjnCOPDxLFg5bvQVfhLSFCGMKQny1DVEtsfgZmbixv5R2R41T4+d
CHJMdEsUFFJ6I7CRLTcg1SDU8IhcAWCBRSNeVuomCHlQG16ti8HxwhiwIcjvDz/z
NC2sL5ZJ2eJnhbtXLdf6pxxO1pA5vLp1AX06IaETO977XvupAkEA+ZgtGZybyUkf
tEA3ekXc5eLoW+zgU0C1fATWcIZ8Iq5YV1BW+3oAzf8HgIbkQh4LM2qa6An3l+vW
NXR4wICHkwJBALIhrcdJqKw36qiyenq+m78klp5SnurQifVt0Sy1GMWyOUqYz5jK
t9sGo9Qn6GDuYe/XGXKWQW25PkEYXxxPPx8CQQCpICyvRidp5VrOURVGjUB5pZ+9
am02/In9V2nXJcnH1kuWHqJSFQGmlEEJHl5dTu5YEMyWnupezzd/UUThbDZxAkAz
TNO5QxNalbf04YG4e9Bq2eSur+iog2pXzkqhb3404UDypNOUkz0jzOO9o8ieschu
xCnGAFPTf7fYE2bAxmnNAkEA0/3bdsvJclquypqP9CQeQnxGwQtWz6+yn07gj3U1
V19mdeKCUZWklRarrcr67u9DdEx+JowyEY/ppzgeQtW01g==
-----END RSA PRIVATE KEY-----
Run Code Online (Sandbox Code Playgroud)
我的猜测是我签署的密钥错误......但我不确定我需要做什么......