diff --git a/README.md b/README.md index fd6f44d..4245f0e 100644 --- a/README.md +++ b/README.md @@ -207,6 +207,15 @@ The CAS standard allows for a `renew=true` parameter to be passed to the CAS ser config.rack_cas.renew = true ``` +Extra query parameters to serviceValidate +----------------------------------------- + +Some CAS servers needs extra query parameters to be passed to serviceValidate. These can be configured by adding the following to `config/application.rb`: + +```ruby +config.rack_cas.extra_params_validate = { key: 'verysecret', location: 'here' } +``` + Integration =========== Your app should __return a [401 status](http://httpstatus.es/401)__ whenever a request is made that requires authentication. Rack-CAS will catch these responses and attempt to authenticate via your CAS server. diff --git a/lib/rack-cas/configuration.rb b/lib/rack-cas/configuration.rb index 0988585..3972cb1 100644 --- a/lib/rack-cas/configuration.rb +++ b/lib/rack-cas/configuration.rb @@ -2,7 +2,7 @@ module RackCAS class Configuration SETTINGS = [:fake, :fake_attributes, :server_url, :session_store, :exclude_path, :exclude_paths, :extra_attributes_filter, :verify_ssl_cert, :renew, :use_saml_validation, :ignore_intercept_validator, :exclude_request_validator, :protocol, - :redis_options, :login_url, :service] + :redis_options, :login_url, :service, :extra_params_validate] SETTINGS.each do |setting| @@ -15,6 +15,7 @@ class Configuration def initialize @verify_ssl_cert = true + @extra_params_validate = {} end def extra_attributes_filter diff --git a/lib/rack-cas/server.rb b/lib/rack-cas/server.rb index 996e833..7e49881 100644 --- a/lib/rack-cas/server.rb +++ b/lib/rack-cas/server.rb @@ -24,25 +24,28 @@ def logout_url(params = {}) end end - def validate_service(service_url, ticket) + def validate_service(service_url, ticket, params = {}) + params = RackCAS.config.extra_params_validate unless RackCAS.config.use_saml_validation? - response = ServiceValidationResponse.new validate_service_url(service_url, ticket) + response = ServiceValidationResponse.new validate_service_url(service_url, ticket, params) else - response = SAMLValidationResponse.new saml_validate_url(service_url), ticket + response = SAMLValidationResponse.new saml_validate_url(service_url, params), ticket end [response.user, response.extra_attributes] end protected - def saml_validate_url(service_url) + def saml_validate_url(service_url, params = {}) service_url = URL.parse(service_url).remove_param('ticket').to_s - @url.dup.append_path(path_for_protocol('samlValidate')).add_params(TARGET: service_url) + base_params = {TARGET: service_url} + @url.dup.append_path(path_for_protocol('samlValidate')).add_params(base_params.merge(params)) end - def validate_service_url(service_url, ticket) + def validate_service_url(service_url, ticket, params = {}) service_url = URL.parse(service_url).remove_param('ticket').to_s - @url.dup.append_path(path_for_protocol('serviceValidate')).add_params(service: service_url, ticket: ticket) + base_params = {service: service_url, ticket: ticket} + @url.dup.append_path(path_for_protocol('serviceValidate')).add_params(base_params.merge(params)) end def path_for_protocol(path) diff --git a/spec/rack-cas/cas_request_spec.rb b/spec/rack-cas/cas_request_spec.rb index 63e2aa3..08148dd 100644 --- a/spec/rack-cas/cas_request_spec.rb +++ b/spec/rack-cas/cas_request_spec.rb @@ -36,7 +36,7 @@ def app end context 'single sign out request' do - before { post "/?logoutRequest=#{URI.encode(fixture('single_sign_out_request.xml'))}" } + before { post "/?logoutRequest=#{URI::Parser.new.escape(fixture('single_sign_out_request.xml'))}" } its(:ticket) { should eql 'ST-0123456789ABCDEFGHIJKLMNOPQRS' } its(:single_sign_out?) { should be true } its(:logout?) { should be false } diff --git a/spec/rack/cas_spec.rb b/spec/rack/cas_spec.rb index d93d59c..f9f65f9 100644 --- a/spec/rack/cas_spec.rb +++ b/spec/rack/cas_spec.rb @@ -65,7 +65,7 @@ def app { session_store: session_store } } - subject { post "/?logoutRequest=#{URI.encode(fixture('single_sign_out_request.xml'))}" } + subject { post "/?logoutRequest=#{URI::Parser.new.escape(fixture('single_sign_out_request.xml'))}" } its(:status) { should eql 200 } its(:body) { should eql 'CAS Single-Sign-Out request intercepted.' } end