我正在使用 Openid4Java 在 GAE 上为我的应用程序实现 Openid。我也在使用 Shiro 来保证安全。在我达到凭据匹配失败的前一天,即发现、提出身份验证请求、获取claim_id 都在工作。昨天所有的地狱都失败了,从那时起在谷歌上的发现就失败了。我已经验证的事情:
- 雅虎工作正常(端到端)并且
- 谷歌的发现在我的本地开发盒上运行良好(返回到我的本地主机 URL 时它当然会失败)。
- appengine 上的应用程序已启用计费,以便在内部 Yadis 可以打开套接字连接。
我已经为 Google 尝试了以下发现网址:(下面的一些网址有空格,因为我不能发布超过 2 个链接)。否则他们很好。
- https://www.google.com/accounts/o8/id
- https://www.google.com/accounts/o8/ud ( https://developers.google.com/accounts/docs/OpenID?hl=es-ES#endpoint )
堆栈跟踪之前的一些有趣的日志:
org.openid4java.discovery.Discovery discover: Starting discovery on URL identifier: https: //www.google.com/accounts/o8/id
org.openid4java.discovery.yadis.YadisResolver retrieveXrdsLocation: Performing HTTP HEAD on: https://www.google.com/accounts/o8/id ...
org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager$1 getConnection: Get connection: {s}->https://www.google.com, timeout = 3000
org.apache.http.impl.conn.tsccm.ConnPoolByRoute getEntryBlocking: [{s}->https://www.google.com] total kept alive: 0, total issued: 0, total allocated: 0 out of 20
org.apache.http.impl.conn.tsccm.ConnPoolByRoute getFreeEntry: No free connections [{s}->https://www.google.com][null]
org.apache.http.impl.conn.tsccm.ConnPoolByRoute getEntryBlocking: Available capacity: 2 out of 2 [{s}->https://www.google.com][null]
org.apache.http.impl.conn.tsccm.ConnPoolByRoute createEntry: Creating new connection [{s}->https://www.google.com]
org.apache.http.impl.conn.DefaultClientConnectionOperator openConnection: Connecting to www.google.com:443
org.apache.http.impl.conn.DefaultClientConnection close: Connection org.apache.http.impl.conn.DefaultClientConnection@197d562 closed
堆栈跟踪如下:
org.apache.shiro.openid4j.DiscoveryException: Unable to discover OpenId Provider based on resolved discoveryId 'https://www.google.com/accounts/o8/id' (specified providerId 'null')
at org.apache.shiro.openid4j.DefaultOpenIdService.getDiscoveryInfo(DefaultOpenIdService.java:182)
at org.apache.shiro.openid4j.DefaultOpenIdService.constructRequestFromOpenIdUrl(DefaultOpenIdService.java:123)
at org.apache.shiro.openid4j.authc.Open4jFilter.constructOpenIdRequest(Open4jFilter.java:344)
at org.apache.shiro.openid4j.authc.Open4jFilter.executeOpenidLogin(Open4jFilter.java:327)
at org.apache.shiro.openid4j.authc.Open4jFilter.onAccessDenied(Open4jFilter.java:304)
at org.apache.shiro.web.filter.AccessControlFilter.onAccessDenied(AccessControlFilter.java:133)
at org.apache.shiro.web.filter.AccessControlFilter.onPreHandle(AccessControlFilter.java:162)
at org.apache.shiro.web.filter.PathMatchingFilter.isFilterChainContinued(PathMatchingFilter.java:203)
at org.apache.shiro.web.filter.PathMatchingFilter.preHandle(PathMatchingFilter.java:178)
at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:131)
at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66)
at org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:449)
at org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365)
at org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
at org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)
at org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:383)
at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362)
at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.apphosting.utils.servlet.ParseBlobUploadFilter.doFilter(ParseBlobUploadFilter.java:125)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.apphosting.runtime.jetty.SaveSessionFilter.doFilter(SaveSessionFilter.java:35)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.apphosting.utils.servlet.JdbcMySqlConnectionCleanupFilter.doFilter(JdbcMySqlConnectionCleanupFilter.java:60)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
at com.google.apphosting.runtime.jetty.AppVersionHandlerMap.handle(AppVersionHandlerMap.java:266)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:326)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:923)
at com.google.apphosting.runtime.jetty.RpcRequestParser.parseAvailable(RpcRequestParser.java:76)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
at com.google.apphosting.runtime.jetty.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:146)
at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.run(JavaRuntime.java:446)
at com.google.tracing.TraceContext$TraceContextRunnable.runInContext(TraceContext.java:435)
at com.google.tracing.TraceContext$TraceContextRunnable$1.run(TraceContext.java:442)
at com.google.tracing.CurrentContext.runInContext(CurrentContext.java:186)
at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContextNoUnref(TraceContext.java:306)
at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContext(TraceContext.java:298)
at com.google.tracing.TraceContext$TraceContextRunnable.run(TraceContext.java:439)
at com.google.apphosting.runtime.ThreadGroupPool$PoolEntry.run(ThreadGroupPool.java:251)
at java.lang.Thread.run(Thread.java:724)
Caused by: org.openid4java.discovery.yadis.YadisException: 0x704: I/O transport error: Permission denied: Attempt to access a blocked recipient without permission. (mapped-IPv4)
at org.openid4java.discovery.yadis.YadisResolver.retrieveXrdsLocation(YadisResolver.java:479)
at org.openid4java.discovery.yadis.YadisResolver.discover(YadisResolver.java:249)
at org.openid4java.discovery.yadis.YadisResolver.discover(YadisResolver.java:233)
at org.openid4java.discovery.yadis.YadisResolver.discover(YadisResolver.java:167)
at org.openid4java.discovery.Discovery.discover(Discovery.java:147)
at org.openid4java.discovery.Discovery.discover(Discovery.java:129)
at org.openid4java.consumer.ConsumerManager.discover(ConsumerManager.java:568)
at org.apache.shiro.openid4j.DefaultOpenIdService.getDiscoveryInfo(DefaultOpenIdService.java:178)
... 49 more
Caused by: java.net.SocketException: Permission denied: Attempt to access a blocked recipient without permission. (mapped-IPv4)
at com.google.appengine.api.socket.SocketApiHelper.translateError(SocketApiHelper.java:107)
at com.google.appengine.api.socket.SocketApiHelper.translateError(SocketApiHelper.java:118)
at com.google.appengine.api.socket.SocketApiHelper.makeSyncCall(SocketApiHelper.java:82)
at com.google.appengine.api.socket.AppEngineSocketImpl.connectSocket(AppEngineSocketImpl.java:421)
at com.google.appengine.api.socket.AppEngineSocketImpl.connectToAddress(AppEngineSocketImpl.java:366)
at com.google.appengine.api.socket.AppEngineSocketImpl.connect(AppEngineSocketImpl.java:352)
at java.net.Socket.connect(Socket.java:600)
at sun.security.ssl.SSLSocketImpl.connect(SSLSocketImpl.java:623)
at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:549)
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:180)
at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:151)
at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:125)
at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:645)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:480)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:906)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:805)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:784)
at org.openid4java.util.HttpCache.head(HttpCache.java:336)
at org.openid4java.discovery.yadis.YadisResolver.retrieveXrdsLocation(YadisResolver.java:401)
... 56 more
依赖方代码与 SampleConsumer(openid4java 的一部分)非常相似,但实际上是 shiro(openid4j) 上的一个补丁。它似乎符合 Sample Consumer 的要求。
在我看来,我在这里缺少一些基本的东西。任何指针都会有帮助。