Class: RackEntraIdAuth::Middleware
- Inherits:
-
Object
- Object
- RackEntraIdAuth::Middleware
- Defined in:
- lib/rack_entra_id_auth/middleware.rb
Instance Method Summary collapse
- #call(env) ⇒ Object
-
#initialize(app) ⇒ Middleware
constructor
A new instance of Middleware.
Constructor Details
#initialize(app) ⇒ Middleware
Returns a new instance of Middleware.
5 6 7 |
# File 'lib/rack_entra_id_auth/middleware.rb', line 5 def initialize (app) @app = app end |
Instance Method Details
#call(env) ⇒ Object
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/rack_entra_id_auth/middleware.rb', line 9 def call (env) request = Rack::Request.new(env) entra_id_request = EntraIdRequest.new(request) # SP initiated single sign-on request if entra_id_request.login? log(env, 'Redirecting login request to Entra ID single sign-on URL…') sso_url = entra_id_request.sso_url( { :RelayState => request.params['relay_state'] || RackEntraIdAuth.config.login_relay_state_url || entra_id_request.base_url }) return found_redirect_response( sso_url, 'Redirecting login request to Entra ID single sign-on URL') end # SP initiated logout/single logout request if entra_id_request.logout? log(env, 'Destroying session…') # destroy session in case single logout fails destroy_session(request.session) relay_state_url = request.params['relay_state'] || RackEntraIdAuth.config.logout_relay_state_url || entra_id_request.base_url slo_url = entra_id_request.slo_url({ :RelayState => relay_state_url }) if request.params['skip_single_logout'].blank? and !RackEntraIdAuth.config.skip_single_logout and slo_url.present? log(env, 'Redirecting logout request to Entra ID single logout URL…') return found_redirect_response( slo_url, 'Redirecting logout request to Entra ID single logout URL') end log(env, 'Skipping single logout because of skip_single_logout query parameter…') if request.params['skip_single_logout'].present? log(env, 'Skipping single logout because of skip_single_logout configuration setting…') if RackEntraIdAuth.config.skip_single_logout log(env, 'Skipping single logout because no Entra ID single logout URL was found…') if slo_url.blank? log(env, 'Redirecting to relay state URL…') return found_redirect_response(relay_state_url) end # SP initiatied single sign-on response if entra_id_request.login_response? log(env, 'Received single login response…') auth_response = entra_id_request.saml_auth_response() if !auth_response.is_valid? log(env, "Invalid single login reponse from Entra ID: #{auth_response.errors.first}") return internal_server_error_response("Invalid single login reponse from Entra ID: #{auth_response.errors.first}") end if !auth_response.success? log(env, 'Unsuccessful single single reponse from Entra ID.') return internal_server_error_response('Unsuccessful single login reponse from Entra ID.') end log(env, 'Initializing session and redirecting to relay state URL…') # initialize the session with the response's SAML attributes request.session[RackEntraIdAuth.config.session_key] = RackEntraIdAuth.config.session_value_proc.call(auth_response.attributes.all) return found_redirect_response( entra_id_request.relay_state_url, 'Received single login response, redirecting to relay state URL') end # IdP initiatied single logout request if entra_id_request.logout_request? and !RackEntraIdAuth.config.skip_single_logout log(env, 'Received single logout request…') logout_request = entra_id_request.saml_logout_request() if !logout_request.is_valid? log(env, "Invalid single logout request from Entra ID: #{logout_request.errors.first}") return internal_server_error_response("Invalid single logout request from Entra ID: #{logout_request.errors.first}") end log(env, 'Destroying session and sending logout response to Entra ID…') # destroy the session destroy_session(request.session) response_url = entra_id_request.slo_response_url( request_id: logout_request.id, logout_message: nil, params: { :RelayState => entra_id_request.relay_state_url }, logout_status_code: nil) return found_redirect_response( response_url, 'Received single logout request, redirecting to Entra ID') end # SP initiated single logout response if entra_id_request.logout_response? log(env, 'Received single logout response…') logout_response = entra_id_request.saml_logout_response() if !logout_response.validate log(env, "Invalid single logout reponse from Entra ID: #{logout_response.errors.first}") return internal_server_error_response("Invalid single logout reponse from Entra ID: #{logout_response.errors.first}") end if !logout_response.success? log(env, 'Unsuccessful single logout reponse from Entra ID.') return internal_server_error_response('Unsuccessful single logout reponse from Entra ID.') end log(env, 'Destroying session and redirecting to relay state URL…') # session should already be destroyed from SP initiated logout/single # logout request, but just to be safe… destroy_session(request.session) return found_redirect_response( entra_id_request.relay_state_url, 'Received single logout response, redirecting to relay state URL') end response = @app.call(env) # Authenticate 401s if response[0] == 401 log(env, 'Intercepted 401 Unauthorized response, redirecting to Entra ID single sign-on URL…') return found_redirect_response( entra_id_request.sso_url(:RelayState => request.url), 'Intercepted 401 Unauthorized response, redirecting to Entra ID single sign-on URL') end response end |