mirror of
https://github.com/codeninjasllc/discourse.git
synced 2024-11-27 17:46:05 -05:00
FEATURE: verbose SSO logging
By enabling the site setting verbose_sso_logging you can log information every time a user tries initiates SSO and during SSO failures
This commit is contained in:
parent
609969bf6f
commit
19ca08857f
5 changed files with 29 additions and 9 deletions
|
@ -20,7 +20,11 @@ class SessionController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
if SiteSetting.enable_sso?
|
if SiteSetting.enable_sso?
|
||||||
redirect_to DiscourseSingleSignOn.generate_url(return_path)
|
sso = DiscourseSingleSignOn.generate_sso(return_path)
|
||||||
|
if SiteSetting.verbose_sso_logging
|
||||||
|
Rails.logger.warn("Verbose SSO log: Started SSO process\n\n#{sso.diagnostics}")
|
||||||
|
end
|
||||||
|
redirect_to sso.to_url
|
||||||
else
|
else
|
||||||
render nothing: true, status: 404
|
render nothing: true, status: 404
|
||||||
end
|
end
|
||||||
|
@ -69,10 +73,16 @@ class SessionController < ApplicationController
|
||||||
|
|
||||||
sso = DiscourseSingleSignOn.parse(request.query_string)
|
sso = DiscourseSingleSignOn.parse(request.query_string)
|
||||||
if !sso.nonce_valid?
|
if !sso.nonce_valid?
|
||||||
|
if SiteSetting.verbose_sso_logging
|
||||||
|
Rails.logger.warn("Verbose SSO log: Nonce has already expired\n\n#{sso.diagnostics}")
|
||||||
|
end
|
||||||
return render(text: I18n.t("sso.timeout_expired"), status: 419)
|
return render(text: I18n.t("sso.timeout_expired"), status: 419)
|
||||||
end
|
end
|
||||||
|
|
||||||
if ScreenedIpAddress.should_block?(request.remote_ip)
|
if ScreenedIpAddress.should_block?(request.remote_ip)
|
||||||
|
if SiteSetting.verbose_sso_logging
|
||||||
|
Rails.logger.warn("Verbose SSO log: IP address is blocked #{request.remote_ip}\n\n#{sso.diagnostics}")
|
||||||
|
end
|
||||||
return render(text: I18n.t("sso.unknown_error"), status: 500)
|
return render(text: I18n.t("sso.unknown_error"), status: 500)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -95,6 +105,9 @@ class SessionController < ApplicationController
|
||||||
session["user_created_message"] = activation.message
|
session["user_created_message"] = activation.message
|
||||||
redirect_to users_account_created_path and return
|
redirect_to users_account_created_path and return
|
||||||
else
|
else
|
||||||
|
if SiteSetting.verbose_sso_logging
|
||||||
|
Rails.logger.warn("Verbose SSO log: User was logged on #{user.username}\n\n#{sso.diagnostics}")
|
||||||
|
end
|
||||||
log_on_user user
|
log_on_user user
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -115,14 +128,9 @@ class SessionController < ApplicationController
|
||||||
rescue ActiveRecord::RecordInvalid => e
|
rescue ActiveRecord::RecordInvalid => e
|
||||||
render text: I18n.t("sso.unknown_error"), status: 500
|
render text: I18n.t("sso.unknown_error"), status: 500
|
||||||
rescue => e
|
rescue => e
|
||||||
details = {}
|
|
||||||
SingleSignOn::ACCESSORS.each do |a|
|
|
||||||
details[a] = sso.send(a)
|
|
||||||
end
|
|
||||||
|
|
||||||
message = "Failed to create or lookup user: #{e}."
|
message = "Failed to create or lookup user: #{e}."
|
||||||
message << "\n\n" << "-" * 100 << "\n\n"
|
message << "\n\n" << "-" * 100 << "\n\n"
|
||||||
message << details.map { |k,v| "#{k}: #{v}" }.join("\n")
|
message << sso.diagnostics
|
||||||
message << "\n\n" << "-" * 100 << "\n\n"
|
message << "\n\n" << "-" * 100 << "\n\n"
|
||||||
message << e.backtrace.join("\n")
|
message << e.backtrace.join("\n")
|
||||||
|
|
||||||
|
|
|
@ -10,12 +10,16 @@ class DiscourseSingleSignOn < SingleSignOn
|
||||||
SiteSetting.sso_secret
|
SiteSetting.sso_secret
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.generate_url(return_path="/")
|
def self.generate_sso(return_path="/")
|
||||||
sso = new
|
sso = new
|
||||||
sso.nonce = SecureRandom.hex
|
sso.nonce = SecureRandom.hex
|
||||||
sso.register_nonce(return_path)
|
sso.register_nonce(return_path)
|
||||||
sso.return_sso_url = Discourse.base_url + "/session/sso_login"
|
sso.return_sso_url = Discourse.base_url + "/session/sso_login"
|
||||||
sso.to_url
|
sso
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.generate_url(return_path="/")
|
||||||
|
generate_sso(return_path).to_url
|
||||||
end
|
end
|
||||||
|
|
||||||
def register_nonce(return_path)
|
def register_nonce(return_path)
|
||||||
|
|
|
@ -943,6 +943,7 @@ en:
|
||||||
block_common_passwords: "Don't allow passwords that are in the 10,000 most common passwords."
|
block_common_passwords: "Don't allow passwords that are in the 10,000 most common passwords."
|
||||||
|
|
||||||
enable_sso: "Enable single sign on via an external site (WARNING: USERS' EMAIL ADDRESSES *MUST* BE VALIDATED BY THE EXTERNAL SITE!)"
|
enable_sso: "Enable single sign on via an external site (WARNING: USERS' EMAIL ADDRESSES *MUST* BE VALIDATED BY THE EXTERNAL SITE!)"
|
||||||
|
verbose_sso_logging: "Log verbose SSO related diagnostics to /logs"
|
||||||
enable_sso_provider: "Implement Discourse SSO provider protocol at the /session/sso_provider endpoint, requires sso_secret to be set"
|
enable_sso_provider: "Implement Discourse SSO provider protocol at the /session/sso_provider endpoint, requires sso_secret to be set"
|
||||||
sso_url: "URL of single sign on endpoint (must include http:// or https://)"
|
sso_url: "URL of single sign on endpoint (must include http:// or https://)"
|
||||||
sso_secret: "Secret string used to cryptographically authenticate SSO information, be sure it is 10 characters or longer"
|
sso_secret: "Secret string used to cryptographically authenticate SSO information, be sure it is 10 characters or longer"
|
||||||
|
|
|
@ -266,6 +266,7 @@ login:
|
||||||
client: true
|
client: true
|
||||||
default: false
|
default: false
|
||||||
enable_sso_provider: false
|
enable_sso_provider: false
|
||||||
|
verbose_sso_logging: true
|
||||||
sso_url:
|
sso_url:
|
||||||
default: ''
|
default: ''
|
||||||
regex: '^https?:\/\/.+[^\/]$'
|
regex: '^https?:\/\/.+[^\/]$'
|
||||||
|
|
|
@ -55,6 +55,12 @@ class SingleSignOn
|
||||||
sso
|
sso
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def diagnostics
|
||||||
|
SingleSignOn::ACCESSORS.map do |a|
|
||||||
|
"#{a}: #{sso.send(a)}"
|
||||||
|
end.join("\n")
|
||||||
|
end
|
||||||
|
|
||||||
def sso_secret
|
def sso_secret
|
||||||
@sso_secret || self.class.sso_secret
|
@sso_secret || self.class.sso_secret
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue