SAML을 처음 사용하고 그것이 어떻게 작동하는지 거의 이해하지 못한다고 말하면서이 질문을 시작합니다.Rails/Devise/SAML 메타 데이터 올바르지 않음 (PingFederate와 작동하지 않음)
설치
내가 SSO를 달성하기 위해 레일 4 응용 프로그램으로 devise_saml_authenticatable
보석을 사용하고 있습니다. Rails 응용 프로그램은 SP (서비스 공급자) 역할을합니다. 내 설정을 테스트하기 위해, 나는 OneLogin 개발자 계정을 만든 다음과 같은 속성을 사용하여 SAML Test Connector (IdP w/attr w/ sign response)를 설정 :
구성 탭을
- 대상 : mysubdomain.onelogin.com
- 받는 사람 : http://mysubdomain.myapp.local:3000/saml/auth
- ACS (소비자) URL 검사기 :^http : //mysubdomain.myapp.local : 3000/saml/auth $
- ACS (소비자) URL : http://mysubdomain.myapp.local:3000/saml/auth
- 싱글 로그 아웃 URL : http://mysubdomain.myapp.local:3000/saml/idp_sign_out
SSO 탭
- 발급자 URL : https://app.onelogin.com/saml/metadata/589819
- SAML 2.0 엔드 포인트 (HTTP) : https://mysubdomain.onelogin.com/trust/saml2/http-post/sso/589819
- SLO 엔드 포인트 (HTTP) : https://mysubdomain.onelogin.com/trust/saml2/http-redirect/slo/589819
- SAML 서명 알고리즘 : SHA-1
- SHA 지문 : 60 : 9D : 18 : 56 : B9 : 80 : D4 : 25 : 63 : C1 : CC : 57 : 6D : B9 : 06 : 7C : 78 : BB : 2C : F1
X.509 증명서 :
----- ----- BEGIN CERTIFICATE MIIEFzCCAv + gAwIBAgIUQYRVa1MQpUh0gJaznmXSF/SPqnowDQYJKoZIhvcNAQEF BQAwWDELMAkGA1UEBhMCVVMxETAPBgNVBAoMCEZpcm1QbGF5MRUwEwYDVQQLDAxP bmVMb2dpbiBJZFAxHzAdBgNVBAMMFk9uZUxvZ2luIEFjY291bnQgOTI1MzEwHhcN MTYwOTIxMTU0NzQwWhcNMjEwOTIyMTU0NzQwWjBYMQswCQYDVQQGEwJVUzERMA8G A1UECgwIRmlybVBsYXkxFTATBgNVBAsMDE9uZUxvZ2luIElkUDEfMB0GA1UEAwwW T25lTG9naW4gQWNjb3VudCA5MjUzMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC AQoCggEBALGVgocBj0ciHM3uKlWIcofPhOtzfJw1XpAdNynAvPtbCl7WE5 + sLBoQ ZF + oZ7Dl wRW6DHMJCl9DdKcOaQA6 +/+ gr5bwt78IzZ8hWMoKQEPih E0km6rKLYA8 M52vxtJxGs8Iqx60QvPEePQFM OA + xg73OExfM7W5LnXwNz/Pxgsr3lBif5oCC76j SaTCFroV + TSjfOaYMW/lZrsS79KRIzA9I5XwUBe3bC8bsfQmZXgddCrkQUNSGGaS 7/jtFUlQ94 + 랄 + l3yoAiNAE6 + mt48qqmyLfkKibXvnZ8dwuO272wpY4fEM + vFRy pYrTajqvhY3hYIq8dLw3ominE5VECl8CAwEAAaOB2DCB1TAMBgNVHRMBAf8EAjAA MB0GA1UdDgQWBBSxiuvTPxwOhh2pupID + tuyKCeceTCBlQYDVR0jBIGNMIGKgBSx iuvTPxwOhh2pupID + tuyKCeceaFcpFowWDELMAkGA1UEBhMCVVMxETAPBgNVBAoM CEZpcm1QbGF5MRUwEwYDVQQLDAxPbmVMb2dpbiBJZFAxHzAdBgNVBAMMFk9uZUxv Z2luIEFjY291bnQgOTI1MzGCFEGEVWtTEKVIdICWs55l0hf0j6p6MA4GA1UdDwEB /wQEAwIHgDANBgkqhkiG9w0BAQUFAAOCAQEAYBe + 5d3zpLZ7fcf3l3rXYeIxcpN + 9D2YZCbxsrBhY2Am4YE9nN + RaJXeDqeRBNtpayCZVxfHnXexRo1n7wxwTmosiydi 9yE7SY2xZf + 3feQreF25atnn4tzVhxYONaX1njZMIt/TNa7A9aeDfHS D + vwSuYYB hGxKT6HOkEAEBiXCZ/FcVNiB0D8bRwQhiJ3BTzXDfqHrmq8QYdn3Ejlqo62vMl6W XeMXUoyv6cUc64Ap6E + XtEQI1E8YB5R8GtTs3Y1Oa2dD6yWyCyVJ20 + Hi7IWAqXC EfqstqXB7FoQ2rAt39cepnu1SOarvEYDMwYIaVNF3hoyodBybJJsAwAnCQ == ----- END의 CERTIFICATE ----- 내
devise.rb
에서
나는 다음과 같은 구성이 있습니다
config.saml_create_user = false
config.saml_update_user = true
config.saml_default_user_key = :email
config.saml_session_index_key = :session_index
config.saml_use_subject = true
config.idp_settings_adapter = IdPSettingsAdapter
config.idp_entity_id_reader = DeviseSamlAuthenticatable::DefaultIdpEntityIdReader
을
내 사용자 모델 Contact
belongs_to Company
이며 SSO 설정이 Company
모델에 저장된다는 점에 유의하십시오.
require "ruby-saml"
class SamlSessionsController < SessionsController
include DeviseSamlAuthenticatable::SamlConfig
skip_before_filter :verify_authenticity_token, raise: false
before_action :authorize_viewer, except: [:metadata]
protect_from_forgery with: :null_session, except: :create
def new
idp_entity_id = Company.friendly.find(@_request.env['HTTP_HOST'].split('.')[0]).idp_entity_id
request = OneLogin::RubySaml::Authrequest.new
action = request.create(saml_config(idp_entity_id))
redirect_to action
end
def metadata
idp_entity_id = Company.friendly.find(@_request.env['HTTP_HOST'].split('.')[0]).idp_entity_id
meta = OneLogin::RubySaml::Metadata.new
render :xml => meta.generate(saml_config(idp_entity_id)), content_type: 'application/samlmetadata+xml'
end
def create
@idp_entity_id = Company.friendly.find(@_request.env['HTTP_HOST'].split('.')[0]).idp_entity_id
response = OneLogin::RubySaml::Response.new(params[:SAMLResponse], settings: saml_config(@idp_entity_id))
if !response.is_valid?
puts "SAML FAILED WITH ERROR: "
puts response.errors
end
super
end
def idp_sign_out
company = Company.friendly.find(request.subdomain.downcase)
idp_entity_id = Company.friendly.find(@_request.env['HTTP_HOST'].split('.')[0]).idp_entity_id
if params[:SAMLRequest] && Devise.saml_session_index_key
saml_config = saml_config(idp_entity_id)
logout_request = OneLogin::RubySaml::SloLogoutrequest.new(params[:SAMLRequest], settings: saml_config(idp_entity_id))
resource_class.reset_session_key_for(logout_request.name_id)
# binding.pry
sign_out current_contact if contact_signed_in?
redirect_to company.after_slo_url.present? ? company.after_slo_url : 'https://' + company.issuer
# redirect_to generate_idp_logout_response(saml_config(idp_entity_id), logout_request.id)
elsif params[:SAMLResponse]
#Currently Devise handles the session invalidation when the request is made.
#To support a true SP initiated logout response, the request ID would have to be tracked and session invalidated
#based on that.
if Devise.saml_sign_out_success_url
redirect_to Devise.saml_sign_out_success_url
else
redirect_to action: :new
end
else
head :invalid_request
end
end
protected
# Override devise to send user to IdP logout for SLO
def after_sign_out_path_for(_)
request = OneLogin::RubySaml::Logoutrequest.new
request.create(saml_config)
end
def generate_idp_logout_response(saml_config, logout_request_id)
OneLogin::RubySaml::SloLogoutresponse.new.create(saml_config, logout_request_id, nil)
end
end
문제점
내가 수동으로 Company
내 OneLogin 어댑터의 설정을지도 저장 : 여기
내 SAML 경로입니다 : 내 SamlSessionsController
마지막으로 여기
devise_for :contacts, skip: :saml_authenticatable, controllers: {
registrations: "registrations",
sessions: "sessions",
passwords: "passwords",
confirmations: "confirmations"
}
devise_scope :contact do
get '/sign_in' => 'sessions#new'
get '/sign_out' => 'sessions#destroy'
# SSO Routes
get 'saml/sign_in' => 'saml_sessions#new', as: :new_user_sso_session
post 'saml/auth' => 'saml_sessions#create', as: :user_sso_session
get 'saml/sign_out' => 'saml_sessions#destroy', as: :destroy_user_sso_session
get 'saml/metadata' => 'saml_sessions#metadata', as: :metadata_user_sso_session
match 'saml/idp_sign_out' => 'saml_sessions#idp_sign_out', via: [:get, :post]
end
입니다 모델 (스크린 샷 참조)에서 아이덴티티 프로 바이더 (IdP)로 OneLogin을 사용하여 앱의 사용자로 인증 할 수 있습니다. 그러나 이제는 클라이언트에게 앱의 설정을 나타내는 XML 메타 데이터를 제공해야합니다. /saml/metadata.xml
으로 갈 때 다음 클라이언트 구성에 따라 구성이 잘못되었습니다. 고객이 문제에 대한 자세한 내용을 제공하지 않았습니다. PingFederate를 사용하고 있습니다.
<?xml version='1.0' encoding='UTF-8'?>
<md:EntityDescriptor ID='_a3581975-b73d-4784-a106-bafd61e15f87' xmlns:md='urn:oasis:names:tc:SAML:2.0:metadata'>
<md:SPSSODescriptor AuthnRequestsSigned='false' WantAssertionsSigned='false' protocolSupportEnumeration='urn:oasis:names:tc:SAML:2.0:protocol'>
<md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</md:NameIDFormat>
<md:AssertionConsumerService Binding='urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST' Location='https://mysubdomain.myapp.local:3000/saml/auth' index='0' isDefault='true'/>
</md:SPSSODescriptor>
</md:EntityDescriptor>
내 질문은, 내가 잘못 여기서 뭐하는거야이며 어떻게 해결 할 수 있습니까? 앞서 말했듯이, SAML이 어떻게 작동하는지 간신히 이해합니다.
오류에 대한 정보가 없으면 어떻게 해결할 수 있습니까? – smartin
나는 클라이언트가 문제가 무엇인지에 대해 더 이상의 세부 정보를 제공하지 않았지만 XML이 어떻게 든 무효라는 점을 이해한다. 누락 된 정보가 있거나 설치가 올바르지 않은지 궁금합니다. – ACIDSTEALTH