我正在从rails 3升级到rails 4,并尝试根据此示例进行摘要式身份验证: http://lightyearsoftware.com/2009/04/testing-http-digest-authentication-in-rails/
看起来'process_with_test'方法已被删除,所以我想我可以像这样覆盖控制器的处理方法:
def authenticate_with_http_digest(user = API_USERNAME, password = API_PASSWORD, realm = API_REALM)
ActionController::Base.class_eval { include ActionController::Testing }
@controller.instance_eval %Q(
alias real_process process
def process(name)
credentials = {
:uri => request.url,
:realm => "#{realm}",
:username => "#{user}",
:nonce => ActionController::HttpAuthentication::Digest.nonce(Rails.configuration.secret_key_base),
:opaque => ActionController::HttpAuthentication::Digest.opaque(Rails.configuration.secret_key_base)
}
request.env['HTTP_AUTHORIZATION'] = ActionController::HttpAuthentication::Digest.encode_credentials(request.request_method, credentials, "#{password}", false)
real_process(name)
end
)
end
我可以看到新方法被调用,但是当我调用控制器时仍然会得到401访问被拒绝错误。我不确定我是否正确创建了摘要式身份验证,但我不知道哪个部分不正确。有没有人有调试这个的提示?
答案 0 :(得分:0)
我有同样的问题。我阅读了Rails 4测试用例并构建了以下解决方案。任何想象力都不完美,但它在我的测试环境中有效。它是原始authenticate_with_http_digest
辅助方法的直接解决方案。
这里的要点: https://gist.github.com/illoyd/9429839
后人:
# This should go into spec/support/auth_spec_helpers.rb (if you are using RSpec)
module AuthSpecHelpers
##
# Convenience method for setting the Digest Authentication details.
# To use, pass the username and password.
# The method and target are used for the initial request to get the digest auth headers. These will be translated into 'get :index' for example.
# The final 'header' parameter sets the request's authentication headers.
def authenticate_with_http_digest(user, password, method = :get, target = :index, header = 'HTTP_AUTHORIZATION')
@request.env[header] = encode_credentials(username: user, password: password, method: method, target: target)
end
##
# Shamelessly stolen from the Rails 4 test framework.
# See https://github.com/rails/rails/blob/a3b1105ada3da64acfa3843b164b14b734456a50/actionpack/test/controller/http_digest_authentication_test.rb
def encode_credentials(options)
options.reverse_merge!(:nc => "00000001", :cnonce => "0a4f113b", :password_is_ha1 => false)
password = options.delete(:password)
# Perform unauthenticated request to retrieve digest parameters to use on subsequent request
method = options.delete(:method) || 'GET'
target = options.delete(:target) || :index
case method.to_s.upcase
when 'GET'
get target
when 'POST'
post target
end
assert_response :unauthorized
credentials = decode_credentials(@response.headers['WWW-Authenticate'])
credentials.merge!(options)
path_info = @request.env['PATH_INFO'].to_s
uri = options[:uri] || path_info
credentials.merge!(:uri => uri)
@request.env["ORIGINAL_FULLPATH"] = path_info
ActionController::HttpAuthentication::Digest.encode_credentials(method, credentials, password, options[:password_is_ha1])
end
##
# Also shamelessly stolen from the Rails 4 test framework.
# See https://github.com/rails/rails/blob/a3b1105ada3da64acfa3843b164b14b734456a50/actionpack/test/controller/http_digest_authentication_test.rb
def decode_credentials(header)
ActionController::HttpAuthentication::Digest.decode_credentials(header)
end
end
# Don't forget to add to rspec's config (spec/spec_helper.rb)
RSpec.configure do |config|
# Include auth digest helper
config.include AuthSpecHelpers, :type => :controller
end
快乐的测试。