handles_oidc_authorization.rb 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. # Copyright (C) 2012-2025 Zammad Foundation, https://zammad-foundation.org/
  2. module HandlesOidcAuthorization
  3. extend ActiveSupport::Concern
  4. included do # rubocop:disable Metrics/BlockLength
  5. skip_before_action :verify_csrf_token, only: %i[oidc_destroy oidc_bc_logout] # rubocop:disable Rails/LexicallyScopedActionFilter
  6. def oidc_bc_logout
  7. raise Exceptions::UnprocessableEntity, __("The required parameter 'logout_token' is missing.") if params[:logout_token].blank?
  8. begin
  9. oidc = OmniAuth::Strategies::OidcDatabase.new(OmniAuth::Strategies::OidcDatabase.setup)
  10. decoded = oidc.decode_logout_token(params[:logout_token])
  11. rescue => e
  12. Rails.logger.error "OpenID Connect OP-initiated logout failed: #{e.message}"
  13. raise Exceptions::UnprocessableEntity, __("The 'logout_token' is invalid.")
  14. end
  15. raise Exceptions::UnprocessableEntity, __("The 'logout_token' does not contain any session information.") if decoded.sid.blank?
  16. Session.all.detect { |s| s.data['oidc_sid'] == decoded.sid }&.destroy
  17. end
  18. private
  19. def oidc_session?
  20. session[:oidc_id_token].present?
  21. end
  22. def oidc_destroy
  23. oidc = OmniAuth::Strategies::OidcDatabase.new(OmniAuth::Strategies::OidcDatabase.setup)
  24. options = oidc.config
  25. logout_url = Addressable::URI.parse(options.end_session_endpoint)
  26. logout_url.query_values = {
  27. id_token_hint: session[:oidc_id_token],
  28. post_logout_redirect_uri: "#{Setting.get('http_type')}://#{Setting.get('fqdn')}"
  29. }
  30. OmniAuth::Strategies::OidcDatabase.destroy_session(request.env, session)
  31. render json: { url: logout_url.to_s }
  32. rescue => e
  33. Rails.logger.error "OpenID Connect RP-initiated logout failed: #{e.message}"
  34. end
  35. end
  36. end