rack-auth-krb 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|