aws-cognito-srp 0.4.0 → 0.5.0
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.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +5 -4
- data/CHANGELOG.md +4 -0
- data/README.md +21 -6
- data/aws-cognito-srp.gemspec +4 -2
- data/lib/aws/cognito_srp/version.rb +1 -1
- data/lib/aws/cognito_srp.rb +32 -29
- metadata +9 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 929d703154eb252230b0ec365cf85bb59e632e62a335bcf63d81c0168f6fe3d3
|
4
|
+
data.tar.gz: 2b857f9bcf58f8363eae7ad056de998758bfaf6458ca478d41e4398b57d34a11
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5763f4fac8412527c21ecfb3ae0e283e4cf7be33fc5eadbc94325c83b1b0aa91d34cfc86ebad7895c9f1e1fad93e8c7f8f0f08180f4219d4f78e1ff63d9cf0c1
|
7
|
+
data.tar.gz: 13e4d566a91689460b4aca21d48b73a3655d336dfc3e07e0e8c505b107606489581b720d045c72e0ebc2aea27d59a79c76eeba5cb3be77965818b69cb259f10d
|
data/.github/workflows/ci.yml
CHANGED
@@ -7,14 +7,15 @@ jobs:
|
|
7
7
|
strategy:
|
8
8
|
fail-fast: false
|
9
9
|
matrix:
|
10
|
-
|
10
|
+
os: [ubuntu-latest, macos-latest]
|
11
|
+
ruby: [2.4, 2.5, 2.6, 2.7, '3.0', 3.1, 3.2, jruby, truffleruby]
|
11
12
|
|
12
|
-
runs-on:
|
13
|
+
runs-on: ${{ matrix.os }}
|
13
14
|
|
14
|
-
name: Test against
|
15
|
+
name: Test against ${{ matrix.ruby }} on ${{ matrix.os }}
|
15
16
|
|
16
17
|
steps:
|
17
|
-
- uses: actions/checkout@
|
18
|
+
- uses: actions/checkout@v3
|
18
19
|
- name: Set up Ruby
|
19
20
|
uses: ruby/setup-ruby@v1
|
20
21
|
with:
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -25,11 +25,12 @@ gem 'aws-cognito-srp'
|
|
25
25
|
require "aws-cognito-srp"
|
26
26
|
|
27
27
|
aws_srp = Aws::CognitoSrp.new(
|
28
|
-
username:
|
29
|
-
password:
|
30
|
-
pool_id:
|
31
|
-
client_id:
|
32
|
-
|
28
|
+
username: "username",
|
29
|
+
password: "password",
|
30
|
+
pool_id: "pool-id",
|
31
|
+
client_id: "client-id",
|
32
|
+
client_secret: "client-secret", # Optional
|
33
|
+
aws_client: Aws::CognitoIdentityProvider::Client.new(region: "aws-region")
|
33
34
|
)
|
34
35
|
|
35
36
|
resp = aws_srp.authenticate
|
@@ -44,9 +45,23 @@ resp.refresh_token
|
|
44
45
|
new_tokens = aws_srp.refresh_tokens(resp.refresh_token)
|
45
46
|
```
|
46
47
|
|
48
|
+
In case you need access to the `USER_ID_FOR_SRP` value from the auth response,
|
49
|
+
you can do so by calling `aws_srp.user_id_for_srp` *after* the initial auth
|
50
|
+
(`aws_srp` being the same as in the code example above).
|
51
|
+
|
52
|
+
If you're using a `client_secret` and calling `#refresh_tokens` in a different
|
53
|
+
instance than the one that performed the initial call to `#authenticate` you
|
54
|
+
will have to pass the `USER_ID_FOR_SRP` value as a keyword argument:
|
55
|
+
|
56
|
+
```ruby
|
57
|
+
new_tokens = aws_srp.refresh_token(resp.refresh_token,
|
58
|
+
user_id_for_srp: your_user_id_for_srp)
|
59
|
+
```
|
60
|
+
|
47
61
|
## Supported rubies
|
48
62
|
|
49
|
-
This gem is tested against and supports Ruby 2.
|
63
|
+
This gem is tested against and supports Ruby 2.4 through 3.2, JRuby and
|
64
|
+
TruffleRuby.
|
50
65
|
|
51
66
|
## Development
|
52
67
|
|
data/aws-cognito-srp.gemspec
CHANGED
@@ -20,11 +20,13 @@ Gem::Specification.new do |spec|
|
|
20
20
|
end
|
21
21
|
spec.require_paths = ["lib"]
|
22
22
|
|
23
|
+
spec.required_ruby_version = '>= 2.4.0'
|
24
|
+
|
23
25
|
spec.add_dependency "aws-sdk-cognitoidentityprovider"
|
24
26
|
|
25
|
-
spec.add_development_dependency "bundler", "~> 2.2
|
27
|
+
spec.add_development_dependency "bundler", "~> 2.2"
|
26
28
|
spec.add_development_dependency "rake", "~> 13.0"
|
27
|
-
spec.add_development_dependency "
|
29
|
+
spec.add_development_dependency "nokogiri", "~> 1.9"
|
28
30
|
spec.add_development_dependency "rspec", "~> 3.0"
|
29
31
|
spec.add_development_dependency "pry"
|
30
32
|
|
data/lib/aws/cognito_srp.rb
CHANGED
@@ -24,19 +24,6 @@ if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("2.5")
|
|
24
24
|
using IntegerWithPow
|
25
25
|
end
|
26
26
|
|
27
|
-
if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("2.4")
|
28
|
-
module StringWithUnpack1
|
29
|
-
refine String do
|
30
|
-
# String#unpack1 was introduced in Ruby 2.4
|
31
|
-
def unpack1(fmt)
|
32
|
-
unpack(fmt)[0]
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
using StringWithUnpack1
|
38
|
-
end
|
39
|
-
|
40
27
|
module Aws
|
41
28
|
# Client for AWS Cognito Identity Provider using Secure Remote Password (SRP).
|
42
29
|
#
|
@@ -85,12 +72,15 @@ module Aws
|
|
85
72
|
|
86
73
|
INFO_BITS = 'Caldera Derived Key'
|
87
74
|
|
88
|
-
|
75
|
+
attr_reader :user_id_for_srp
|
76
|
+
|
77
|
+
def initialize(username:, password:, pool_id:, client_id:, aws_client:, client_secret: nil)
|
89
78
|
@username = username
|
90
79
|
@password = password
|
91
80
|
@pool_id = pool_id
|
92
81
|
@client_id = client_id
|
93
82
|
@aws_client = aws_client
|
83
|
+
@client_secret = client_secret
|
94
84
|
|
95
85
|
@big_n = hex_to_long(N_HEX)
|
96
86
|
@g = hex_to_long(G_HEX)
|
@@ -100,13 +90,16 @@ module Aws
|
|
100
90
|
end
|
101
91
|
|
102
92
|
def authenticate
|
93
|
+
auth_parameters = {
|
94
|
+
USERNAME: @username,
|
95
|
+
SRP_A: long_to_hex(@large_a_value),
|
96
|
+
SECRET_HASH: @client_secret && secret_hash(@username)
|
97
|
+
}.compact
|
98
|
+
|
103
99
|
init_auth_response = @aws_client.initiate_auth(
|
104
100
|
client_id: @client_id,
|
105
101
|
auth_flow: USER_SRP_AUTH,
|
106
|
-
auth_parameters:
|
107
|
-
USERNAME: @username,
|
108
|
-
SRP_A: long_to_hex(@large_a_value)
|
109
|
-
}
|
102
|
+
auth_parameters: auth_parameters
|
110
103
|
)
|
111
104
|
|
112
105
|
unless init_auth_response.challenge_name == PASSWORD_VERIFIER
|
@@ -114,12 +107,15 @@ module Aws
|
|
114
107
|
end
|
115
108
|
|
116
109
|
challenge_response = process_challenge(init_auth_response.challenge_parameters)
|
110
|
+
hash = @client_secret && secret_hash(@user_id_for_srp)
|
117
111
|
|
118
|
-
|
112
|
+
params = {
|
119
113
|
client_id: @client_id,
|
120
114
|
challenge_name: PASSWORD_VERIFIER,
|
121
|
-
challenge_responses: challenge_response
|
122
|
-
|
115
|
+
challenge_responses: challenge_response.merge(SECRET_HASH: hash).compact
|
116
|
+
}
|
117
|
+
|
118
|
+
auth_response = @aws_client.respond_to_auth_challenge(params)
|
123
119
|
|
124
120
|
if auth_response.challenge_name == NEW_PASSWORD_REQUIRED
|
125
121
|
raise NewPasswordRequired, "Cognito responded to password verifier with a #{NEW_PASSWORD_REQUIRED} challenge"
|
@@ -128,13 +124,16 @@ module Aws
|
|
128
124
|
auth_response.authentication_result
|
129
125
|
end
|
130
126
|
|
131
|
-
def refresh_tokens(refresh_token)
|
127
|
+
def refresh_tokens(refresh_token, user_id_for_srp: @user_id_for_srp)
|
128
|
+
auth_parameters = {
|
129
|
+
REFRESH_TOKEN: refresh_token,
|
130
|
+
SECRET_HASH: @client_secret && secret_hash(user_id_for_srp)
|
131
|
+
}.compact
|
132
|
+
|
132
133
|
resp = @aws_client.initiate_auth(
|
133
134
|
client_id: @client_id,
|
134
135
|
auth_flow: REFRESH_TOKEN,
|
135
|
-
auth_parameters:
|
136
|
-
REFRESH_TOKEN: refresh_token
|
137
|
-
}
|
136
|
+
auth_parameters: auth_parameters
|
138
137
|
)
|
139
138
|
|
140
139
|
resp.authentication_result
|
@@ -170,22 +169,22 @@ module Aws
|
|
170
169
|
end
|
171
170
|
|
172
171
|
def process_challenge(challenge_parameters)
|
173
|
-
user_id_for_srp = challenge_parameters.fetch("USER_ID_FOR_SRP")
|
172
|
+
@user_id_for_srp = challenge_parameters.fetch("USER_ID_FOR_SRP")
|
174
173
|
salt_hex = challenge_parameters.fetch("SALT")
|
175
174
|
srp_b_hex = challenge_parameters.fetch("SRP_B")
|
176
175
|
secret_block_b64 = challenge_parameters.fetch("SECRET_BLOCK")
|
177
176
|
|
178
177
|
timestamp = ::Time.now.utc.strftime("%a %b %-d %H:%M:%S %Z %Y")
|
179
178
|
|
180
|
-
hkdf = get_password_authentication_key(user_id_for_srp, @password, srp_b_hex.to_i(16), salt_hex)
|
179
|
+
hkdf = get_password_authentication_key(@user_id_for_srp, @password, srp_b_hex.to_i(16), salt_hex)
|
181
180
|
secret_block_bytes = ::Base64.strict_decode64(secret_block_b64)
|
182
|
-
msg = @pool_id.split("_")[1] + user_id_for_srp + secret_block_bytes + timestamp
|
181
|
+
msg = @pool_id.split("_")[1] + @user_id_for_srp + secret_block_bytes + timestamp
|
183
182
|
hmac_digest = ::OpenSSL::HMAC.digest(::OpenSSL::Digest::SHA256.new, hkdf, msg)
|
184
183
|
signature_string = ::Base64.strict_encode64(hmac_digest).force_encoding('utf-8')
|
185
184
|
|
186
185
|
{
|
187
186
|
TIMESTAMP: timestamp,
|
188
|
-
USERNAME: user_id_for_srp,
|
187
|
+
USERNAME: @user_id_for_srp,
|
189
188
|
PASSWORD_CLAIM_SECRET_BLOCK: secret_block_b64,
|
190
189
|
PASSWORD_CLAIM_SIGNATURE: signature_string
|
191
190
|
}
|
@@ -242,5 +241,9 @@ module Aws
|
|
242
241
|
u_hex_hash = hex_hash(pad_hex(big_a) + pad_hex(big_b))
|
243
242
|
hex_to_long(u_hex_hash)
|
244
243
|
end
|
244
|
+
|
245
|
+
def secret_hash(username)
|
246
|
+
Base64.strict_encode64(OpenSSL::HMAC.digest('sha256', @client_secret, username + @client_id))
|
247
|
+
end
|
245
248
|
end
|
246
249
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aws-cognito-srp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonathan Viney
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2023-02-14 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: aws-sdk-cognitoidentityprovider
|
@@ -32,14 +32,14 @@ dependencies:
|
|
32
32
|
requirements:
|
33
33
|
- - "~>"
|
34
34
|
- !ruby/object:Gem::Version
|
35
|
-
version: 2.2
|
35
|
+
version: '2.2'
|
36
36
|
type: :development
|
37
37
|
prerelease: false
|
38
38
|
version_requirements: !ruby/object:Gem::Requirement
|
39
39
|
requirements:
|
40
40
|
- - "~>"
|
41
41
|
- !ruby/object:Gem::Version
|
42
|
-
version: 2.2
|
42
|
+
version: '2.2'
|
43
43
|
- !ruby/object:Gem::Dependency
|
44
44
|
name: rake
|
45
45
|
requirement: !ruby/object:Gem::Requirement
|
@@ -55,19 +55,19 @@ dependencies:
|
|
55
55
|
- !ruby/object:Gem::Version
|
56
56
|
version: '13.0'
|
57
57
|
- !ruby/object:Gem::Dependency
|
58
|
-
name:
|
58
|
+
name: nokogiri
|
59
59
|
requirement: !ruby/object:Gem::Requirement
|
60
60
|
requirements:
|
61
61
|
- - "~>"
|
62
62
|
- !ruby/object:Gem::Version
|
63
|
-
version:
|
63
|
+
version: '1.9'
|
64
64
|
type: :development
|
65
65
|
prerelease: false
|
66
66
|
version_requirements: !ruby/object:Gem::Requirement
|
67
67
|
requirements:
|
68
68
|
- - "~>"
|
69
69
|
- !ruby/object:Gem::Version
|
70
|
-
version:
|
70
|
+
version: '1.9'
|
71
71
|
- !ruby/object:Gem::Dependency
|
72
72
|
name: rspec
|
73
73
|
requirement: !ruby/object:Gem::Requirement
|
@@ -132,14 +132,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
132
132
|
requirements:
|
133
133
|
- - ">="
|
134
134
|
- !ruby/object:Gem::Version
|
135
|
-
version:
|
135
|
+
version: 2.4.0
|
136
136
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
137
137
|
requirements:
|
138
138
|
- - ">="
|
139
139
|
- !ruby/object:Gem::Version
|
140
140
|
version: '0'
|
141
141
|
requirements: []
|
142
|
-
rubygems_version: 3.
|
142
|
+
rubygems_version: 3.3.3
|
143
143
|
signing_key:
|
144
144
|
specification_version: 4
|
145
145
|
summary: AWS Cognito SRP auth for Ruby
|