I'm using basic http authentication in my rails app via the following code:
class ApplicationController < ActionController::Base
helper :all # include all helpers, all the time
before_filter :authenticate
private
def authenticate
authenticate_or_request_with_http_basic do |username, password|
if username.nil? || password.nil?
render :inline => %(xml.instruct! :xml, :version => "1.0", :encoding => "UTF-8"
xml.errors do
xml.error('Could not authenticate you.')
end), :type => :builder, :status => 401
end
end
end
end
The problem is, if you do a curl http://127.0.0.1:3000/foo/1.xml
without providing the -u username:password flag, you get a dead beat response like this:
HTTP/1.1 401 Unauthorized
Cache-Control: no-cache
WWW-Authenticate: Basic realm="Foo"
X-Runtime: 1
Content-Type: text/html; charset=utf-8
Content-Length: 27
Server: WEBrick/1.3.1 (Ruby/1.9.1/2010-01-10)
Date: Thu, 03 Jun 2010 03:09:18 GMT
Connection: Keep-Alive
HTTP Basic: Access denied.
Is it possible at all to render the inline XML I have above in the event a username and password is not provided by t开发者_如何学Pythonhe user?
This might not be the safest way to go about this, but you can give it a shot.
First, go ahead and build a custom error:
#construct a custom error class
class AuthenticationError < StandardError
# error code goes here
end
Now in your code block raise that error:
xml.errors do
raise AuthenticationError
end
You can use ActionController's rescue_from method to handle your custom error message now:
class ApplicationController < ActionController::Base
rescue_from AuthenticationError { |e| xml_status_error(:unauthorized, e) }
def xml_status_error(status,exception)
respond_to do |format|
format.xml { #here you go! }
format.any { head status } #just return the status code
end
end
end
精彩评论