我正在尝试验证在AD服务器上成功用户授权后收到的RS256令牌。
我正在查看响应的id_token属性值。
这就是我所拥有的 -
String[] split_string = idToken.split("\\.");
String base64EncodedHeader = split_string[0];
String base64EncodedBody = split_string[1];
String base64EncodedSignature = split_string[2];
Base64 base64Url = new Base64(true);
String header = new String(base64Url.decode(base64EncodedHeader));
JSONObject jsonObjHeader = JSONObject.fromObject(header);
String body = new String(base64Url.decode(base64EncodedBody));
JSONObject jsonObjBody = JSONObject.fromObject(body);
String signatre = new String(base64Url.decode(base64EncodedSignature));
//kid for signature validation
String kid = jsonObjHeader.getString("kid");
//open-id-config endpoint
String openIdConfigEndPoint = "https://login.microsoftonline.com/{tenantID}/.well-known/openid-configuration";
OAuthRequest requestOpenId = constructOAuthRequest(
openIdConfigEndPoint, oauthNonce, oauthTimestamp, Verb.GET);
Response responseOpenId = requestOpenId.send();
String openIdString = responseOpenId.getBody();
JSONObject jsonObjopenId = JSONObject.fromObject(openIdString);
String keysEndPoint = jsonObjopenId.getString("jwks_uri");
OAuthRequest requestkeysEndPoint = constructOAuthRequest(keysEndPoint,
oauthNonce, oauthTimestamp, Verb.GET);
Response responsekeysEndPoint = requestkeysEndPoint.send();
String keysEndPointString = responsekeysEndPoint.getBody();
JSONObject jsonKeysEndPointString = JSONObject.fromObject(keysEndPointString);
JSONArray keysEndPointArray = jsonKeysEndPointString.getJSONArray("keys");
String x5t = null;
String n = null;
String e = null;
for (int i = 0; i < keysEndPointArray.size(); i++) {
JSONObject obj1 = keysEndPointArray.getJSONObject(i);
if (obj1.getString("kid").equals(kid)) {
n = obj1.getString("n");
e = obj1.getString("e");
x5t = obj1.getString("x5t");
}
}
byte[] modulusBytes = Base64.decodeBase64(n.getBytes("UTF-8"));
byte[] exponentBytes = Base64.decodeBase64(e.getBytes("UTF-8"));
BigInteger modulusInt = new BigInteger(1, modulusBytes);
BigInteger exponentInt = new BigInteger(1, exponentBytes);
try {
Signature signature = Signature.getInstance("SHA256withRSA");
RSAPublicKeySpec publicSpec = new RSAPublicKeySpec(modulusInt, exponentInt);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey pubKey = keyFactory.generatePublic(publicSpec);
signature.initVerify(pubKey);
signature.update(base64Url.decode(base64EncodedBody));
boolean isVerified = signature.verify(base64Url .decode(base64EncodedSignature));
// isVerified is false , should be true on successful validation
} catch (Exception ex) {
ex.printStackTrace();
}
//trying with JJWT
try {
KeyFactory factory = KeyFactory.getInstance("RSA");
PublicKey pub = factory.generatePublic(publicSpec);
Jwt<Header, String> c = Jwts.parser().setSigningKey(pub).parsePlaintextJwt(idToken);
System.out.println();
} catch (Exception e1) {
e1.printStackTrace();
}
这是我得到的例外 -
io.jsonwebtoken.SignatureException: Unable to verify RSA signature using configured PublicKey. Signature length not correct: got 255 but was expecting 256
at io.jsonwebtoken.impl.crypto.RsaSignatureValidator.isValid(RsaSignatureValidator.java:50)
at io.jsonwebtoken.impl.crypto.DefaultJwtSignatureValidator.isValid(DefaultJwtSignatureValidator.java:47)
at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:339)
at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:458)
at io.jsonwebtoken.impl.DefaultJwtParser.parsePlaintextJwt(DefaultJwtParser.java:480)
at edu.umn.faip.web.spring.controller.OAuthSSOTestController.referenceData(OAuthSSOTestController.java:221)
at org.springframework.web.servlet.mvc.SimpleFormController.referenceData(SimpleFormController.java:214)
at org.springframework.web.servlet.mvc.AbstractFormController.showForm(AbstractFormController.java:574)
at org.springframework.web.servlet.mvc.SimpleFormController.showForm(SimpleFormController.java:198)
at org.springframework.web.servlet.mvc.SimpleFormController.showForm(SimpleFormController.java:175)
at org.springframework.web.servlet.mvc.AbstractFormController.showNewForm(AbstractFormController.java:338)
at org.springframework.web.servlet.mvc.AbstractFormController.handleRequestInternal(AbstractFormController.java:278)
at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:153)
at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:875)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:807)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:571)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:501)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.security.SignatureException: Signature length not correct: got 255 but was expecting 256
at sun.security.rsa.RSASignature.engineVerify(Unknown Source)
at java.security.Signature$Delegate.engineVerify(Unknown Source)
at java.security.Signature.verify(Unknown Source)
at io.jsonwebtoken.impl.crypto.RsaSignatureValidator.doVerify(RsaSignatureValidator.java:63)
at io.jsonwebtoken.impl.crypto.RsaSignatureValidator.isValid(RsaSignatureValidator.java:47)
... 38 more
我尝试过使用jjwt库,但这似乎也不起作用。我试图从端点上发布的公钥中获取模数和指数,以在java中构建我自己的密钥对象,然后使用它来验证签名。
非常感谢任何帮助!
答案 0 :(得分:0)
您可以尝试
signature.update((split_string[0]+ "." +
split_string[0]).getBytes(StandardCharsets.UTF_8));
OpenID Connect - how to verify id token in Java?
您可以参考此链接。它对我有用。