rack-auth-krb 0.0.8
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +19 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +68 -0
- data/README.md +57 -0
- data/lib/basic_and_nego/auth/base.rb +20 -0
- data/lib/basic_and_nego/auth/basic.rb +31 -0
- data/lib/basic_and_nego/auth/gss.rb +36 -0
- data/lib/basic_and_nego/auth/krb.rb +28 -0
- data/lib/basic_and_nego/auth/negotiate.rb +53 -0
- data/lib/basic_and_nego/auth/none.rb +14 -0
- data/lib/basic_and_nego/auth/responses.rb +36 -0
- data/lib/basic_and_nego/auth/unsupported.rb +14 -0
- data/lib/basic_and_nego/auth.rb +4 -0
- data/lib/basic_and_nego/nulllogger.rb +10 -0
- data/lib/basic_and_nego/processor.rb +59 -0
- data/lib/basic_and_nego/request.rb +30 -0
- data/lib/goliath/rack/auth/krb/basic_and_nego.rb +36 -0
- data/lib/rack/auth/krb/basic_and_nego.rb +29 -0
- data/misc/goliath_dump_headers.rb +20 -0
- data/misc/rack_dump_headers.ru +12 -0
- data/misc/start_goliath_srv.sh +2 -0
- data/misc/start_puma_srv.sh +2 -0
- data/rack-auth-krb.gemspec +27 -0
- data/spec/basic_and_nego/auth/basic_spec.rb +46 -0
- data/spec/basic_and_nego/auth/gss_spec.rb +26 -0
- data/spec/basic_and_nego/auth/krb_spec.rb +48 -0
- data/spec/basic_and_nego/auth/negotiate_spec.rb +80 -0
- data/spec/basic_and_nego/processor_spec.rb +60 -0
- data/spec/basic_and_nego/request_spec.rb +37 -0
- data/spec/goliath/goliath_krb_spec.rb +48 -0
- data/spec/rack/rack_krb_spec.rb +40 -0
- data/spec/spec_helper.rb +30 -0
- metadata +184 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
rack-auth-krb (0.0.2)
|
5
|
+
gssapi
|
6
|
+
rkerberos
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: http://rubygems.org/
|
10
|
+
specs:
|
11
|
+
async-rack (0.5.1)
|
12
|
+
rack (~> 1.1)
|
13
|
+
diff-lcs (1.1.3)
|
14
|
+
em-synchrony (1.0.1)
|
15
|
+
eventmachine (>= 1.0.0.beta.1)
|
16
|
+
eventmachine (1.0.0.beta.4)
|
17
|
+
ffi (1.0.11)
|
18
|
+
goliath (0.9.4)
|
19
|
+
async-rack
|
20
|
+
em-synchrony (>= 1.0.0)
|
21
|
+
eventmachine (>= 1.0.0.beta.3)
|
22
|
+
http_parser.rb
|
23
|
+
http_router (~> 0.9.0)
|
24
|
+
log4r
|
25
|
+
multi_json
|
26
|
+
rack (>= 1.2.2)
|
27
|
+
rack-contrib
|
28
|
+
rack-respond_to
|
29
|
+
gssapi (1.1.1)
|
30
|
+
ffi (>= 1.0.1)
|
31
|
+
http_parser.rb (0.5.3)
|
32
|
+
http_router (0.9.7)
|
33
|
+
rack (>= 1.0.0)
|
34
|
+
url_mount (~> 0.2.1)
|
35
|
+
log4r (1.1.10)
|
36
|
+
multi_json (1.3.4)
|
37
|
+
puma (1.3.0)
|
38
|
+
rack (~> 1.2)
|
39
|
+
rack (1.4.1)
|
40
|
+
rack-accept-media-types (0.9)
|
41
|
+
rack-contrib (1.1.0)
|
42
|
+
rack (>= 0.9.1)
|
43
|
+
rack-respond_to (0.9.8)
|
44
|
+
rack-accept-media-types (>= 0.6)
|
45
|
+
rake (0.9.2.2)
|
46
|
+
rake-compiler (0.8.1)
|
47
|
+
rake
|
48
|
+
rkerberos (0.1.0)
|
49
|
+
rake-compiler
|
50
|
+
rspec (2.9.0)
|
51
|
+
rspec-core (~> 2.9.0)
|
52
|
+
rspec-expectations (~> 2.9.0)
|
53
|
+
rspec-mocks (~> 2.9.0)
|
54
|
+
rspec-core (2.9.0)
|
55
|
+
rspec-expectations (2.9.1)
|
56
|
+
diff-lcs (~> 1.1.3)
|
57
|
+
rspec-mocks (2.9.0)
|
58
|
+
url_mount (0.2.1)
|
59
|
+
rack
|
60
|
+
|
61
|
+
PLATFORMS
|
62
|
+
ruby
|
63
|
+
|
64
|
+
DEPENDENCIES
|
65
|
+
goliath
|
66
|
+
puma
|
67
|
+
rack-auth-krb!
|
68
|
+
rspec (~> 2.0)
|
data/README.md
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
rack-auth-krb
|
2
|
+
=============
|
3
|
+
|
4
|
+
Kerberos/GSSAPI authentication (Basic and Negotiate) rack middleware.
|
5
|
+
|
6
|
+
Actually this middleware should (hopefully) work for standard Rack
|
7
|
+
application and as a Goliath middleware.
|
8
|
+
|
9
|
+
Dependencies
|
10
|
+
============
|
11
|
+
Kerberos should be installed and configured on the server.
|
12
|
+
|
13
|
+
If you do want to share the authentication through your application,
|
14
|
+
you'll need to have a Rack::Session middleware inserted before you in
|
15
|
+
the loop.
|
16
|
+
|
17
|
+
Rack applications
|
18
|
+
=================
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
require 'rack/auth/krb/basic_and_nego'
|
22
|
+
|
23
|
+
infinity = Proc.new {|env| [200, {"Content-Type" => "text/html"}, ["Hello #{env['REMOTE_USER']}"]]}
|
24
|
+
|
25
|
+
use Rack::Session::Cookie
|
26
|
+
use Rack::Logger, ::Logger::DEBUG
|
27
|
+
use Rack::Auth::Krb::BasicAndNego, 'my realm', 'my keytab'
|
28
|
+
|
29
|
+
map '/' do
|
30
|
+
run infinity
|
31
|
+
end
|
32
|
+
```
|
33
|
+
|
34
|
+
|
35
|
+
Goliath applications
|
36
|
+
====================
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
require 'rack/session/cookie'
|
40
|
+
require 'goliath'
|
41
|
+
require 'goliath/rack/auth/krb/basic_and_nego'
|
42
|
+
|
43
|
+
class DumpHeaders < Goliath::API
|
44
|
+
# Must be placed *before* BasicAndNego if we want it to use sessions !
|
45
|
+
use Rack::Session::Cookie
|
46
|
+
use Goliath::Rack::Auth::Krb::BasicAndNego, 'my realm', 'my keytab'
|
47
|
+
|
48
|
+
def on_headers(env, headers)
|
49
|
+
env.logger.info 'received headers: ' + headers.inspect
|
50
|
+
end
|
51
|
+
|
52
|
+
def response(env)
|
53
|
+
[200, {}, "Hello #{env['REMOTE_USER']}"]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
```
|
57
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'basic_and_nego/auth/responses'
|
2
|
+
|
3
|
+
module BasicAndNego
|
4
|
+
module Auth
|
5
|
+
class Base
|
6
|
+
include Responses
|
7
|
+
|
8
|
+
attr_reader :response, :client_name, :headers
|
9
|
+
|
10
|
+
def initialize(request, logger, realm, keytab, service)
|
11
|
+
@request = request
|
12
|
+
@logger = logger
|
13
|
+
@realm = realm
|
14
|
+
@keytab = keytab
|
15
|
+
@service = service
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'basic_and_nego/auth/base'
|
2
|
+
require 'basic_and_nego/auth/krb'
|
3
|
+
|
4
|
+
module BasicAndNego
|
5
|
+
module Auth
|
6
|
+
class Basic < Base
|
7
|
+
|
8
|
+
def initialize(request, logger, realm, keytab, service)
|
9
|
+
super
|
10
|
+
@krb = BasicAndNego::Auth::Krb.new(@logger, @realm, @keytab)
|
11
|
+
end
|
12
|
+
|
13
|
+
def process
|
14
|
+
@logger.debug "Basic scheme proposed by client"
|
15
|
+
user, password = @request.credentials
|
16
|
+
authenticate(user, password)
|
17
|
+
@client_name = user unless @response
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def authenticate(user, password)
|
23
|
+
unless @krb.authenticate(user, password)
|
24
|
+
@logger.debug "Unable to authenticate (401)"
|
25
|
+
@response = unauthorized
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'gssapi'
|
2
|
+
|
3
|
+
module BasicAndNego
|
4
|
+
module Auth
|
5
|
+
class GSS
|
6
|
+
attr_reader :gssapi, :logger
|
7
|
+
|
8
|
+
#
|
9
|
+
# Can raise GSSAPI::GssApiError
|
10
|
+
#
|
11
|
+
def initialize(logger, service, realm, keytab)
|
12
|
+
@logger = logger
|
13
|
+
@service = service
|
14
|
+
@realm = realm
|
15
|
+
@keytab = keytab
|
16
|
+
@gssapi = GSSAPI::Simple.new(@realm, @service, @keytab)
|
17
|
+
|
18
|
+
gssapi.acquire_credentials
|
19
|
+
end
|
20
|
+
|
21
|
+
#
|
22
|
+
# Attempt to authenticate the furnished token against gssapi
|
23
|
+
#
|
24
|
+
# It return nil (in case of error) or the token sent back
|
25
|
+
# by the gssapi if the authentication is successfull
|
26
|
+
#
|
27
|
+
def authenticate(token)
|
28
|
+
return gssapi.accept_context(token)
|
29
|
+
end
|
30
|
+
|
31
|
+
def display_name
|
32
|
+
return gssapi.display_name
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require "rkerberos"
|
2
|
+
|
3
|
+
module BasicAndNego
|
4
|
+
module Auth
|
5
|
+
class Krb
|
6
|
+
attr_reader :realm, :keytab, :logger
|
7
|
+
|
8
|
+
def initialize(logger, realm, keytab)
|
9
|
+
@logger = logger
|
10
|
+
@realm = realm
|
11
|
+
@keytab = keytab
|
12
|
+
end
|
13
|
+
|
14
|
+
def authenticate(user, passwd)
|
15
|
+
successfull = false
|
16
|
+
Kerberos::Krb5.new do |krb5|
|
17
|
+
begin
|
18
|
+
krb5.get_init_creds_password(user, passwd)
|
19
|
+
successfull = true
|
20
|
+
rescue Kerberos::Krb5::Exception => e
|
21
|
+
logger.error "Failed to authenticate user '#{user}': #{e.message}"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
successfull
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'basic_and_nego/auth/base'
|
2
|
+
require 'basic_and_nego/auth/gss'
|
3
|
+
require 'base64'
|
4
|
+
|
5
|
+
module BasicAndNego
|
6
|
+
module Auth
|
7
|
+
class Negotiate < Base
|
8
|
+
|
9
|
+
def initialize(request, logger, realm, keytab, service)
|
10
|
+
super
|
11
|
+
setup_gss
|
12
|
+
end
|
13
|
+
|
14
|
+
def process
|
15
|
+
@logger.debug "Negotiate scheme proposed by client"
|
16
|
+
authenticate unless @response
|
17
|
+
verify_token unless @response
|
18
|
+
set_headers unless @response
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def setup_gss
|
24
|
+
@gss = BasicAndNego::Auth::GSS.new(@logger, @service, @realm, @keytab)
|
25
|
+
rescue GSSAPI::GssApiError => e
|
26
|
+
@logger.error "Unable to setup GSSAPI: #{e.message}"
|
27
|
+
@response = error
|
28
|
+
end
|
29
|
+
|
30
|
+
def authenticate
|
31
|
+
token = ::Base64.strict_decode64(@request.params)
|
32
|
+
@out_tok = @gss.authenticate(token)
|
33
|
+
rescue GSSAPI::GssApiError => e
|
34
|
+
@logger.error "Unable to authenticate: #{e.message}"
|
35
|
+
@response = unauthorized
|
36
|
+
end
|
37
|
+
|
38
|
+
def verify_token
|
39
|
+
if !@out_tok
|
40
|
+
@logger.debug "Unable to authenticate (401)"
|
41
|
+
@response = unauthorized
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def set_headers
|
46
|
+
tok_b64 = ::Base64.strict_encode64(@out_tok)
|
47
|
+
@headers = {'WWW-Authenticate' => "Negotiate #{tok_b64}"}
|
48
|
+
@client_name = @gss.display_name
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module BasicAndNego
|
2
|
+
module Auth
|
3
|
+
module Responses
|
4
|
+
|
5
|
+
def challenge
|
6
|
+
["Negotiate", "Basic"]
|
7
|
+
end
|
8
|
+
|
9
|
+
def unauthorized
|
10
|
+
[ 401,
|
11
|
+
{ 'Content-Type' => 'text/plain',
|
12
|
+
'Content-Length' => '0',
|
13
|
+
'WWW-Authenticate' => challenge },
|
14
|
+
[]
|
15
|
+
]
|
16
|
+
end
|
17
|
+
|
18
|
+
def bad_request
|
19
|
+
[ 400,
|
20
|
+
{ 'Content-Type' => 'text/plain',
|
21
|
+
'Content-Length' => '0' },
|
22
|
+
[]
|
23
|
+
]
|
24
|
+
end
|
25
|
+
|
26
|
+
def error
|
27
|
+
[ 500,
|
28
|
+
{ 'Content-Type' => 'text/plain',
|
29
|
+
'Content-Length' => '0' },
|
30
|
+
[]
|
31
|
+
]
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'socket'
|
2
|
+
require 'basic_and_nego/request'
|
3
|
+
require 'basic_and_nego/auth'
|
4
|
+
|
5
|
+
module BasicAndNego
|
6
|
+
class Processor
|
7
|
+
DEFAULT_SERVICE = "http@#{Socket::gethostname}"
|
8
|
+
|
9
|
+
def initialize(env, logger, realm, keytab, service)
|
10
|
+
@env = env
|
11
|
+
@logger = logger
|
12
|
+
@realm = realm
|
13
|
+
@keytab = keytab
|
14
|
+
@service = service || DEFAULT_SERVICE
|
15
|
+
|
16
|
+
@request = BasicAndNego::Request.new(@env)
|
17
|
+
@authenticator = @request.authenticator.new(@request, @logger, @realm, @keytab, @service)
|
18
|
+
@session = @env['rack.session']
|
19
|
+
end
|
20
|
+
|
21
|
+
def process_request
|
22
|
+
if authenticated
|
23
|
+
@logger.debug "User #{@session['REMOTE_USER']} already authenticated"
|
24
|
+
@env['REMOTE_USER'] = @session['REMOTE_USER']
|
25
|
+
else
|
26
|
+
@logger.debug "User not authenticated : delegate to authenticator"
|
27
|
+
|
28
|
+
if authenticate
|
29
|
+
@env['REMOTE_USER'] = client_name
|
30
|
+
@session['REMOTE_USER'] = client_name if @session
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def client_name
|
36
|
+
@authenticator.client_name
|
37
|
+
end
|
38
|
+
|
39
|
+
def headers
|
40
|
+
@authenticator.headers || {}
|
41
|
+
end
|
42
|
+
|
43
|
+
def response
|
44
|
+
@authenticator.response
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def authenticated
|
50
|
+
@session && @session['REMOTE_USER']
|
51
|
+
end
|
52
|
+
|
53
|
+
def authenticate
|
54
|
+
@authenticator.process
|
55
|
+
@authenticator.response.nil?
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'rack/auth/abstract/request'
|
2
|
+
module BasicAndNego
|
3
|
+
class Request < Rack::Auth::AbstractRequest
|
4
|
+
attr_reader :credentials
|
5
|
+
|
6
|
+
def authenticator
|
7
|
+
if !provided?
|
8
|
+
BasicAndNego::Auth::None
|
9
|
+
elsif supported_auth?
|
10
|
+
BasicAndNego::Auth.const_get(scheme.to_s.capitalize)
|
11
|
+
else
|
12
|
+
BasicAndNego::Auth::Unsupported
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def credentials
|
17
|
+
@credentials ||= params.unpack("m*").first.split(/:/, 2)
|
18
|
+
end
|
19
|
+
|
20
|
+
def username
|
21
|
+
credentials.first
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def supported_auth?
|
27
|
+
[:basic, :negotiate].include? scheme
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'goliath'
|
2
|
+
require 'basic_and_nego/request'
|
3
|
+
require 'basic_and_nego/processor'
|
4
|
+
|
5
|
+
module Goliath
|
6
|
+
module Rack
|
7
|
+
module Auth
|
8
|
+
module Krb
|
9
|
+
class BasicAndNego
|
10
|
+
include Goliath::Rack::AsyncMiddleware
|
11
|
+
|
12
|
+
def initialize(app, realm, keytab, service=nil)
|
13
|
+
@app = app
|
14
|
+
@realm = realm
|
15
|
+
@keytab = keytab
|
16
|
+
@service = service
|
17
|
+
end
|
18
|
+
|
19
|
+
def call(env)
|
20
|
+
a = ::BasicAndNego::Processor.new(env, env.logger, @realm, @keytab, @service)
|
21
|
+
a.process_request
|
22
|
+
|
23
|
+
return a.response if a.response
|
24
|
+
|
25
|
+
super(env, a.headers)
|
26
|
+
end
|
27
|
+
|
28
|
+
def post_process(env, status, headers, body, additional_headers)
|
29
|
+
[status, headers.merge(additional_headers), body]
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'basic_and_nego/request'
|
2
|
+
require 'basic_and_nego/processor'
|
3
|
+
|
4
|
+
module Rack
|
5
|
+
module Auth
|
6
|
+
module Krb
|
7
|
+
class BasicAndNego
|
8
|
+
|
9
|
+
def initialize(app, realm, keytab, service=nil)
|
10
|
+
@app = app
|
11
|
+
@realm = realm
|
12
|
+
@keytab = keytab
|
13
|
+
@service = service
|
14
|
+
end
|
15
|
+
|
16
|
+
def call(env)
|
17
|
+
a = ::BasicAndNego::Processor.new(env, env['rack.logger'], @realm, @keytab, @service)
|
18
|
+
a.process_request
|
19
|
+
|
20
|
+
return a.response if a.response
|
21
|
+
|
22
|
+
status, headers, body = @app.call(env)
|
23
|
+
|
24
|
+
[status, headers.merge(a.headers), body]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'rack/session/cookie'
|
5
|
+
require 'goliath'
|
6
|
+
require 'goliath/rack/auth/krb/basic_and_nego'
|
7
|
+
|
8
|
+
class DumpHeaders < Goliath::API
|
9
|
+
# Must be placed *before* BasicAndNego if we want it to use sessions !
|
10
|
+
use Rack::Session::Cookie
|
11
|
+
use Goliath::Rack::Auth::Krb::BasicAndNego, 'my realm', 'my keytab'
|
12
|
+
|
13
|
+
def on_headers(env, headers)
|
14
|
+
env.logger.info 'received headers: ' + headers.inspect
|
15
|
+
end
|
16
|
+
|
17
|
+
def response(env)
|
18
|
+
[200, {}, "Hello #{env['REMOTE_USER']}"]
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'rack/auth/krb/basic_and_nego'
|
2
|
+
|
3
|
+
infinity = Proc.new {|env| [200, {"Content-Type" => "text/html"}, ["Hello #{env['REMOTE_USER']}"]]}
|
4
|
+
|
5
|
+
use Rack::Session::Cookie
|
6
|
+
use Rack::Logger, ::Logger::DEBUG
|
7
|
+
use Rack::Auth::Krb::BasicAndNego, 'my realm', 'my keytab'
|
8
|
+
|
9
|
+
map '/' do
|
10
|
+
run infinity
|
11
|
+
end
|
12
|
+
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
Gem::Specification.new do |gem|
|
4
|
+
gem.name = 'rack-auth-krb'
|
5
|
+
gem.version = '0.0.8'
|
6
|
+
gem.authors = ["Frederick Ros"]
|
7
|
+
gem.email = 'frederick.ros@gmail.com'
|
8
|
+
gem.homepage = 'https://github.com/sleeper/rack-auth-krb'
|
9
|
+
gem.summary = 'Kerberos/GSSAPI authentication (Basic and Negotiate) Rack library'
|
10
|
+
gem.files = `git ls-files`.split("\n")
|
11
|
+
gem.test_files = `git ls-files -- spec/*`.split("\n")
|
12
|
+
|
13
|
+
gem.add_dependency "rack"
|
14
|
+
gem.add_dependency "gssapi"
|
15
|
+
gem.add_dependency "rkerberos"
|
16
|
+
|
17
|
+
gem.add_development_dependency "rspec", "~> 2.0"
|
18
|
+
gem.add_development_dependency "goliath"
|
19
|
+
gem.add_development_dependency "puma"
|
20
|
+
|
21
|
+
gem.extra_rdoc_files = ['README.md']
|
22
|
+
|
23
|
+
gem.description = <<-EOF
|
24
|
+
This library allows Kerberos/GSSAPI authentication using either Basic method
|
25
|
+
or Negotiate (i.e. authentication without the need of user/password combo).
|
26
|
+
EOF
|
27
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'basic_and_nego/auth/basic'
|
3
|
+
require 'basic_and_nego/nulllogger'
|
4
|
+
require 'basic_and_nego/request'
|
5
|
+
require 'base64'
|
6
|
+
|
7
|
+
describe BasicAndNego::Auth::Basic do
|
8
|
+
|
9
|
+
before(:each) do
|
10
|
+
env = {'HTTP_AUTHORIZATION' => "Basic #{::Base64.encode64('fred:pass')}"}
|
11
|
+
@realm = "my realm"
|
12
|
+
@keytab = "my keytab"
|
13
|
+
@service = "http/hostname"
|
14
|
+
@logger = BasicAndNego::NullLogger.new
|
15
|
+
@request = BasicAndNego::Request.new(env)
|
16
|
+
@request.should_receive(:credentials).and_return(['fred', 'pass'])
|
17
|
+
@krb = double('kerberos').as_null_object
|
18
|
+
BasicAndNego::Auth::Krb.should_receive(:new).with(@logger, @realm, @keytab).and_return(@krb)
|
19
|
+
@a = BasicAndNego::Auth::Basic.new(@request, @logger, @realm, @keytab, @service)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should try authentication against Kerberos in case of Basic" do
|
23
|
+
@krb.should_receive(:authenticate).with("fred", "pass").and_return(true)
|
24
|
+
@a.process
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should return 'unauthorized' if authentication fails" do
|
28
|
+
@krb.should_receive(:authenticate).and_return(false)
|
29
|
+
@a.process
|
30
|
+
@a.response.should_not be_nil
|
31
|
+
@a.response[0].should == 401
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should return true if authentication worked" do
|
35
|
+
@krb.should_receive(:authenticate).and_return(true)
|
36
|
+
@a.process
|
37
|
+
@a.response.should be_nil
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should set client's name if authentication worked" do
|
41
|
+
@krb.should_receive(:authenticate).and_return(true)
|
42
|
+
@a.process
|
43
|
+
@a.client_name.should == "fred"
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'basic_and_nego/auth/gss'
|
3
|
+
|
4
|
+
describe BasicAndNego::Auth::GSS do
|
5
|
+
let(:realm) { "my realm"}
|
6
|
+
let(:service) { "foo" }
|
7
|
+
let(:keytab) { "my keytab" }
|
8
|
+
let(:gssapi) { double("gss api").as_null_object }
|
9
|
+
let(:logger) { double('logger').as_null_object }
|
10
|
+
let(:good_request) { BasicAndNego::Request.new({'HTTP_AUTHORIZATION' => "Negotiate VGhpcyBpcyBteSB0b2tlbg=="})}
|
11
|
+
|
12
|
+
it "should initialize and deal with gssapi" do
|
13
|
+
gssapi.should_receive(:acquire_credentials)
|
14
|
+
GSSAPI::Simple.should_receive(:new).with(realm, service, keytab).and_return(gssapi)
|
15
|
+
g = BasicAndNego::Auth::GSS.new(logger, service, realm, keytab)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should authenticate request" do
|
19
|
+
gssapi.should_receive(:acquire_credentials)
|
20
|
+
gssapi.should_receive(:accept_context).and_return("Granted")
|
21
|
+
GSSAPI::Simple.should_receive(:new).with(realm, service, keytab).and_return(gssapi)
|
22
|
+
g = BasicAndNego::Auth::GSS.new(logger, service, realm, keytab)
|
23
|
+
g.authenticate("My token").should == "Granted"
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'basic_and_nego/auth/krb'
|
3
|
+
|
4
|
+
describe BasicAndNego::Auth::Krb do
|
5
|
+
let(:logger) { double('logger').as_null_object }
|
6
|
+
let(:realm) {"my realm"}
|
7
|
+
let(:keytab) {"my keytab"}
|
8
|
+
|
9
|
+
it "should initialize" do
|
10
|
+
krb = BasicAndNego::Auth::Krb.new(logger, realm, keytab)
|
11
|
+
krb.realm.should == realm
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should authenticate user/password" do
|
15
|
+
user = "fred"
|
16
|
+
passwd = "passwd"
|
17
|
+
k = double("rkerberos").as_null_object
|
18
|
+
k.should_receive(:get_init_creds_password).with(user, passwd).and_return(true)
|
19
|
+
Kerberos::Krb5.should_receive(:new).and_yield(k)
|
20
|
+
krb = BasicAndNego::Auth::Krb.new(logger, realm, keytab)
|
21
|
+
authenticated = krb.authenticate(user, passwd)
|
22
|
+
authenticated.should be_a(TrueClass)
|
23
|
+
authenticated.should be_true
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
it "should not-authenticate user if kerberos does not agree" do
|
28
|
+
user = "fred"
|
29
|
+
passwd = "passwd"
|
30
|
+
k = double("rkerberos").as_null_object
|
31
|
+
k.should_receive(:get_init_creds_password).with(user, passwd).and_raise(Kerberos::Krb5::Exception)
|
32
|
+
Kerberos::Krb5.should_receive(:new).and_yield(k)
|
33
|
+
krb = BasicAndNego::Auth::Krb.new(logger, realm, keytab)
|
34
|
+
authenticated = krb.authenticate(user, passwd)
|
35
|
+
authenticated.should be_a(FalseClass)
|
36
|
+
authenticated.should be_false
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should catch exception from underlying system" do
|
40
|
+
user = "fred"
|
41
|
+
passwd = "passwd"
|
42
|
+
k = double("rkerberos").as_null_object
|
43
|
+
k.should_receive(:get_init_creds_password).with(user, passwd).and_raise(Kerberos::Krb5::Exception)
|
44
|
+
Kerberos::Krb5.should_receive(:new).and_yield(k)
|
45
|
+
krb = BasicAndNego::Auth::Krb.new(logger, realm, keytab)
|
46
|
+
krb.authenticate(user, passwd).should be_false
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'basic_and_nego/auth/negotiate'
|
3
|
+
require 'basic_and_nego/nulllogger'
|
4
|
+
require 'basic_and_nego/request'
|
5
|
+
require 'base64'
|
6
|
+
|
7
|
+
describe BasicAndNego::Auth::Negotiate do
|
8
|
+
|
9
|
+
before(:each) do
|
10
|
+
env = {'HTTP_AUTHORIZATION' => "Negotiate VGhpcyBpcyBteSB0b2tlbg=="}
|
11
|
+
@realm = "my realm"
|
12
|
+
@keytab = "my keytab"
|
13
|
+
@service = "http/hostname"
|
14
|
+
@logger = BasicAndNego::NullLogger.new
|
15
|
+
@request = BasicAndNego::Request.new(env)
|
16
|
+
@gss = double('gss').as_null_object
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should try authentication against GSS in case of Negotiate" do
|
20
|
+
BasicAndNego::Auth::GSS.should_receive(:new).with(@logger, @service, @realm, @keytab).and_return(@gss)
|
21
|
+
@a = BasicAndNego::Auth::Negotiate.new(@request, @logger, @realm, @keytab, @service)
|
22
|
+
@gss.should_receive(:authenticate).and_return("Granted")
|
23
|
+
@gss.should_receive(:display_name).and_return("fred")
|
24
|
+
@a.process
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should return 'unauthorized' if authentication fails" do
|
28
|
+
BasicAndNego::Auth::GSS.should_receive(:new).with(@logger, @service, @realm, @keytab).and_return(@gss)
|
29
|
+
@a = BasicAndNego::Auth::Negotiate.new(@request, @logger, @realm, @keytab, @service)
|
30
|
+
@gss.should_receive(:authenticate).and_return(nil)
|
31
|
+
@a.process
|
32
|
+
@a.response.should_not be_nil
|
33
|
+
@a.response[0].should == 401
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should return true if authentication worked" do
|
37
|
+
BasicAndNego::Auth::GSS.should_receive(:new).with(@logger, @service, @realm, @keytab).and_return(@gss)
|
38
|
+
@a = BasicAndNego::Auth::Negotiate.new(@request, @logger, @realm, @keytab, @service)
|
39
|
+
@gss.should_receive(:authenticate).and_return("Granted")
|
40
|
+
@a.process
|
41
|
+
@a.response.should be_nil
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should set client's name if authentication worked" do
|
45
|
+
BasicAndNego::Auth::GSS.should_receive(:new).with(@logger, @service, @realm, @keytab).and_return(@gss)
|
46
|
+
@a = BasicAndNego::Auth::Negotiate.new(@request, @logger, @realm, @keytab, @service)
|
47
|
+
@gss.should_receive(:authenticate).and_return("Granted")
|
48
|
+
@gss.should_receive(:display_name).and_return("fred")
|
49
|
+
@a.process
|
50
|
+
@a.client_name.should == "fred"
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should set header to returned token if authentication worked" do
|
54
|
+
BasicAndNego::Auth::GSS.should_receive(:new).with(@logger, @service, @realm, @keytab).and_return(@gss)
|
55
|
+
@a = BasicAndNego::Auth::Negotiate.new(@request, @logger, @realm, @keytab, @service)
|
56
|
+
@gss.should_receive(:authenticate).and_return("Granted")
|
57
|
+
@gss.should_receive(:display_name).and_return("fred")
|
58
|
+
@a.process
|
59
|
+
@a.client_name.should == "fred"
|
60
|
+
@a.headers['WWW-Authenticate'].should == "Negotiate #{::Base64.strict_encode64('Granted')}"
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should catch GSSAPI exceptions in getting credentials" do
|
64
|
+
BasicAndNego::Auth::GSS.should_receive(:new).with(@logger, @service, @realm, @keytab).and_raise(GSSAPI::GssApiError)
|
65
|
+
@a = BasicAndNego::Auth::Negotiate.new(@request, @logger, @realm, @keytab, @service)
|
66
|
+
@a.process
|
67
|
+
@a.response.should_not be_nil
|
68
|
+
@a.response[0].should == 500
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should catch GSSAPI exceptions in authenticating token" do
|
72
|
+
BasicAndNego::Auth::GSS.should_receive(:new).with(@logger, @service, @realm, @keytab).and_return(@gss)
|
73
|
+
@a = BasicAndNego::Auth::Negotiate.new(@request, @logger, @realm, @keytab, @service)
|
74
|
+
@gss.should_receive(:authenticate).and_raise(GSSAPI::GssApiError)
|
75
|
+
@a.process
|
76
|
+
@a.response.should_not be_nil
|
77
|
+
@a.response[0].should == 401
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'basic_and_nego/processor'
|
3
|
+
require 'basic_and_nego/nulllogger'
|
4
|
+
|
5
|
+
describe BasicAndNego::Processor do
|
6
|
+
it "should not re-authenticate user" do
|
7
|
+
env = {}
|
8
|
+
env['rack.session'] = {}
|
9
|
+
env['rack.session']['REMOTE_USER'] = 'fred'
|
10
|
+
a = BasicAndNego::Processor.new(env, BasicAndNego::NullLogger.new, 'my realm', 'my keytab file', nil)
|
11
|
+
a.process_request
|
12
|
+
a.response.should be_nil
|
13
|
+
a.headers.should be_empty
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should try to authenticate if there's no session" do
|
17
|
+
env = {}
|
18
|
+
a = BasicAndNego::Processor.new(env, BasicAndNego::NullLogger.new, 'my realm', 'my keytab file', nil)
|
19
|
+
a.should_receive(:authenticate)
|
20
|
+
a.process_request
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should set REMOTE_USER if user authenticated" do
|
24
|
+
env = {}
|
25
|
+
a = BasicAndNego::Processor.new(env, BasicAndNego::NullLogger.new, 'my realm', 'my keytab file', nil)
|
26
|
+
a.should_receive(:authenticate).and_return(true)
|
27
|
+
a.should_receive(:client_name).and_return("fred")
|
28
|
+
a.process_request
|
29
|
+
env['REMOTE_USER'].should == "fred"
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should update the session if user authenticated" do
|
33
|
+
env = {}
|
34
|
+
env['rack.session'] = {}
|
35
|
+
a = BasicAndNego::Processor.new(env, BasicAndNego::NullLogger.new, 'my realm', 'my keytab file', nil)
|
36
|
+
a.should_receive(:authenticate).and_return(true)
|
37
|
+
a.should_receive(:client_name).twice.and_return("fred")
|
38
|
+
a.process_request
|
39
|
+
env['REMOTE_USER'].should == "fred"
|
40
|
+
env['rack.session']['REMOTE_USER'].should == 'fred'
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should try to authenticate if user is not yet authenticated" do
|
44
|
+
env = {}
|
45
|
+
env['rack.session'] = {}
|
46
|
+
a = BasicAndNego::Processor.new(env, BasicAndNego::NullLogger.new, 'my realm', 'my keytab file', nil)
|
47
|
+
a.should_receive(:authenticate)
|
48
|
+
a.process_request
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should ask for an authorization key if none is provided" do
|
52
|
+
env = {}
|
53
|
+
env['rack.session'] = {}
|
54
|
+
a = BasicAndNego::Processor.new(env, BasicAndNego::NullLogger.new, 'my realm', 'my keytab file', nil)
|
55
|
+
a.process_request
|
56
|
+
a.response.should_not be_nil
|
57
|
+
a.response[0].should == 401
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'basic_and_nego/request'
|
3
|
+
require 'base64'
|
4
|
+
|
5
|
+
describe BasicAndNego::Request do
|
6
|
+
|
7
|
+
it "should be able to detect a no auth" do
|
8
|
+
r = BasicAndNego::Request.new({})
|
9
|
+
r.authenticator.should == BasicAndNego::Auth::None
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should be able to detect a 'basic' scheme" do
|
13
|
+
r = BasicAndNego::Request.new({'HTTP_AUTHORIZATION' => "Basic #{Base64.encode64('fred:pass')}"})
|
14
|
+
r.authenticator.should == BasicAndNego::Auth::Basic
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should be able to detect a 'negotiate' scheme" do
|
18
|
+
r = BasicAndNego::Request.new({'HTTP_AUTHORIZATION' => "Negotiate #{Base64.encode64('fred:pass')}"})
|
19
|
+
r.authenticator.should == BasicAndNego::Auth::Negotiate
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should be able to detect an unsupported auth" do
|
23
|
+
r = BasicAndNego::Request.new({'HTTP_AUTHORIZATION' => "Digest #{Base64.encode64('fred:pass')}"})
|
24
|
+
r.authenticator.should == BasicAndNego::Auth::Unsupported
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should decode credentials" do
|
28
|
+
r = BasicAndNego::Request.new({'HTTP_AUTHORIZATION' => "Basic #{Base64.encode64('fred:pass')}"})
|
29
|
+
r.credentials.should =~ ["fred", "pass"]
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should return username" do
|
33
|
+
r = BasicAndNego::Request.new({'HTTP_AUTHORIZATION' => "Basic #{Base64.encode64('fred:pass')}"})
|
34
|
+
r.username.should == "fred"
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'goliath/rack/auth/krb/basic_and_nego'
|
3
|
+
|
4
|
+
describe Goliath::Rack::Auth::Krb::BasicAndNego do
|
5
|
+
it 'accepts an app' do
|
6
|
+
lambda { Goliath::Rack::Auth::Krb::BasicAndNego.new('my app', 'my realm', 'my keytab') }.should_not raise_error
|
7
|
+
end
|
8
|
+
|
9
|
+
describe 'with middleware' do
|
10
|
+
before(:each) do
|
11
|
+
@app = mock('app').as_null_object
|
12
|
+
@env = Goliath::Env.new
|
13
|
+
@env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded; charset=utf-8'
|
14
|
+
@auth = Goliath::Rack::Auth::Krb::BasicAndNego.new(@app, 'my realm', 'my keytab')
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
it 'returns status, headers and body from the app' do
|
19
|
+
app_headers = {'Content-Type' => 'hash'}
|
20
|
+
app_body = {:a => 1, :b => 2}
|
21
|
+
p = double("processor").as_null_object
|
22
|
+
p.should_receive(:response).and_return(nil)
|
23
|
+
add_headers = {"fred" => "foo"}
|
24
|
+
p.should_receive(:headers).and_return(add_headers)
|
25
|
+
::BasicAndNego::Processor.should_receive(:new).and_return(p)
|
26
|
+
p.should_receive(:process_request)
|
27
|
+
@app.should_receive(:call).and_return([200, app_headers, app_body])
|
28
|
+
|
29
|
+
status, headers, body = @auth.call(@env)
|
30
|
+
status.should == 200
|
31
|
+
headers['fred'].should == "foo"
|
32
|
+
body.should == app_body
|
33
|
+
end
|
34
|
+
|
35
|
+
it "returns error in case of failing authentication" do
|
36
|
+
app_headers = {'Content-Type' => 'hash'}
|
37
|
+
app_body = {:a => 1, :b => 2}
|
38
|
+
p = double("processor").as_null_object
|
39
|
+
r = [401, {}, "foo"]
|
40
|
+
p.should_receive(:response).twice.and_return(r)
|
41
|
+
p.should_receive(:process_request)
|
42
|
+
::BasicAndNego::Processor.should_receive(:new).and_return(p)
|
43
|
+
|
44
|
+
response = @auth.call(@env)
|
45
|
+
response.should =~ r
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'rack/auth/krb/basic_and_nego'
|
3
|
+
require 'basic_and_nego/nulllogger'
|
4
|
+
|
5
|
+
class SessionAuthentified
|
6
|
+
attr_accessor :app
|
7
|
+
def initialize(app,configs = {})
|
8
|
+
@app = app
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(e)
|
12
|
+
e['rack.session'] ||= {}
|
13
|
+
e['rack.session']['REMOTE_USER'] = "fred"
|
14
|
+
@app.call(e)
|
15
|
+
end
|
16
|
+
end # session
|
17
|
+
|
18
|
+
describe "Rack::Auth::Krb::BasicAndNego" do
|
19
|
+
|
20
|
+
before(:each) do
|
21
|
+
@basic_app = lambda{|env| [200,{'Content-Type' => 'text/plain'},'OK']}
|
22
|
+
@env = env_with_params("/", {}, {'rack.logger' => BasicAndNego::NullLogger.new})
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should return a 401 if authentication failed" do
|
26
|
+
app = setup_rack(@basic_app)
|
27
|
+
p = double("processor").as_null_object
|
28
|
+
p.should_receive(:response).twice.and_return(not_authorized_response)
|
29
|
+
p.should_receive(:process_request)
|
30
|
+
::BasicAndNego::Processor.should_receive(:new).and_return(p)
|
31
|
+
|
32
|
+
app.call(@env).first.should == 401
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should not ask for authentication if client is already authenticated" do
|
36
|
+
app = setup_rack(@basic_app, {:session => SessionAuthentified})
|
37
|
+
app.call(@env).first.should == 200
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
$:.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
|
2
|
+
$:.unshift File.expand_path(File.dirname(__FILE__))
|
3
|
+
|
4
|
+
require 'rspec'
|
5
|
+
require 'rack'
|
6
|
+
|
7
|
+
def env_with_params(path = "/", params = {}, env = {})
|
8
|
+
method = params.delete(:method) || "GET"
|
9
|
+
env = { 'HTTP_VERSION' => '1.1', 'REQUEST_METHOD' => "#{method}" }.merge(env)
|
10
|
+
Rack::MockRequest.env_for("#{path}?#{Rack::Utils.build_query(params)}", env)
|
11
|
+
end
|
12
|
+
|
13
|
+
def setup_rack(app = nil, opts={}, &block)
|
14
|
+
app ||= block if block_given?
|
15
|
+
|
16
|
+
Rack::Builder.new do
|
17
|
+
use opts[:session] if opts[:session]
|
18
|
+
use Rack::Auth::Krb::BasicAndNego, 'my realm', 'my keytab'
|
19
|
+
run app
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def not_authorized_response
|
24
|
+
[ 401,
|
25
|
+
{ 'Content-Type' => 'text/plain',
|
26
|
+
'Content-Length' => '0',
|
27
|
+
'WWW-Authenticate' => ["Negotiate", "Basic"]},
|
28
|
+
[]
|
29
|
+
]
|
30
|
+
end
|
metadata
ADDED
@@ -0,0 +1,184 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rack-auth-krb
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.8
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Frederick Ros
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-06-13 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rack
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: gssapi
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rkerberos
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rspec
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '2.0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '2.0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: goliath
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: puma
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
description: ! " This library allows Kerberos/GSSAPI authentication using either
|
111
|
+
Basic method\n or Negotiate (i.e. authentication without the need of user/password
|
112
|
+
combo).\n"
|
113
|
+
email: frederick.ros@gmail.com
|
114
|
+
executables: []
|
115
|
+
extensions: []
|
116
|
+
extra_rdoc_files:
|
117
|
+
- README.md
|
118
|
+
files:
|
119
|
+
- .gitignore
|
120
|
+
- Gemfile
|
121
|
+
- Gemfile.lock
|
122
|
+
- README.md
|
123
|
+
- lib/basic_and_nego/auth.rb
|
124
|
+
- lib/basic_and_nego/auth/base.rb
|
125
|
+
- lib/basic_and_nego/auth/basic.rb
|
126
|
+
- lib/basic_and_nego/auth/gss.rb
|
127
|
+
- lib/basic_and_nego/auth/krb.rb
|
128
|
+
- lib/basic_and_nego/auth/negotiate.rb
|
129
|
+
- lib/basic_and_nego/auth/none.rb
|
130
|
+
- lib/basic_and_nego/auth/responses.rb
|
131
|
+
- lib/basic_and_nego/auth/unsupported.rb
|
132
|
+
- lib/basic_and_nego/nulllogger.rb
|
133
|
+
- lib/basic_and_nego/processor.rb
|
134
|
+
- lib/basic_and_nego/request.rb
|
135
|
+
- lib/goliath/rack/auth/krb/basic_and_nego.rb
|
136
|
+
- lib/rack/auth/krb/basic_and_nego.rb
|
137
|
+
- misc/goliath_dump_headers.rb
|
138
|
+
- misc/rack_dump_headers.ru
|
139
|
+
- misc/start_goliath_srv.sh
|
140
|
+
- misc/start_puma_srv.sh
|
141
|
+
- rack-auth-krb.gemspec
|
142
|
+
- spec/basic_and_nego/auth/basic_spec.rb
|
143
|
+
- spec/basic_and_nego/auth/gss_spec.rb
|
144
|
+
- spec/basic_and_nego/auth/krb_spec.rb
|
145
|
+
- spec/basic_and_nego/auth/negotiate_spec.rb
|
146
|
+
- spec/basic_and_nego/processor_spec.rb
|
147
|
+
- spec/basic_and_nego/request_spec.rb
|
148
|
+
- spec/goliath/goliath_krb_spec.rb
|
149
|
+
- spec/rack/rack_krb_spec.rb
|
150
|
+
- spec/spec_helper.rb
|
151
|
+
homepage: https://github.com/sleeper/rack-auth-krb
|
152
|
+
licenses: []
|
153
|
+
post_install_message:
|
154
|
+
rdoc_options: []
|
155
|
+
require_paths:
|
156
|
+
- lib
|
157
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
158
|
+
none: false
|
159
|
+
requirements:
|
160
|
+
- - ! '>='
|
161
|
+
- !ruby/object:Gem::Version
|
162
|
+
version: '0'
|
163
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
164
|
+
none: false
|
165
|
+
requirements:
|
166
|
+
- - ! '>='
|
167
|
+
- !ruby/object:Gem::Version
|
168
|
+
version: '0'
|
169
|
+
requirements: []
|
170
|
+
rubyforge_project:
|
171
|
+
rubygems_version: 1.8.24
|
172
|
+
signing_key:
|
173
|
+
specification_version: 3
|
174
|
+
summary: Kerberos/GSSAPI authentication (Basic and Negotiate) Rack library
|
175
|
+
test_files:
|
176
|
+
- spec/basic_and_nego/auth/basic_spec.rb
|
177
|
+
- spec/basic_and_nego/auth/gss_spec.rb
|
178
|
+
- spec/basic_and_nego/auth/krb_spec.rb
|
179
|
+
- spec/basic_and_nego/auth/negotiate_spec.rb
|
180
|
+
- spec/basic_and_nego/processor_spec.rb
|
181
|
+
- spec/basic_and_nego/request_spec.rb
|
182
|
+
- spec/goliath/goliath_krb_spec.rb
|
183
|
+
- spec/rack/rack_krb_spec.rb
|
184
|
+
- spec/spec_helper.rb
|