我们在分布式架构中实现了WSO2 API Manager(v1.10.0),如在线文档here中所述 .
这包括以下内容(在5个独立的服务器上):
-
网关(x2)
-
Publisher&Store(在一台服务器上)
-
密钥管理器(x2)
它们连接到SQL Server 2014实例上的3个普通API Manager数据库(注册表,用户管理器和API管理器) .
我们使用密钥管理器进行网站用户的身份验证(登录,忘记密码等),以及验证API调用 .
但是,当尝试登录到站点时,我在密钥管理器上看到以下内容(违反UNIQUE KEY约束)错误:
TID:[ - 1] [] [2016-10-06 00:36:47,842] ERROR - 持久访问令牌时出错:c5a0a11e63388dCHANGEDea34b0533445 org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception:fpA6AhOfbVCHANGEDgH0WzBDOga在org.wso2.carbon.identity.oauth2.dao.TokenMgtDAO.storeAccessToken:当存储为消费者密钥访问令牌错误(TokenMgtDAO.java:246)在org.wso2.carbon.identity.oauth2.dao.TokenMgtDAO.persistAccessToken(TokenMgtDAO.java:284)在org.wso2.carbon.identity.oauth2.dao.TokenPersistenceTask.run(TokenPersistenceTask.java :52)at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)at java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:615)at java.lang.Thread.run(Thread . java:745)引起:com.microsoft.sqlserver.jdbc.SQLServerException:违反UNIQUE KEY约束'CON_APP_KEY' . 无法在对象'dbo.IDN_OAUTH2_ACCESS_TOKEN'中插入重复键 . 重复键值为(15,williams.j2 @ CHANGED.org.uk,-1234,,APPLICATION_USER,369db21a386ae4CHANGED0ff34d35708d,ACTIVE,NONE) . 在com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:216)在com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1515)在com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement (SQLServerPreparedStatement.java:404)在com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement $ PrepStmtExecCmd.doExecute(SQLServerPreparedStatement.java:350)在com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:5696)在COM . microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:1715)在com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(SQLServerStatement.java:180)在com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement . java:155)在com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.execute(SQLServerPreparedStatement.java:332)at org.wso2.carbon.identity.oauth2.dao.TokenMgtDAO.storeAccessToken(TokenMgtDAO.java:224)...还有5个
这导致网站上出现以下.NET错误:
我试过谷歌搜索,但无法找到最新的答案 .
我没有将密钥管理器配置为具有主节点和工作节点(如here所述),因为文档似乎表明这不是必需的 .
任何帮助将非常感谢请!
3 回答
经过一番调试发现问题!在我们放置此配置之前,
APIM可以将多个ACTIVE OAUTH令牌保存到IDN_OAUTH2_ACCESS_TOKEN表以进行单个令牌获取调用 .
当令牌验证 endpoints 查询令牌时,仅返回最后一个(使用基于时间的排序和限制) . 当那个过期时,令牌验证会将其标记为非活动状态 . 但前一个保持不变 .
刷新令牌发生时,会检查最新令牌是否处于非活动状态 . 由于它处于非活动状态,因此会发出新令牌 . 但是当令牌 endpoints 尝试持久化令牌时,还有另一个ACTIVE令牌 . 这导致了这个例外 .
要对此进行排序,我们可以在IDN_OAUTH2_ACCESS_TOKEN表上运行更新查询,以将所有ACTIVE标记标记为INACTIVE .
然后旧的错误令牌将被删除,服务器将开始正常工作!
我使用mysql并面临同样的问题 . 更改池大小也不是完整的解决方案 . 然后我注意到idn_oauth2_access_token表有些奇怪 . 列time_created,但内容不是创建的时间 . 这是最后一次更新时间戳 . 我在time_created列中的几列上读取系统命令 . 我检查了我的sql脚本,发现更新被触发时数据库更新了这个列 . 我删除了这个规则,我没有更多的错误 .
你可以在
<APIM_HOME>/repository/conf/identity.xml
中更改以下配置(<PoolSize>0</PoolSize>
),看看?默认情况下,PoolSize设置为100 .希望这将解决您的问题 .
参考:http://sanjeewamalalgoda.blogspot.com/2015/08/how-to-avoid-getting-incorrect-access.html