linux下运行main函数OAuth验证遇到的签名问题的解决办法

最近做应用分享微博到新浪和腾讯的后台服务支撑的时候,发现一个问题,应用打成jar包的时候,部署到linux环境下,在请求腾讯https://open.t.qq.com/cgi-bin/request_token校验的时候后台服务抛出了SSLException:

java.lang.Exception: javax.net.ssl.SSLException: Server key
        at com.tencent.weibo.utils.QHttpClient.httpGet(QHttpClient.java:65)
        at com.tencent.weibo.utils.OAuthClient.requestToken(OAuthClient.java:50)
        at com.test.QQTest.requestToken(QQTest.java:37)
        at com.test.QQTest.main(QQTest.java:26)
Caused by: javax.net.ssl.SSLException: Server key
        at com.sun.net.ssl.internal.ssl.Handshaker.throwSSLException(Handshaker.java:850)
        at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:150)
        at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:516)
        at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:454)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:884)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1096)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:623)
        at com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.java:59)
        at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65)
        at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:123)
        at org.apache.commons.httpclient.HttpConnection.flushRequestOutputStream(HttpConnection.java:828)
        at org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:2116)
        at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:1096)
        at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:398)
        at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171)
        at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397)
        at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:323)
        at com.tencent.weibo.utils.QHttpClient.httpGet(QHttpClient.java:53)
        ... 3 more
Caused by: java.security.InvalidKeyException: No installed provider supports this key: sun.security.rsa.RSAPublicKeyImpl
        at java.security.Signature$Delegate.chooseProvider(Signature.java:1056)
        at java.security.Signature$Delegate.engineInitVerify(Signature.java:1088)
        at java.security.Signature.initVerify(Signature.java:420)
        at com.sun.net.ssl.internal.ssl.HandshakeMessage$DH_ServerKeyExchange.<init>(HandshakeMessage.java:773)
        at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:145)
        ... 19 more
Caused by: java.security.NoSuchAlgorithmException: NONEwithRSA Signature not available
        at java.security.Signature.getInstance(Signature.java:193)
        at com.sun.net.ssl.internal.ssl.JsseJce.getSignature(JsseJce.java:197)
        at com.sun.net.ssl.internal.ssl.RSASignature.<init>(RSASignature.java:45)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
        at java.lang.Class.newInstance0(Class.java:355)
        at java.lang.Class.newInstance(Class.java:308)
        at java.security.Provider$Service.newInstance(Provider.java:1221)
        at java.security.Signature$Delegate.newInstance(Signature.java:938)
        at java.security.Signature$Delegate.chooseProvider(Signature.java:1032)
        ... 23 more

但是将其打成war包部署到tomcat中时,向腾讯发起请求的话就会正常交互;(明明一个纯后台的东西,还得跑到tomcat下,很不爽...)

 

百度找到一个解决办法,将https://open.t.qq.com/cgi-bin/request_token该成http://open.t.qq.com/cgi-bin/request_token,不过这样就要修改腾讯SDK的源码了;

 

接着调试新浪的API接口,结果直接抛空指针异常:

Exception in thread "main" java.lang.NullPointerException
        at weibo4android.http.BASE64Encoder.encode(BASE64Encoder.java:46)
        at weibo4android.http.OAuth.generateSignature(OAuth.java:161)
        at weibo4android.http.OAuth.generateAuthorizationHeader(OAuth.java:85)
        at weibo4android.http.OAuth.generateAuthorizationHeader(OAuth.java:125)
        at weibo4android.http.HttpClient.setHeaders(HttpClient.java:715)
        at weibo4android.http.HttpClient.httpRequest(HttpClient.java:607)
        at weibo4android.http.HttpClient.httpRequest(HttpClient.java:591)
        at weibo4android.http.HttpClient.getOauthRequestToken(HttpClient.java:166)
        at weibo4android.Weibo.getOAuthRequestToken(Weibo.java:1567)
        at com.test.SinaTest.requestToken(SinaTest.java:57)
        at com.test.SinaTest.main(SinaTest.java:34)

 

查看其SDK源码,发现at weibo4android.http.OAuth.generateSignature(OAuth.java:161)时

执行Mac mac = Mac.getInstance(HMAC_SHA1);的时候直接抛出异常了,其竟然没做任何处理...

} catch (NoSuchAlgorithmException ignore) {
            // should never happen
        }

将异常打印出来发现:

java.security.NoSuchAlgorithmException: Algorithm HmacSHA1 not available
        at javax.crypto.Mac.getInstance(DashoA13*..)
        at weibo4android.http.OAuth.generateSignature(OAuth.java:139)
        at weibo4android.http.OAuth.generateAuthorizationHeader(OAuth.java:85)
        at weibo4android.http.OAuth.generateAuthorizationHeader(OAuth.java:125)
        at weibo4android.http.HttpClient.setHeaders(HttpClient.java:715)
        at weibo4android.http.HttpClient.httpRequest(HttpClient.java:607)
        at weibo4android.http.HttpClient.httpRequest(HttpClient.java:591)
        at weibo4android.http.HttpClient.getOauthRequestToken(HttpClient.java:166)
        at weibo4android.Weibo.getOAuthRequestToken(Weibo.java:1567)
        at com.test.SinaTest.requestToken(SinaTest.java:57)
        at com.test.SinaTest.main(SinaTest.java:34)

 

