在我的Rails 3.1.5应用程序中,我使用ims-lti gem来执行第三方身份验证。要执行身份验证,必须完成三件事:
前两个已完成,但我在使用随机数检查时遇到问题。我发现的大多数问题都涉及在Rails中生成nonces,而不是检查它们。
有几个相关问题使用oauth-plugin gem来检查现时:
Rails oauth-plugin: multiple strategies causes duplicate nonce error
OAuth signature verification fails
return false unless OauthNonce.remember(nonce, timestamp)
不幸的是,oauth-plugin gem自2013年以来一直没有更新,并且与ims-lti gem所需的oauth gem版本不兼容。
oauth gem似乎不支持验证nonce。
是否有一种固定的方法可以检查nonce,无论是在原生Rails还是通过gem,或者我降级为:
答案 0 :(得分:0)
这是我最终做的事情。
创建一个数据库表来存储nonce值:
<强> /db/migrate/<timestamp>_create_oauth_nonces.rb 强>
class CreateOauthNonces < ActiveRecord::Migration
def change
create_table :oauth_nonces do |t|
t.string :nonce
t.timestamp :timestamp
end
add_index :oauth_nonces, :nonce
add_index :oauth_nonces, :timestamp
end
end
由于nonce是短暂的,因此在不再需要它们之后应该删除它们。 Sidekiq和Redis gems可用于异步执行nonce删除:
<强> /app/workers/oauth_nonces_worker.rb 强>
class OauthNoncesWorker
include Sidekiq::Worker
def perform(nonce_id)
OauthNonces.find(nonce_id).delete
end
end
在会话控制器中,执行随机数处理 - 检查请求是否已过期,然后检查nonce值,如果通过,则将nonce删除队列:
<强> sessions_controller.rb 强>
request_timestamp = DateTime.strptime(params[:oauth_timestamp], '%s')
nonce_expiry_time = 5.minutes
if request_timestamp < nonce_expiry_time.ago
# Handle expired request here
end
nonce_exists = OauthNonces.find_by_nonce(params[:oauth_nonce])
if nonce_exists
# Handle re-used nonce here
end
# Store the new nonce in the nonces table
nonce = OauthNonces.create!({ nonce: params[:oauth_nonce], timestamp: timestamp }, without_protection: true)
# Use Sidekiq and Redis to queue the nonce deletion
begin
OauthNoncesWorker.perform_in(nonce_expiry_time, nonce.id)
rescue Redis::CannotConnectError
# Okay to swallow error, since enqueuing the nonce deletion is for performance only
# Users shouldn't be prevented from logging in just because the nonce deletion worker isn't running
end
这不是最好的解决方案,还有待改进的空间。