WSO2IS JWT 访问令牌
WSO2IS JWT access token
我正在尝试从 WSO2 IS 获取 JWT 访问令牌。我遵循了 msf4j Oauth2 Security Sample, and managed to get a JWT acces token by resource owner password 资助类型的说明。
但我在外部验证令牌时遇到问题。
似乎令牌没有被默认签名 "wso2carbon.jks"。
此外,我在 "service providers" 中的声明配置未反映在 jwt 内容中
所以我的问题是:如何在 WSO2IS 中配置 JWT 签名证书?
还有:
如何操纵 JWT 中的声明?
出于性能方面的考虑,我不想转向 "introspect" 端点,我的策略是只信任 IS,只是为了确保(本地)JWT 令牌的真实性
请指教
谢谢
您可以按照 [1] 使用 WSO2 身份服务器获取 JWT 访问令牌(自包含访问令牌)
嗯,看来是我自己的错。
我一直在使用 jose4j JWT 包,并不断收到验证失败的消息。
进一步检查 msf4j implementation, I switched over to nimbus-jose-jwt JWT 包并完成后,
以下是我的实现。
import com.nimbusds.jose.JWSVerifier;
import com.nimbusds.jose.crypto.RSASSAVerifier;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.SignedJWT;
public class JwtParser {
private static final String KEYSTORE = System.getProperty("javax.net.ssl.trustStore");
private static final String KEYSTORE_PASSWORD = System.getProperty("javax.net.ssl.trustStorePassword");
private static Map<String, JWSVerifier> verifiers = getVerifiers();
public static JWTClaimsSet verify(String jwt) throws Exception {
SignedJWT signedJWT = SignedJWT.parse(jwt);
if (!new Date().before(signedJWT.getJWTClaimsSet().getExpirationTime())) {
new Exception("token has expired");
}
boolean notYet = true;
for(Iterator<JWSVerifier> it = verifiers.values().iterator(); notYet && it.hasNext();){
JWSVerifier verifier = it.next();
notYet = !signedJWT.verify(verifier);
}
if(notYet){
throw new Exception("token verification failed");
}
JWTClaimsSet claims = signedJWT.getJWTClaimsSet();
if (claims == null) {
// Do something with claims
throw new Exception("non valid payload in token, failed");
}
return claims;
}
private static Map<String, JWSVerifier> getVerifiers(){
Map<String, JWSVerifier> verifiers = new HashMap<>();
try (InputStream inputStream = new FileInputStream(KEYSTORE)) {
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
keystore.load(inputStream, KEYSTORE_PASSWORD.toCharArray());
Enumeration<String> aliases = keystore.aliases();
while(aliases.hasMoreElements()){
String alias = aliases.nextElement();
if(!keystore.isCertificateEntry(alias)){
continue;
}
Certificate cert = keystore.getCertificate(alias);
if(cert == null){
continue;
}
PublicKey key = cert.getPublicKey();
verifiers.put(alias, new RSASSAVerifier((RSAPublicKey)key));
}
}catch(KeyStoreException | CertificateException | NoSuchAlgorithmException | IOException e){
//TODO: report the exception
}
return verifiers;
}
}
我正在尝试从 WSO2 IS 获取 JWT 访问令牌。我遵循了 msf4j Oauth2 Security Sample, and managed to get a JWT acces token by resource owner password 资助类型的说明。 但我在外部验证令牌时遇到问题。
似乎令牌没有被默认签名 "wso2carbon.jks"。
此外,我在 "service providers" 中的声明配置未反映在 jwt 内容中
所以我的问题是:如何在 WSO2IS 中配置 JWT 签名证书?
还有: 如何操纵 JWT 中的声明?
出于性能方面的考虑,我不想转向 "introspect" 端点,我的策略是只信任 IS,只是为了确保(本地)JWT 令牌的真实性
请指教
谢谢
您可以按照 [1] 使用 WSO2 身份服务器获取 JWT 访问令牌(自包含访问令牌)
嗯,看来是我自己的错。
我一直在使用 jose4j JWT 包,并不断收到验证失败的消息。
进一步检查 msf4j implementation, I switched over to nimbus-jose-jwt JWT 包并完成后,
以下是我的实现。
import com.nimbusds.jose.JWSVerifier;
import com.nimbusds.jose.crypto.RSASSAVerifier;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.SignedJWT;
public class JwtParser {
private static final String KEYSTORE = System.getProperty("javax.net.ssl.trustStore");
private static final String KEYSTORE_PASSWORD = System.getProperty("javax.net.ssl.trustStorePassword");
private static Map<String, JWSVerifier> verifiers = getVerifiers();
public static JWTClaimsSet verify(String jwt) throws Exception {
SignedJWT signedJWT = SignedJWT.parse(jwt);
if (!new Date().before(signedJWT.getJWTClaimsSet().getExpirationTime())) {
new Exception("token has expired");
}
boolean notYet = true;
for(Iterator<JWSVerifier> it = verifiers.values().iterator(); notYet && it.hasNext();){
JWSVerifier verifier = it.next();
notYet = !signedJWT.verify(verifier);
}
if(notYet){
throw new Exception("token verification failed");
}
JWTClaimsSet claims = signedJWT.getJWTClaimsSet();
if (claims == null) {
// Do something with claims
throw new Exception("non valid payload in token, failed");
}
return claims;
}
private static Map<String, JWSVerifier> getVerifiers(){
Map<String, JWSVerifier> verifiers = new HashMap<>();
try (InputStream inputStream = new FileInputStream(KEYSTORE)) {
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
keystore.load(inputStream, KEYSTORE_PASSWORD.toCharArray());
Enumeration<String> aliases = keystore.aliases();
while(aliases.hasMoreElements()){
String alias = aliases.nextElement();
if(!keystore.isCertificateEntry(alias)){
continue;
}
Certificate cert = keystore.getCertificate(alias);
if(cert == null){
continue;
}
PublicKey key = cert.getPublicKey();
verifiers.put(alias, new RSASSAVerifier((RSAPublicKey)key));
}
}catch(KeyStoreException | CertificateException | NoSuchAlgorithmException | IOException e){
//TODO: report the exception
}
return verifiers;
}
}