继续百度,找到一个参考资料http://stackoverflow.com/questions/2856248/nosuchalgorithmexception-algorithm-hmacsha1-not-available

照着做,在sinaSDK源码Mac mac = Mac.getInstance(HMAC_SHA1);前加入

java.security.Security.addProvider(new com.sun.crypto.provider.SunJCE());

然后将sunjce_provider.jar 考到lib下,sunjce_provider.jar 原来位于 $JAVA_HOME/jre/lib/ext 下;

然后执行,ok,没问题了~~

 

思考~~~why??继续咬牙看上面的参考资料http://stackoverflow.com/questions/2856248/nosuchalgorithmexception-algorithm-hmacsha1-not-available里面的回答;

回答的哥们说可能是$JAVA_HOME/jre/lib、security/java.security 中不包含SunJCE的设置,所以需要在代码中添加

 

java.security.Security.addProvider(new com.sun.crypto.provider.SunJCE());

然后又找到一个资料http://chenjianjx.iteye.com/blog/738285

可是我的java.security 中明明包含了security.provider.4=com.sun.crypto.provider.SunJCE

难道是因为找不到sunjce_provider.jar,即时配置了也不管用的原因?

于是乎,全部代码还原,全部SDK代码还原,只是在lib中添加了sunjce_provider.jar,发现所有问题都解决了~~

腾讯API的SSLException也没问题了~~

 

ok,说了这么多,就是因为缺少sunjce_provider.jar的原因,不知道为什么在tomcat中跑时没问题,难道是tomcat启动的时候加载了~~

 

继续找资料,$JAVA_HOME/jre/lib/ext 中的jar包会在jvm启动的时候自动加载,可是为什么sunjce_provider.jar没有加载?难道是什么时候跳过了$JAVA_HOME/jre/lib/ext 的加载?

看了一下,启动的命令...jre/bin/java -Xms256m -Xmx512m -Dlabel=temp -Djava.ext.dirs=../lib/ com.test.SinaTest &

 

ok,现在清楚了,在启动的时候将ext.dirs设成了=../lib/,这个时候自然不会继续加载了~~

(为什么要这样写呢,因为之前某个哥们在lib下放了需要手动改的配置文件~~)

 

 

### 回答1: OAuth2.0是一种授权框架,允许用户授权第三方应用程序代表用户访问受保护的资源,而无需将用户的凭据(例如用户名和密码)直接提供给第三方应用程序。这可以增强用户的安全性,并使用户能够更好地控制他们的数据。 OAuth2.0的主要问题之一是在实施过程中可能存在安全漏洞。例如,如果实施不当,攻击者可能会使用OAuth2.0流程来获取对用户帐户的未经授权访问。此外,还可能出现其他问题,例如:对用户数据的不透明处理和管理,访问令牌的不正确存储和管理,以及对OAuth2.0协议本身的误解和不正确的使用等等。 为了解决这些问题,需要合理设计和实施OAuth2.0协议,并使用最佳实践和安全措施来保护用户数据和隐私。 ### 回答2: OAuth2.0是一种授权框架,旨在解决互联网应用程序中的身份验证和授权问题。它的主要目标是使用户能够在不直接分享他们的用户名和密码的情况下,授予第三方应用程序对其受保护资源的有限访问权限。 传统的身份验证模式要求用户向每个应用程序提供自己的用户名和密码。这种做法存在多个问题。首先,用户可能不希望将他们的凭据共享给每个应用程序,尤其是对于不太可信的应用程序。其次,这种模式对于需要与多个应用程序进行交互的用户来说非常麻烦,因为他们必须为每个应用程序记住不同的用户名和密码。 OAuth2.0通过引入授权服务器来解决这些问题。当用户尝试访问第三方应用程序时,它会要求用户给予授权。然后,该应用程序将重定向用户到授权服务器,用户在此之前需要进行登录验证。一旦用户成功登录,授权服务器会要求用户确认他们是否同意授予第三方应用程序访问受保护资源的权限。如果用户同意,授权服务器将向第三方应用程序颁发一个访问令牌。 第三方应用程序可以使用此访问令牌来请求授权服务器中的资源,前提是用户已授予相应的访问权限。这样,第三方应用程序就能够访问用户的受保护资源,而无需直接使用用户的用户名和密码。 通过OAuth2.0,用户拥有更多的控制权和安全性,因为他们可以选择哪些应用程序可以访问他们的数据,以及可以授予给这些应用程序的权限级别。此外,OAuth2.0还提供了一套标准化的协议和工具,使开发人员能够轻松地为他们的应用程序实现授权功能。 总之,OAuth2.0通过解决身份验证和授权问题,提供了一种安全、可靠的机制,使用户能够授予第三方应用程序对其受保护资源的有限访问权限,同时为开发人员简化了授权功能的实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值