basic auth

master
Kanezoh 2022-01-04 13:09:09 +09:00
parent 712147aa70
commit 12df962cbd
5 changed files with 50 additions and 45 deletions

View File

@ -1,18 +1,19 @@
require "./spec_helper"
require "./server.cr"
#WebMock.stub(:get, "http://auth.example.com/")
# .with(headers: {"Authorization" => "Basic #{Base64.strict_encode("user:pass").chomp}"})
# .to_return(status: 200)
#
#WebMock.stub(:get, "http://auth.example.com/")
# .to_return(status: 401, headers: {"WWW-Authenticate" => "Basic realm=\"Access to the staging site\", charset=\"UTF-8\""})
describe "Mechanize HTTP Authentication test" do
WebMock.allow_net_connect = true
it "auth" do
WebMock.allow_net_connect = true
it "should be unsuccessful without credentials " do
agent = Mechanize.new
page = agent.get("#{TEST_SERVER_URL}/secret")
p page.body
WebMock.allow_net_connect = false
end
page.code.should eq 401
# WebMock.allow_net_connect = false
end
it "should be successful with credentials " do
agent = Mechanize.new
agent.add_auth("#{TEST_SERVER_URL}", "username", "password")
page = agent.get("#{TEST_SERVER_URL}/secret")
page.code.should eq 200
end
end

View File

@ -14,6 +14,7 @@ class BasicAuthHandler < Kemal::BasicAuth::Handler
super
end
end
add_handler BasicAuthHandler.new("username", "password")
get "/secret" do

View File

@ -41,8 +41,9 @@ class Mechanize
set_user_agent
set_request_referer(referer)
uri, params = resolve_parameters(uri, method, params)
response = http_request(uri, method, params, body)
request_auth response, uri
client = ::HTTP::Client.new(uri)
request_auth client, uri
response = http_request(client, uri, method, params, body)
body = response.not_nil!.body
page = response_parse(response, body, uri)
response_log(response)
@ -55,7 +56,7 @@ class Mechanize
end
if response && response.status.unauthorized?
response_authenticate(response, page, uri, params, referer)
return response_authenticate(response, page, uri, params, referer)
end
page
@ -76,27 +77,28 @@ class Mechanize
end
# send http request
private def http_request(uri, method, params, body) : ::HTTP::Client::Response?
private def http_request(client, uri, method, params, body) : ::HTTP::Client::Response?
request_log(uri, method)
path = uri.path
case uri.scheme.not_nil!.downcase
when "http", "https"
case method
when :get
::HTTP::Client.get(uri, headers: request_headers)
client.get(path, headers: request_headers)
when :post
::HTTP::Client.post(uri, headers: request_headers, form: params.not_nil!.fetch("value", ""))
client.post(path, headers: request_headers, form: params.not_nil!.fetch("value", ""))
when :put
::HTTP::Client.put(uri, headers: request_headers, body: body)
client.put(path, headers: request_headers, body: body)
when :delete
::HTTP::Client.delete(uri, headers: request_headers, body: body)
client.delete(uri, headers: request_headers, body: body)
when :head
::HTTP::Client.head(uri, headers: request_headers)
client.head(uri, headers: request_headers)
end
end
end
def request_auth(request, uri)
def request_auth(client, uri)
base_uri = uri.dup
base_uri.path = "/"
base_uri.user &&= nil
@ -108,9 +110,7 @@ class Mechanize
res = @auth_store.credentials_for uri, realm.realm
if res
user, password = res
# p user
# p password
# request.basic_auth user, password
client.basic_auth user, password
end
end
@ -270,13 +270,10 @@ class Mechanize
unless @auth_store.credentials?(uri, challenges)
# TODO: raise error
return page
end
if challenge = challenges.find { |c| c.scheme =~ /^Digest$/i }
# TODO implement Digest Auth
elsif challenge = challenges.find { |c| c.scheme == "NTLM" }
# TODO implement Digest Auth
elsif challenge = challenges.find { |c| c.scheme == "Basic" }
if challenge = challenges.find { |c| c.scheme == "Basic" }
realm = challenge.realm uri
if realm
@authenticate_methods[realm.uri] = Hash(String, Array(AuthRealm)).new([] of AuthRealm) unless @authenticate_methods.has_key?(realm.uri)
@ -288,10 +285,11 @@ class Mechanize
existing_realms << realm
end
fetch(uri, headers: request_headers, params: params, referer: referer)
else
# TODO: raise error
raise Exception.new("error")
end
fetch(uri, headers: request_headers, params: params, referer: referer)
end
# reset request cookie before setting headers.

View File

@ -29,13 +29,14 @@ class Mechanize
# Constructs an AuthRealm for this challenge
def realm(uri)
uri.path = "/"
target_uri = uri.dup
target_uri.path = "/"
case scheme
when "Basic"
# raise ArgumentError, "provide uri for Basic authentication" unless uri
Mechanize::HTTP::AuthRealm.new scheme, uri, self["realm"]
Mechanize::HTTP::AuthRealm.new scheme, target_uri, self["realm"]
when "Digest"
Mechanize::HTTP::AuthRealm.new scheme, uri, self["realm"]
Mechanize::HTTP::AuthRealm.new scheme, target_uri, self["realm"]
else
# raise Mechanize::Error, "unknown HTTP authentication scheme #{scheme}"
end

View File

@ -9,20 +9,22 @@ class Mechanize
end
def add_auth(uri : String | URI, user : String, pass : String, realm : String? = nil, domain : String? = nil)
target_uri = uri.dup
unless uri.is_a?(URI)
uri = URI.parse(uri)
target_uri = URI.parse(uri)
end
uri.path = "/"
uri.user = nil
uri.password = nil
target_uri = target_uri.as(URI)
target_uri.path = "/"
target_uri.user = nil
target_uri.password = nil
realm = "" if realm.nil?
domain = "" if domain.nil?
realm_hash = {realm => [user, pass, domain]}
if auth_accounts.has_key?(uri)
auth_accounts[uri].merge!(realm_hash)
if auth_accounts.has_key?(target_uri)
auth_accounts[target_uri].merge!(realm_hash)
else
auth_accounts[uri] = realm_hash
auth_accounts[target_uri] = realm_hash
end
end
@ -38,15 +40,17 @@ class Mechanize
# Retrieves credentials for +realm+ on the server at +uri+.
def credentials_for(uri : String | URI, realm : String?) : Array(String)?
target_uri = uri.dup
unless uri.is_a?(URI)
uri = URI.parse(uri)
target_uri = URI.parse(uri)
end
uri.path = "/"
uri.user = nil
uri.password = nil
target_uri = target_uri.as(URI)
target_uri.path = "/"
target_uri.user = nil
target_uri.password = nil
realm = "" if realm.nil?
realms = auth_accounts.fetch(uri, nil)
realms = auth_accounts.fetch(target_uri, nil)
return nil if realms.nil?
realms.fetch(realm, nil) || realms.fetch("", nil)