2017-01-05 15 views
2

Azure ADトークン署名の検証に苦労しています。Azure ADトークン署名の検証に失敗するJAVA

私は

https://login.microsoftonline.com/common/.well-known/openid-configuration

の下に「jwks_uri」フィールドに正しいキーの記述を見ると、私が属するキーデータを確認してください。

私は「N」を使用してみてください - 私はエラーで終わる署名検証用の公開鍵を生成するための係数および「e」のフィールドを:

BASE64Decoder decoder = new BASE64Decoder();   
byte[] modulusBytes = decoder.decodeBuffer(n); 
byte[] exponentBytes = decoder.decodeBuffer(e); 

BigInteger modulusInt = new BigInteger(1, modulusBytes); 
BigInteger exponentInt = new BigInteger(1, exponentBytes); 

try { 
    KeyFactory keyFactory = KeyFactory.getInstance("RSA"); 
    RSAPublicKeySpec publicSpec = new RSAPublicKeySpec(modulusInt, exponentInt); 
RSAPublicKey pubKey = (RSAPublicKey)keyFactory.generatePublic(publicSpec); 
Jwt<Header, String> c = Jwts.parser().setSigningKey(pubKey).parsePlaintextJwt(token); 

} catch (Exception ex) { 
    ex.printStackTrace(); 
} 

コンソール:

io.jsonwebtoken.SignatureException: Unable to verify RSA signature using configured PublicKey. Signature length not correct: got 256 but was expecting 246 
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:351) 
at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:481) 
at io.jsonwebtoken.impl.DefaultJwtParser.parsePlaintextJwt(DefaultJwtParser.java:503) 
at com.ge.hc.pfh.poc.ams.filter.JwtFilter.doFilter(JwtFilter.java:120) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) 
at com.ge.hc.pfh.poc.ams.filter.ApiOriginFIlter.doFilter(ApiOriginFIlter.java:28) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) 
at com.ge.hc.pfh.poc.ams.filter.MDCFilter.doFilter(MDCFilter.java:34) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) 
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) 
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:89) 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) 
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) 
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) 
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) 
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:108) 
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) 
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) 
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) 
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) 
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349) 
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:784) 
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) 
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:802) 
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1410) 
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 
at java.lang.Thread.run(Thread.java:745) 

Iはベース64符号化された証明書チェーンで出願された「x5c」を使用する別のアプローチを試みた:

byte[] certChain = Base64.getDecoder().decode(x5c); 
X509Certificate cert = X509CertUtils.parse(certChain); 
PublicKey pubKeyNew = cert.getPublicKey(); 
Claims claims3 = Jwts.parser() 
      .setSigningKey(pubKeyNew) 
      .parseClaimsJws(token).getBody(); 

Iが終わります他のエラー:

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) 
at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:481) 
at io.jsonwebtoken.impl.DefaultJwtParser.parsePlaintextJwt(DefaultJwtParser.java:503) 
at com.ge.hc.pfh.poc.ams.filter.JwtFilter.doFilter(JwtFilter.java:106) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) 
at com.ge.hc.pfh.poc.ams.filter.ApiOriginFIlter.doFilter(ApiOriginFIlter.java:28) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) 
at com.ge.hc.pfh.poc.ams.filter.MDCFilter.doFilter(MDCFilter.java:34) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) 
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) 
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:89) 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) 
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) 
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) 
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) 
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:108) 
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) 
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) 
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) 
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) 
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349) 
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:784) 
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) 
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:802) 
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1410) 
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 
at java.lang.Thread.run(Thread.java:745) 

私が間違っていることを知っている人はいますか?おかげさまで https://login.microsoftonline.com/common/discovery/keys

+0

ここでマイクロソフトが正式に推奨するライブラリに記載されているADALライブラリを試してみましたか:https://docs.microsoft.com/en-us/azure/active-directory/active-directory-authentication-libraries –

答えて

2

まず例

モジュラスおよび指数(ne)はbase64base64urlずにエンコードされているので、それらをデコードするためのコードが

byte[] modulusBytes = Base64.getUrlDecoder().decode(n); 
BigInteger modulusInt = new BigInteger(1, modulusBytes); 

である必要があり、古い使用しないでください。 com.sun.misc.BASE64Decoder

JWTに署名した場合は、JWTParser.plaintextJwt()documentation

plaintextJwt: a compact serialized unsigned plaintext JWT string

によると、代わりにparseClaimsJwsまたはparsePlaintextJwsを使用してください。ペイロードは、文字列非JSON

第二の例

第2の例である場合にのみ、第二の方法は、基本的権利です。私はX509CertUtils.parse(certChain)

InputStream in = new ByteArrayInputStream(certChain); 
CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); 
X509Certificate cert = (X509Certificate)certFactory.generateCertificate(in); 

モジュラスと同様のものであり、証明書の指数は、デコードされたのと同じで、その公開鍵はリンク内の2つの類似の証明書があります

相当していると仮定し、両方を確認してください。署名を検証することができるはずです。そうでない場合は、トークンはこれらのキーで署名されていません

+0

あなたは正しいです、2番目のアプローチは正しいです。問題は、azureがid_tokenとアクセストークンを返したことです。検証はid_tokenでうまくいき、アクセストークンで失敗します。ドキュメントにはhttps://docs.microsoft.comに記載されているとおりです。com/ja/azure/active-directory/active-directory-v2-tokens: "v2.0エンドポイントによって発行された[...]アクセストークンは、Microsoftサービスでのみ使用できます。任意の検証[...]を実行する。 "現在、アプリケーションで実行する必要がある唯一のトークン検証は、IDトークンの検証です。" – HDCase

関連する問題