conjur-api 5.3.8.pre.194 → 5.4.0.pre.341
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop_settings.yml +1 -1
- data/CHANGELOG.md +15 -2
- data/CONTRIBUTING.md +1 -4
- data/Jenkinsfile +6 -38
- data/VERSION +1 -1
- data/bin/parse-changelog.sh +1 -1
- data/ci/configure_v5.sh +5 -0
- data/ci/oauth/keycloak/create_client +18 -0
- data/ci/oauth/keycloak/create_user +21 -0
- data/ci/oauth/keycloak/fetch_certificate +18 -0
- data/ci/oauth/keycloak/keycloak_functions.sh +71 -0
- data/ci/oauth/keycloak/standalone.xml +578 -0
- data/ci/oauth/keycloak/wait_for_server +56 -0
- data/conjur-api.gemspec +1 -0
- data/dev/Dockerfile.dev +1 -1
- data/docker-compose.yml +23 -1
- data/features/authenticators.feature +8 -0
- data/features/authn.feature +14 -0
- data/features/step_definitions/api_steps.rb +34 -0
- data/features/step_definitions/policy_steps.rb +59 -0
- data/features/step_definitions/result_steps.rb +4 -0
- data/features/support/env.rb +1 -0
- data/lib/conjur/api/authenticators.rb +8 -0
- data/lib/conjur/api/authn.rb +19 -0
- data/lib/conjur/api/router/v5.rb +21 -0
- data/test.sh +4 -1
- metadata +28 -7
data/docker-compose.yml
CHANGED
@@ -4,15 +4,36 @@ services:
|
|
4
4
|
image: postgres:9.3
|
5
5
|
|
6
6
|
conjur_5:
|
7
|
-
image: cyberark/conjur
|
7
|
+
image: cyberark/conjur:edge
|
8
8
|
command: server -a cucumber
|
9
9
|
environment:
|
10
10
|
DATABASE_URL: postgres://postgres@pg/postgres
|
11
11
|
CONJUR_DATA_KEY: 'WMfApcDBtocRWV+ZSUP3Tjr5XNU+Z2FdBb6BEezejIs='
|
12
12
|
volumes:
|
13
13
|
- authn_local_5:/run/authn-local
|
14
|
+
- ./ci/oauth/keycloak:/scripts
|
14
15
|
depends_on:
|
15
16
|
- pg
|
17
|
+
- keycloak
|
18
|
+
|
19
|
+
keycloak:
|
20
|
+
image: jboss/keycloak:4.3.0.Final
|
21
|
+
environment:
|
22
|
+
- KEYCLOAK_USER=admin
|
23
|
+
- KEYCLOAK_PASSWORD=admin
|
24
|
+
- KEYCLOAK_APP_USER=alice
|
25
|
+
- KEYCLOAK_APP_USER_PASSWORD=alice
|
26
|
+
- KEYCLOAK_APP_USER_EMAIL=alice@conjur.net
|
27
|
+
- DB_VENDOR=H2
|
28
|
+
- KEYCLOAK_CLIENT_ID=conjurClient
|
29
|
+
- KEYCLOAK_REDIRECT_URI=http://conjur_5/authn-oidc/keycloak/cucumber/authenticate
|
30
|
+
- KEYCLOAK_CLIENT_SECRET=1234
|
31
|
+
- KEYCLOAK_SCOPE=openid
|
32
|
+
ports:
|
33
|
+
- "7777:8080"
|
34
|
+
volumes:
|
35
|
+
- ./ci/oauth/keycloak/standalone.xml:/opt/jboss/keycloak/standalone/configuration/standalone.xml
|
36
|
+
- ./ci/oauth/keycloak:/scripts
|
16
37
|
|
17
38
|
conjur_4:
|
18
39
|
image: registry2.itci.conjur.net/conjur-appliance-cuke-master:4.9-stable
|
@@ -33,6 +54,7 @@ services:
|
|
33
54
|
- ./features/reports:/src/conjur-api/features/reports
|
34
55
|
- ./coverage:/src/conjur-api/coverage
|
35
56
|
- authn_local_5:/run/authn-local-5
|
57
|
+
- ./ci/oauth/keycloak:/scripts
|
36
58
|
environment:
|
37
59
|
CONJUR_APPLIANCE_URL: http://conjur_5
|
38
60
|
CONJUR_VERSION: 5
|
@@ -7,6 +7,7 @@ Feature: List and manage authenticators
|
|
7
7
|
- !webservice conjur/authn-k8s/my-auth
|
8
8
|
POLICY
|
9
9
|
"""
|
10
|
+
And I setup a keycloak authenticator
|
10
11
|
|
11
12
|
Scenario: Authenticator list includes the authenticator status
|
12
13
|
When I run the code:
|
@@ -31,3 +32,10 @@ Feature: List and manage authenticators
|
|
31
32
|
$conjur.authenticator_list
|
32
33
|
"""
|
33
34
|
Then the JSON at "enabled" should be ["authn"]
|
35
|
+
|
36
|
+
Scenario: Get a list of OIDC providers
|
37
|
+
When I run the code:
|
38
|
+
"""
|
39
|
+
$conjur.authentication_providers("authn-oidc")
|
40
|
+
"""
|
41
|
+
Then the providers list contains service id "keycloak"
|
@@ -0,0 +1,14 @@
|
|
1
|
+
Feature: Authenticate with Conjur
|
2
|
+
|
3
|
+
Background:
|
4
|
+
Given I setup a keycloak authenticator
|
5
|
+
|
6
|
+
Scenario: Authenticate with OIDC state and code
|
7
|
+
When I retrieve the login url for OIDC authenticator "keycloak"
|
8
|
+
And I retrieve auth info for the OIDC provider with username: "alice" and password: "alice"
|
9
|
+
And I run the code:
|
10
|
+
"""
|
11
|
+
$conjur.authenticator_enable "authn-oidc", "keycloak"
|
12
|
+
Conjur::API.authenticator_authenticate("authn-oidc", "keycloak", options: @auth_body)
|
13
|
+
"""
|
14
|
+
Then the JSON should have "payload"
|
@@ -16,3 +16,37 @@ Then(/^this code should fail with "([^"]*)"$/) do |error_msg, code|
|
|
16
16
|
fail "The provided block did not raise an error"
|
17
17
|
end
|
18
18
|
end
|
19
|
+
|
20
|
+
Given(/^I retrieve the login url for OIDC authenticator "([^"]+)"$/) do |service_id|
|
21
|
+
provider = $conjur.authentication_providers("authn-oidc").select {|provider_details| provider_details["service_id"] == service_id}
|
22
|
+
@login_url = provider[0]["redirect_uri"]
|
23
|
+
puts @login_url
|
24
|
+
end
|
25
|
+
|
26
|
+
Given(/^I retrieve auth info for the OIDC provider with username: "([^"]+)" and password: "([^"]+)"$/) do |username, password|
|
27
|
+
res = Net::HTTP.get_response(URI(@login_url))
|
28
|
+
raise res if res.is_a?(Net::HTTPError) || res.is_a?(Net::HTTPClientError)
|
29
|
+
|
30
|
+
all_cookies = res.get_fields('set-cookie')
|
31
|
+
puts all_cookies
|
32
|
+
cookies_arrays = Array.new
|
33
|
+
all_cookies.each do |cookie|
|
34
|
+
cookies_arrays.push(cookie.split('; ')[0])
|
35
|
+
end
|
36
|
+
|
37
|
+
html = Nokogiri::HTML(res.body)
|
38
|
+
post_uri = URI(html.xpath('//form').first.attributes['action'].value)
|
39
|
+
|
40
|
+
http = Net::HTTP.new(post_uri.host, post_uri.port)
|
41
|
+
http.use_ssl = true
|
42
|
+
request = Net::HTTP::Post.new(post_uri.request_uri)
|
43
|
+
request['Cookie'] = cookies_arrays.join('; ')
|
44
|
+
request.set_form_data({'username' => username, 'password' => password})
|
45
|
+
|
46
|
+
response = http.request(request)
|
47
|
+
|
48
|
+
if response.is_a?(Net::HTTPRedirection)
|
49
|
+
response_details = URI.decode_www_form(URI(response['location']).query)
|
50
|
+
@auth_body = {state: response_details.assoc('state')[1], code: response_details.assoc('code')[1]}
|
51
|
+
end
|
52
|
+
end
|
@@ -13,6 +13,15 @@ Given(/^a new user$/) do
|
|
13
13
|
expect(@user_api_key).to be
|
14
14
|
end
|
15
15
|
|
16
|
+
Given(/^a user "([^"]+)"$/) do |user_id|
|
17
|
+
response = $conjur.load_policy 'root', <<-POLICY
|
18
|
+
- !user #{user_id}
|
19
|
+
POLICY
|
20
|
+
@user = $conjur.resource("cucumber:user:#{user_id}")
|
21
|
+
@user_api_key = response.created_roles["cucumber:user:#{user_id}"]['api_key']
|
22
|
+
expect(@user_api_key).to be
|
23
|
+
end
|
24
|
+
|
16
25
|
Given(/^a new delegated user$/) do
|
17
26
|
# Create a new host that is owned by that user
|
18
27
|
step 'a new user'
|
@@ -73,3 +82,53 @@ Given(/^a new delegated host$/) do
|
|
73
82
|
@host = $conjur.resource("cucumber:host:#{@host_id}")
|
74
83
|
@host.attributes['api_key'] = @host_api_key
|
75
84
|
end
|
85
|
+
|
86
|
+
Given(/^I setup a keycloak authenticator$/) do
|
87
|
+
$conjur.load_policy 'root', <<-POLICY
|
88
|
+
- !policy
|
89
|
+
id: conjur/authn-oidc/keycloak
|
90
|
+
body:
|
91
|
+
- !webservice
|
92
|
+
|
93
|
+
- !variable provider-uri
|
94
|
+
- !variable client-id
|
95
|
+
- !variable client-secret
|
96
|
+
- !variable name
|
97
|
+
|
98
|
+
- !variable claim-mapping
|
99
|
+
|
100
|
+
- !variable nonce
|
101
|
+
- !variable state
|
102
|
+
|
103
|
+
- !variable redirect-uri
|
104
|
+
|
105
|
+
- !group users
|
106
|
+
|
107
|
+
- !permit
|
108
|
+
role: !group users
|
109
|
+
privilege: [ read, authenticate ]
|
110
|
+
resource: !webservice
|
111
|
+
|
112
|
+
- !user alice
|
113
|
+
- !grant
|
114
|
+
role: !group conjur/authn-oidc/keycloak/users
|
115
|
+
member: !user alice
|
116
|
+
POLICY
|
117
|
+
@provider_uri = $conjur.resource("cucumber:variable:conjur/authn-oidc/keycloak/provider-uri")
|
118
|
+
@client_id = $conjur.resource("cucumber:variable:conjur/authn-oidc/keycloak/client-id")
|
119
|
+
@client_secret = $conjur.resource("cucumber:variable:conjur/authn-oidc/keycloak/client-secret")
|
120
|
+
@name = $conjur.resource("cucumber:variable:conjur/authn-oidc/keycloak/name")
|
121
|
+
@claim_mapping = $conjur.resource("cucumber:variable:conjur/authn-oidc/keycloak/claim-mapping")
|
122
|
+
@nonce = $conjur.resource("cucumber:variable:conjur/authn-oidc/keycloak/nonce")
|
123
|
+
@state = $conjur.resource("cucumber:variable:conjur/authn-oidc/keycloak/state")
|
124
|
+
@redirect_uri = $conjur.resource("cucumber:variable:conjur/authn-oidc/keycloak/redirect-uri")
|
125
|
+
|
126
|
+
@provider_uri.add_value "https://keycloak:8443/auth/realms/master"
|
127
|
+
@client_id.add_value "conjurClient"
|
128
|
+
@client_secret.add_value "1234"
|
129
|
+
@claim_mapping.add_value "preferred_username"
|
130
|
+
@nonce.add_value SecureRandom.uuid
|
131
|
+
@state.add_value SecureRandom.uuid
|
132
|
+
@name.add_value "keycloak"
|
133
|
+
@redirect_uri.add_value "http://conjur_5/authn-oidc/keycloak/cucumber/authenticate"
|
134
|
+
end
|
data/features/support/env.rb
CHANGED
@@ -13,6 +13,14 @@ module Conjur
|
|
13
13
|
JSON.parse(url_for(:authenticators).get)
|
14
14
|
end
|
15
15
|
|
16
|
+
# Fetches the available authentication providers for the authenticator and account.
|
17
|
+
# The authenticators must be loaded in Conjur policy prior to fetching.
|
18
|
+
#
|
19
|
+
# @param [String] authenticator the authenticator type to retrieve providers for
|
20
|
+
def authentication_providers authenticator, account: Conjur.configuration.account
|
21
|
+
JSON.parse(url_for(:authentication_providers, account, authenticator, credentials).get)
|
22
|
+
end
|
23
|
+
|
16
24
|
# Enables an authenticator in Conjur. The authenticator must be defined and
|
17
25
|
# loaded in Conjur policy prior to enabling it.
|
18
26
|
#
|
data/lib/conjur/api/authn.rb
CHANGED
@@ -22,6 +22,10 @@ require 'conjur/user'
|
|
22
22
|
|
23
23
|
module Conjur
|
24
24
|
class API
|
25
|
+
def whoami
|
26
|
+
JSON.parse(url_for(:whoami, credentials).get)
|
27
|
+
end
|
28
|
+
|
25
29
|
class << self
|
26
30
|
#@!group Authentication
|
27
31
|
|
@@ -50,6 +54,21 @@ module Conjur
|
|
50
54
|
url_for(:authn_login, account, username, password).get
|
51
55
|
end
|
52
56
|
|
57
|
+
# Authenticates using a third party authenticator like authn-oidc. It will return an
|
58
|
+
# access token to be used to authenticate further API calls.
|
59
|
+
#
|
60
|
+
# @param [String] authenticator
|
61
|
+
# @param [String] service_id
|
62
|
+
# @param [String] account The organization account.
|
63
|
+
# @param [Hash] params Additional params to send to authenticator
|
64
|
+
# @return [String] A JSON formatted authentication token.
|
65
|
+
def authenticator_authenticate authenticator, service_id, account: Conjur.configuration.account, options: {}
|
66
|
+
if Conjur.log
|
67
|
+
Conjur.log << "Authenticating to account #{account} using #{authenticator}/#{service_id}\n"
|
68
|
+
end
|
69
|
+
JSON.parse url_for(:authenticator_authenticate, account, service_id, authenticator, options).get
|
70
|
+
end
|
71
|
+
|
53
72
|
# Exchanges Conjur the API key (refresh token) for an access token. The access token can
|
54
73
|
# then be used to authenticate further API calls.
|
55
74
|
#
|
data/lib/conjur/api/router/v5.rb
CHANGED
@@ -43,6 +43,13 @@ module Conjur
|
|
43
43
|
)[fully_escape account][fully_escape username]['authenticate']
|
44
44
|
end
|
45
45
|
|
46
|
+
def authenticator_authenticate(account, service_id, authenticator, options)
|
47
|
+
RestClient::Resource.new(
|
48
|
+
Conjur.configuration.core_url,
|
49
|
+
Conjur.configuration.rest_client_options
|
50
|
+
)[fully_escape authenticator][fully_escape service_id][fully_escape account]['authenticate'][options_querystring options]
|
51
|
+
end
|
52
|
+
|
46
53
|
def authenticator account, authenticator, service_id, credentials
|
47
54
|
RestClient::Resource.new(
|
48
55
|
Conjur.configuration.core_url,
|
@@ -57,6 +64,13 @@ module Conjur
|
|
57
64
|
)['authenticators']
|
58
65
|
end
|
59
66
|
|
67
|
+
def authentication_providers(account, authenticator, credentials)
|
68
|
+
RestClient::Resource.new(
|
69
|
+
Conjur.configuration.core_url,
|
70
|
+
Conjur.configuration.create_rest_client_options(credentials)
|
71
|
+
)[fully_escape authenticator][fully_escape account]['providers']
|
72
|
+
end
|
73
|
+
|
60
74
|
# For v5, the authn-local message is a JSON string with account, sub, and optional fields.
|
61
75
|
def authn_authenticate_local username, account, expiration, cidr, &block
|
62
76
|
{ account: account, sub: username }.tap do |params|
|
@@ -236,6 +250,13 @@ module Conjur
|
|
236
250
|
)['ldap-sync']["policy?config_name=#{fully_escape(config_name)}"]
|
237
251
|
end
|
238
252
|
|
253
|
+
def whoami(credentials)
|
254
|
+
RestClient::Resource.new(
|
255
|
+
Conjur.configuration.core_url,
|
256
|
+
Conjur.configuration.create_rest_client_options(credentials)
|
257
|
+
)['whoami']
|
258
|
+
end
|
259
|
+
|
239
260
|
private
|
240
261
|
|
241
262
|
def resource_annotations resource
|
data/test.sh
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
# My local RUBY_VERSION is set to ruby-#.#.# so this allows running locally.
|
5
5
|
RUBY_VERSION="$(cut -d '-' -f 2 <<< "$RUBY_VERSION")"
|
6
6
|
|
7
|
+
source ./ci/oauth/keycloak/keycloak_functions.sh
|
7
8
|
|
8
9
|
function finish {
|
9
10
|
echo 'Removing test environment'
|
@@ -54,7 +55,9 @@ function runTests_5() {
|
|
54
55
|
echo '-----'
|
55
56
|
docker-compose run --rm \
|
56
57
|
-e CONJUR_AUTHN_API_KEY="$api_key" \
|
57
|
-
|
58
|
+
-e SSL_CERT_FILE=/etc/ssl/certs/keycloak.pem \
|
59
|
+
tester_5 \
|
60
|
+
"/scripts/fetch_certificate && rake jenkins_init jenkins_spec jenkins_cucumber_v5"
|
58
61
|
}
|
59
62
|
|
60
63
|
function runTests_4() {
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: conjur-api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.4.0.pre.341
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- CyberArk Maintainers
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-08-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rest-client
|
@@ -226,6 +226,20 @@ dependencies:
|
|
226
226
|
- - ">="
|
227
227
|
- !ruby/object:Gem::Version
|
228
228
|
version: '0'
|
229
|
+
- !ruby/object:Gem::Dependency
|
230
|
+
name: nokogiri
|
231
|
+
requirement: !ruby/object:Gem::Requirement
|
232
|
+
requirements:
|
233
|
+
- - ">="
|
234
|
+
- !ruby/object:Gem::Version
|
235
|
+
version: '0'
|
236
|
+
type: :development
|
237
|
+
prerelease: false
|
238
|
+
version_requirements: !ruby/object:Gem::Requirement
|
239
|
+
requirements:
|
240
|
+
- - ">="
|
241
|
+
- !ruby/object:Gem::Version
|
242
|
+
version: '0'
|
229
243
|
description: Conjur API
|
230
244
|
email:
|
231
245
|
- conj_maintainers@cyberark.com
|
@@ -257,6 +271,12 @@ files:
|
|
257
271
|
- bin/parse-changelog.sh
|
258
272
|
- ci/configure_v4.sh
|
259
273
|
- ci/configure_v5.sh
|
274
|
+
- ci/oauth/keycloak/create_client
|
275
|
+
- ci/oauth/keycloak/create_user
|
276
|
+
- ci/oauth/keycloak/fetch_certificate
|
277
|
+
- ci/oauth/keycloak/keycloak_functions.sh
|
278
|
+
- ci/oauth/keycloak/standalone.xml
|
279
|
+
- ci/oauth/keycloak/wait_for_server
|
260
280
|
- ci/submit-coverage
|
261
281
|
- conjur-api.gemspec
|
262
282
|
- dev/Dockerfile.dev
|
@@ -267,6 +287,7 @@ files:
|
|
267
287
|
- example/demo_v4.rb
|
268
288
|
- example/demo_v5.rb
|
269
289
|
- features/authenticators.feature
|
290
|
+
- features/authn.feature
|
270
291
|
- features/authn_local.feature
|
271
292
|
- features/exists.feature
|
272
293
|
- features/group.feature
|
@@ -378,7 +399,7 @@ homepage: https://github.com/cyberark/conjur-api-ruby/
|
|
378
399
|
licenses:
|
379
400
|
- Apache-2.0
|
380
401
|
metadata: {}
|
381
|
-
post_install_message:
|
402
|
+
post_install_message:
|
382
403
|
rdoc_options: []
|
383
404
|
require_paths:
|
384
405
|
- lib
|
@@ -393,13 +414,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
393
414
|
- !ruby/object:Gem::Version
|
394
415
|
version: 1.3.1
|
395
416
|
requirements: []
|
396
|
-
|
397
|
-
|
398
|
-
signing_key:
|
417
|
+
rubygems_version: 3.2.33
|
418
|
+
signing_key:
|
399
419
|
specification_version: 4
|
400
420
|
summary: Conjur API
|
401
421
|
test_files:
|
402
422
|
- features/authenticators.feature
|
423
|
+
- features/authn.feature
|
403
424
|
- features/authn_local.feature
|
404
425
|
- features/exists.feature
|
405
426
|
- features/group.feature
|