From 9b267c499709472cd20d95df76b53fc6c571e797 Mon Sep 17 00:00:00 2001 From: mo khan Date: Wed, 12 Mar 2025 16:15:20 -0600 Subject: feat: require a login before authorizing an auth grant --- bin/idp | 53 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 18 deletions(-) (limited to 'bin/idp') diff --git a/bin/idp b/bin/idp index 69c947b..3aeeb07 100755 --- a/bin/idp +++ b/bin/idp @@ -89,8 +89,11 @@ module Authn end end + attr_reader :id + def initialize(attributes) @attributes = attributes + @id = self[:id] end def [](attribute) @@ -106,7 +109,7 @@ module Authn end def create_access_token - ::Authz::JWT.new(sub: self[:id], iat: Time.now.to_i) + ::Authz::JWT.new(sub: to_global_id.to_s, iat: Time.now.to_i) end def assertion_attributes_for(request) @@ -118,6 +121,10 @@ module Authn def valid_password?(entered_password) ::BCrypt::Password.new(self[:password_digest]) == entered_password end + + def to_global_id + ::GlobalID.create(self, app: "example").to_s + end end class OnDemandRegistry < Saml::Kit::DefaultRegistry @@ -139,6 +146,7 @@ module Authn when Rack::GET case request.path when '/sessions/new' + request.session.delete(:user_id) return get_login(request) end when Rack::POST @@ -376,29 +384,38 @@ module Authz case request.request_method when Rack::GET - case request.path_info - when "/authorize" # RFC-6749 + case request.path + when "/oauth/authorize/continue" + if current_user?(request) + return get_authorize(request.session[:oauth_params]) + end + when "/oauth/authorize" # RFC-6749 + oauth_params = request.params.slice('client_id', 'scope', 'redirect_uri', 'response_mode', 'response_type', 'state', 'code_challenge_method', 'code_challenge') if current_user?(request) - return get_authorize(request) + return get_authorize(oauth_params) else - http_redirect_to("/saml/") + request.session[:oauth_params] = oauth_params + return http_redirect_to("/sessions/new?redirect_back=/oauth/authorize/continue") end else return http_not_found end when Rack::POST - case request.path_info - when "/authorize" # RFC-6749 + case request.path + when "/oauth/authorize" # RFC-6749 return post_authorize(request) - when "/token" # RFC-6749 + when "/oauth/token" # RFC-6749 + # TODO:: Look up authorization grant by (code, saml_assertion) + user = Authn::User.new(id: SecureRandom.uuid) return [200, { 'Content-Type' => "application/json" }, [JSON.pretty_generate({ - access_token: ::Authz::JWT.new(sub: SecureRandom.uuid, iat: Time.now.to_i).to_jwt, + access_token: user.create_access_token.to_jwt, token_type: "Bearer", issued_token_type: "urn:ietf:params:oauth:token-type:access_token", expires_in: 3600, refresh_token: SecureRandom.hex(32) })]] when "/oauth/revoke" # RFC-7009 + # TODO:: Revoke the JWT token and make it ineligible for usage return http_not_found else return http_not_found @@ -407,7 +424,7 @@ module Authz http_not_found end - def get_authorize(request) + def get_authorize(oauth_params) template = <<~ERB @@ -415,14 +432,14 @@ module Authz

Authorize?

- - - - - - - - + + + + + + + +
-- cgit v1.2.3