Skip to content

Commit

Permalink
feature: authorization_code grant with public client usage (#123)
Browse files Browse the repository at this point in the history
* feature: authorization_code grant with public client usage

add PKCE to authorization code
optional allow to omit client_secret

* Add dependency for supported PKCE

* Bump actions/checkout from 3 to 4

Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](actions/checkout@v3...v4)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>

* Use PKCE by default

---------

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
  • Loading branch information
strehle and dependabot[bot] authored Sep 12, 2023
1 parent 257a832 commit 9011ec2
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 11 deletions.
2 changes: 1 addition & 1 deletion cf-uaac.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Gem::Specification.new do |s|
s.require_paths = ['lib']

# dependencies
s.add_runtime_dependency 'cf-uaa-lib', '~> 4.0'
s.add_runtime_dependency 'cf-uaa-lib', '~> 4.0.3'
s.add_development_dependency 'rake', '~> 13.0'
s.add_development_dependency 'rspec', '~> 3.12'
s.add_development_dependency 'simplecov', '~> 0.22.0'
Expand Down
27 changes: 17 additions & 10 deletions lib/uaa/cli/token.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,14 @@ class TokenCatcher < Stub::Base
def process_grant(data)
server.logger.debug "processing grant for path #{request.path}"
secret = server.info.delete(:client_secret)
do_authcode = server.info.delete(:do_authcode)
ti = TokenIssuer.new(Config.target, server.info.delete(:client_id), secret,
{ token_target: Config.target_value(:token_target),
basic_auth: Config.target_value(:basic_auth),
use_pkce: true,
code_verifier: server.info.delete(:code_verifier),
skip_ssl_validation: Config.target_value(:skip_ssl_validation)})
tkn = secret ? ti.authcode_grant(server.info.delete(:uri), data) :
tkn = do_authcode ? ti.authcode_grant(server.info.delete(:uri), data) :
ti.implicit_grant(server.info.delete(:uri), data)
server.info.update(token_info: tkn.info)
reply.text "you are now logged in and can close this window"
Expand Down Expand Up @@ -87,11 +90,13 @@ def set_context(token_info)
did_save
end

def issuer_request(client_id, secret = nil)
def issuer_request(client_id, secret = nil, code_verifier = nil)
update_target_info
yield TokenIssuer.new(Config.target.to_s, client_id, secret,
{ token_target: Config.target_value(:token_endpoint),
basic_auth: Config.target_value(:basic_auth),
use_pkce: true,
code_verifier: code_verifier,
skip_ssl_validation: Config.target_value(:skip_ssl_validation),
ssl_ca_file: Config.target_value(:ca_cert) })
rescue Exception => e
Expand Down Expand Up @@ -159,24 +164,26 @@ def issuer_request(client_id, secret = nil)
CF_TOKEN_FILE = File.join ENV["HOME"], ".cf_token"
CF_TARGET_FILE = File.join ENV["HOME"], ".cf_target"

def use_browser(client_id, secret = nil)
def use_browser(client_id, secret = nil, grant = nil)
do_authcode = (not grant.nil?) && (grant == 'authcode')
code_verifier = SecureRandom.base64(96).tr("+/", "-_").tr("=", "")
catcher = Stub::Server.new(TokenCatcher,
logger: Util.default_logger(debug? ? :debug : trace? ? :trace : :info),
info: {client_id: client_id, client_secret: secret},
info: {client_id: client_id, client_secret: secret, code_verifier: code_verifier, do_authcode: do_authcode},
port: opts[:port]).run_on_thread
uri = issuer_request(client_id, secret) { |ti|
secret ? ti.authcode_uri("#{catcher.url}/authcode", opts[:scope]) :
uri = issuer_request(client_id, secret, code_verifier) { |ti|
do_authcode ? ti.authcode_uri("#{catcher.url}/authcode", opts[:scope]) :
ti.implicit_uri("#{catcher.url}/callback", opts[:scope])
}
return unless catcher.info[:uri] = uri
say "launching browser with #{uri}" if trace?
Launchy.open(uri, debug: true, dry_run: false)
say " and launching browser with #{uri}"
Launchy.open(uri, debug: false, dry_run: false)
print "waiting for token "
while catcher.info[:uri] || !catcher.info[:token_info]
sleep 5
print "."
end
say_success(secret ? "authorization code" : "implicit") if set_context(catcher.info[:token_info])
say_success(do_authcode ? "authorization code" : "implicit") if set_context(catcher.info[:token_info])
return unless opts[:cf]
begin
cf_target = File.open(CF_TARGET_FILE, 'r') { |f| f.read.strip }
Expand All @@ -193,7 +200,7 @@ def use_browser(client_id, secret = nil)
define_option :port, "--port <number>", "pin internal server to specific port"
define_option :cf, "--[no-]cf", "save token in the ~/.cf_tokens file"
desc "token authcode get", "Gets a token using the authcode flow with browser",
:client, :secret, :scope, :cf, :port do use_browser(clientid, clientsecret) end
:client, :secret, :scope, :cf, :port do use_browser(clientid, opts[:secret], 'authcode') end

desc "token implicit get", "Gets a token using the implicit flow with browser",
:client, :scope, :cf, :port do use_browser opts[:client] || "cf" end
Expand Down

0 comments on commit 9011ec2

Please sign in to comment.