Skip to content
Extraits de code Groupes Projets
Valider 9c9880d8 rédigé par theworldbright's avatar theworldbright
Parcourir les fichiers

Move JWKs files to database

parent 2c7d1020
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
Affichage de avec 49 ajouts et 39 suppressions
......@@ -21,7 +21,6 @@ config/database.yml
.rvmrc_custom
.rvmrc.local
config/oidc_key.pem
config/jwks/
# Mailing list stuff
config/email_offset
......
......@@ -10,12 +10,7 @@ module Api
def new
auth = Api::OpenidConnect::Authorization.find_by_client_id_and_user(params[:client_id], current_user)
if auth
auth.o_auth_access_tokens.destroy_all
auth.id_tokens.destroy_all
auth.code_used = false
auth.save
end
reset_auth(auth)
if logged_in_before?(params[:max_age])
reauthenticate
elsif params[:prompt]
......@@ -43,6 +38,14 @@ module Api
private
def reset_auth(auth)
return unless auth
auth.o_auth_access_tokens.destroy_all
auth.id_tokens.destroy_all
auth.code_used = false
auth.save
end
def handle_prompt(prompt, auth)
if prompt.include? "select_account"
handle_prompt_params_error("account_selection_required",
......
......@@ -6,7 +6,7 @@ module Api
if req["client_assertion_type"] == "urn:ietf:params:oauth:client-assertion-type:jwt-bearer"
handle_jwt_bearer(req)
end
self.status, self.response.headers, self.response_body = Api::OpenidConnect::TokenEndpoint.new.call(request.env)
self.status, response.headers, self.response_body = Api::OpenidConnect::TokenEndpoint.new.call(request.env)
nil
end
......@@ -24,12 +24,10 @@ module Api
end
def fetch_public_key(o_auth_app, jwt)
jwks_file_path = File.join(Rails.root, "config", "jwks", o_auth_app.jwks_file)
public_key = fetch_public_key_from_json(File.read(jwks_file_path), jwt)
public_key = fetch_public_key_from_json(o_auth_app.jwks, jwt)
if public_key.empty? && o_auth_app.jwks_uri
uri = URI.parse(o_auth_app.jwks_uri)
response = Net::HTTP.get_response(uri)
File.write jwks_file_path, response.body
public_key = fetch_public_key_from_json(response.body, jwt)
end
raise Rack::OAuth2::Server::Authorize::BadRequest(:unauthorized_client) if public_key.empty?
......
......@@ -10,7 +10,7 @@ module Api
validates :client_secret, presence: true
validates :client_name, uniqueness: {scope: :redirect_uris}
%i(redirect_uris response_types grant_types contacts).each do |serializable|
%i(redirect_uris response_types grant_types contacts jwks).each do |serializable|
serialize serializable, JSON
end
......@@ -82,27 +82,15 @@ module Api
elsif key == :jwks_uri
uri = URI.parse(value)
response = Net::HTTP.get_response(uri)
file_name = create_file_path(response.body)
attr[:jwks_file] = file_name + ".json"
attr[:jwks] = response.body
attr[:jwks_uri] = value
elsif key == :jwks
file_name = create_file_path(value.to_json)
attr[:jwks_file] = file_name + ".json"
attr[:jwks] = value.to_json
else
attr[key] = value
end
end
end
def create_file_path(content)
file_name = Base64.urlsafe_encode64(Digest::SHA256.base64digest(content))
directory_name = File.join(Rails.root, "config", "jwks")
Dir.mkdir(directory_name) unless File.exist?(directory_name)
jwk_file_path = File.join(Rails.root, "config", "jwks", file_name + ".json")
File.write jwk_file_path, content
File.chmod(0600, jwk_file_path)
file_name
end
end
end
end
......
......@@ -17,9 +17,8 @@ class CreateOAuthApplications < ActiveRecord::Migration
t.string :tos_uri
t.string :sector_identifier_uri
t.string :token_endpoint_auth_method
t.text :jwks
t.string :jwks_uri
t.string :jwks_file
t.boolean :ppid, default: false
t.timestamps null: false
......
......@@ -281,7 +281,7 @@ ActiveRecord::Schema.define(version: 20150828132451) do
t.string "redirect_uris", limit: 255
t.string "response_types", limit: 255
t.string "grant_types", limit: 255
t.string "application_type", limit: 255, default: "web"
t.string "application_type", limit: 255, default: "web"
t.string "contacts", limit: 255
t.string "logo_uri", limit: 255
t.string "client_uri", limit: 255
......@@ -289,11 +289,11 @@ ActiveRecord::Schema.define(version: 20150828132451) do
t.string "tos_uri", limit: 255
t.string "sector_identifier_uri", limit: 255
t.string "token_endpoint_auth_method", limit: 255
t.text "jwks", limit: 65535
t.string "jwks_uri", limit: 255
t.string "jwks_file", limit: 255
t.boolean "ppid", default: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.boolean "ppid", default: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "o_auth_applications", ["client_id"], name: "index_o_auth_applications_on_client_id", unique: true, length: {"client_id"=>191}, using: :btree
......
eyJhbGciOiJSUzI1NiIsImtpZCI6ImExIn0.ewogIGF1ZDogWwogICAgaHR0cHM6Ly9rZW50c2hpa2FtYS5jb20vYXBpL29wZW5pZF9jb25uZWN0L2FjY2Vzc190b2tlbnMKICBdLAogIGlzczogMTRkNjkyY2Q1M2Q5YzFhOWY0NmZkNjllMGU1NzQ0M2QsCiAganRpOiAwbWNycmVZSCwKICBleHA6IDE0NDMxNzA4OTEuMzk3NDU2LAogIGlhdDogMTQ0MzE3MDI5MS4zOTc0NTYsCiAgc3ViOiAxNGQ2OTJjZDUzZDljMWE5ZjQ2ZmQ2OWUwZTU3NDQzZAp9Cg.QJUR3SYFrEIlbfOKjO0NYInddklytbJ2LSWNpkQ1aNThgneDCVCjIYGCaL2C9Sw-GR8j7QSUsKOwBbjZMUmVPFTjsfB4wdgObbxVt1QAXwDjAXc5w1smOerRsoahZ4yKI1an6PTaFxMwnoXUQcBZTsOS6RgXOCPPPoxibxohxoehPLieM0l7LYcF5DQKg7fTxZYOpmtiP--nibJxomXdVQNLSnZuQwnyWtlp_gYmqrYMMN1LPSmNCgZMZZZIYttaaAIA96SylglqubowJRShtDO9rSvUz_sgeCo7qo5Bfb0B5n9_PtIlr1CZSVoHyYj2lVqQldx7fnGuqqQJCfDQog
ewogIGFsZzogUlMyNTYsCiAga2lkOiBpbnZhbGlkX2tpZAp9Cg.eyJhdWQiOiBbImh0dHBzOi8va2VudHNoaWthbWEuY29tL2FwaS9vcGVuaWRfY29ubmVjdC9hY2Nlc3NfdG9rZW5zIl0sICJpc3MiOiAiMTRkNjkyY2Q1M2Q5YzFhOWY0NmZkNjllMGU1NzQ0M2UiLCAianRpIjogIjBtY3JyZVlIIiwgImV4cCI6IDE0NDMxNzA4OTEuMzk3NDU2LCAiaWF0IjogMTQ0MzE3MDI5MS4zOTc0NTYsICJzdWIiOiAiMTRkNjkyY2Q1M2Q5YzFhOWY0NmZkNjllMGU1NzQ0M2UifQ.
\ No newline at end of file
eyJhbGciOiJSUzI1NiIsImtpZCI6ImExIn0.eyJhdWQiOiBbImh0dHBzOi8va2VudHNoaWthbWEuY29tL2FwaS9vcGVuaWRfY29ubmVjdC9hY2Nlc3NfdG9rZW5zIl0sICJpc3MiOiAiMTRkNjkyY2Q1M2Q5YzFhOWY0NmZkNjllMGU1NzQ0M2UiLCAianRpIjogIjBtY3JyZVlIIiwgImV4cCI6IDE0NDMxNzA4OTEuMzk3NDU2LCAiaWF0IjogMTQ0MzE3MDI5MS4zOTc0NTYsICJzdWIiOiAiMTRkNjkyY2Q1M2Q5YzFhOWY0NmZkNjllMGU1NzQ0M2UifQ.QJUR3SYFrEIlbfOKjO0NYInddklytbJ2LSWNpkQ1aNThgneDCVCjIYGCaL2C9Sw-GR8j7QSUsKOwBbjZMUmVPFTjsfB4wdgObbxVt1QAXwDjAXc5w1smOerRsoahZ4yKI1an6PTaFxMwnoXUQcBZTsOS6RgXOCPPPoxibxohxoehPLieM0l7LYcF5DQKg7fTxZYOpmtiP--nibJxomXdVQNLSnZuQwnyWtlp_gYmqrYMMN1LPSmNCgZMZZZIYttaaAIA96SylglqubowJRShtDO9rSvUz_sgeCo7qo5Bfb0B5n9_PtIlr1CZSVoHyYj2lVqQldx7fnGuqqQJCfDQoe
\ No newline at end of file
eyJhbGciOiJSUzI1NiIsImtpZCI6ImExIn0.eyJhdWQiOiBbImh0dHBzOi8va2VudHNoaWthbWEuY29tL2FwaS9vcGVuaWRfY29ubmVjdC9hY2Nlc3NfdG9rZW5zIl0sICJpc3MiOiAiMTRkNjkyY2Q1M2Q5YzFhOWY0NmZkNjllMGU1NzQ0M2UiLCAianRpIjogIjBtY3JyZVlIIiwgImV4cCI6IDE0NDMxNzA4OTEuMzk3NDU2LCAiaWF0IjogMTQ0MzE3MDI5MS4zOTc0NTYsICJzdWIiOiAiMTRkNjkyY2Q1M2Q5YzFhOWY0NmZkNjllMGU1NzQ0M2UifQ.QJUR3SYFrEIlbfOKjO0NYInddklytbJ2LSWNpkQ1aNThgneDCVCjIYGCaL2C9Sw-GR8j7QSUsKOwBbjZMUmVPFTjsfB4wdgObbxVt1QAXwDjAXc5w1smOerRsoahZ4yKI1an6PTaFxMwnoXUQcBZTsOS6RgXOCPPPoxibxohxoehPLieM0l7LYcF5DQKg7fTxZYOpmtiP--nibJxomXdVQNLSnZuQwnyWtlp_gYmqrYMMN1LPSmNCgZMZZZIYttaaAIA96SylglqubowJRShtDO9rSvUz_sgeCo7qo5Bfb0B5n9_PtIlr1CZSVoHyYj2lVqQldx7fnGuqqQJCfDQog
\ No newline at end of file
......@@ -10,7 +10,7 @@ describe Api::OpenidConnect::TokenEndpoint, type: :request do
let!(:client_with_specific_id) { FactoryGirl.create(:o_auth_application_with_ppid_with_specific_id) }
let!(:auth_with_specific_id) do
client_with_specific_id.client_id = "14d692cd53d9c1a9f46fd69e0e57443e"
client_with_specific_id.jwks_file = jwks_file_path
client_with_specific_id.jwks = File.read(jwks_file_path)
client_with_specific_id.save!
Api::OpenidConnect::Authorization.find_or_create_by(
o_auth_application: client_with_specific_id,
......@@ -67,7 +67,7 @@ describe Api::OpenidConnect::TokenEndpoint, type: :request do
post api_openid_connect_access_tokens_path, grant_type: "authorization_code",
redirect_uri: "http://localhost:3000/", code: code_with_specific_id,
client_assertion_type: "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
client_assertion: "eyJhbGciOiJSUzI1NiIsImtpZCI6ImExIn0.eyJhdWQiOiBbImh0dHBzOi8va2VudHNoaWthbWEuY29tL2FwaS9vcGVuaWRfY29ubmVjdC9hY2Nlc3NfdG9rZW5zIl0sICJpc3MiOiAiMTRkNjkyY2Q1M2Q5YzFhOWY0NmZkNjllMGU1NzQ0M2UiLCAianRpIjogIjBtY3JyZVlIIiwgImV4cCI6IDE0NDMxNzA4OTEuMzk3NDU2LCAiaWF0IjogMTQ0MzE3MDI5MS4zOTc0NTYsICJzdWIiOiAiMTRkNjkyY2Q1M2Q5YzFhOWY0NmZkNjllMGU1NzQ0M2UifQ.QJUR3SYFrEIlbfOKjO0NYInddklytbJ2LSWNpkQ1aNThgneDCVCjIYGCaL2C9Sw-GR8j7QSUsKOwBbjZMUmVPFTjsfB4wdgObbxVt1QAXwDjAXc5w1smOerRsoahZ4yKI1an6PTaFxMwnoXUQcBZTsOS6RgXOCPPPoxibxohxoehPLieM0l7LYcF5DQKg7fTxZYOpmtiP--nibJxomXdVQNLSnZuQwnyWtlp_gYmqrYMMN1LPSmNCgZMZZZIYttaaAIA96SylglqubowJRShtDO9rSvUz_sgeCo7qo5Bfb0B5n9_PtIlr1CZSVoHyYj2lVqQldx7fnGuqqQJCfDQog"
client_assertion: File.read(valid_client_assertion_path)
end
it "should return a valid id token" do
......@@ -125,7 +125,7 @@ describe Api::OpenidConnect::TokenEndpoint, type: :request do
post api_openid_connect_access_tokens_path, grant_type: "authorization_code",
redirect_uri: "http://localhost:3000/", code: code_with_specific_id,
client_assertion_type: "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
client_assertion: "eyJhbGciOiJSUzI1NiIsImtpZCI6ImExIn0.eyJhdWQiOiBbImh0dHBzOi8va2VudHNoaWthbWEuY29tL2FwaS9vcGVuaWRfY29ubmVjdC9hY2Nlc3NfdG9rZW5zIl0sICJpc3MiOiAiMTRkNjkyY2Q1M2Q5YzFhOWY0NmZkNjllMGU1NzQ0M2UiLCAianRpIjogIjBtY3JyZVlIIiwgImV4cCI6IDE0NDMxNzA4OTEuMzk3NDU2LCAiaWF0IjogMTQ0MzE3MDI5MS4zOTc0NTYsICJzdWIiOiAiMTRkNjkyY2Q1M2Q5YzFhOWY0NmZkNjllMGU1NzQ0M2UifQ.QJUR3SYFrEIlbfOKjO0NYInddklytbJ2LSWNpkQ1aNThgneDCVCjIYGCaL2C9Sw-GR8j7QSUsKOwBbjZMUmVPFTjsfB4wdgObbxVt1QAXwDjAXc5w1smOerRsoahZ4yKI1an6PTaFxMwnoXUQcBZTsOS6RgXOCPPPoxibxohxoehPLieM0l7LYcF5DQKg7fTxZYOpmtiP--nibJxomXdVQNLSnZuQwnyWtlp_gYmqrYMMN1LPSmNCgZMZZZIYttaaAIA96SylglqubowJRShtDO9rSvUz_sgeCo7qo5Bfb0B5n9_PtIlr1CZSVoHyYj2lVqQldx7fnGuqqQJCfDQoe"
client_assertion: File.read(client_assertion_with_tampered_sig_path)
end
it "should return an error" do
......@@ -138,7 +138,7 @@ describe Api::OpenidConnect::TokenEndpoint, type: :request do
post api_openid_connect_access_tokens_path, grant_type: "authorization_code",
redirect_uri: "http://localhost:3000/", code: code_with_specific_id,
client_assertion_type: "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
client_assertion: "ewogIGFsZzogUlMyNTYsCiAga2lkOiBpbnZhbGlkX2tpZAp9Cg.eyJhdWQiOiBbImh0dHBzOi8va2VudHNoaWthbWEuY29tL2FwaS9vcGVuaWRfY29ubmVjdC9hY2Nlc3NfdG9rZW5zIl0sICJpc3MiOiAiMTRkNjkyY2Q1M2Q5YzFhOWY0NmZkNjllMGU1NzQ0M2UiLCAianRpIjogIjBtY3JyZVlIIiwgImV4cCI6IDE0NDMxNzA4OTEuMzk3NDU2LCAiaWF0IjogMTQ0MzE3MDI5MS4zOTc0NTYsICJzdWIiOiAiMTRkNjkyY2Q1M2Q5YzFhOWY0NmZkNjllMGU1NzQ0M2UifQ."
client_assertion: File.read(client_assertion_with_nonexistent_kid_path)
end
it "should return an error" do
......@@ -159,7 +159,7 @@ describe Api::OpenidConnect::TokenEndpoint, type: :request do
post api_openid_connect_access_tokens_path, grant_type: "authorization_code",
redirect_uri: "http://localhost:3000/", code: code_with_specific_id,
client_assertion_type: "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
client_assertion: "eyJhbGciOiJSUzI1NiIsImtpZCI6ImExIn0.ewogIGF1ZDogWwogICAgaHR0cHM6Ly9rZW50c2hpa2FtYS5jb20vYXBpL29wZW5pZF9jb25uZWN0L2FjY2Vzc190b2tlbnMKICBdLAogIGlzczogMTRkNjkyY2Q1M2Q5YzFhOWY0NmZkNjllMGU1NzQ0M2QsCiAganRpOiAwbWNycmVZSCwKICBleHA6IDE0NDMxNzA4OTEuMzk3NDU2LAogIGlhdDogMTQ0MzE3MDI5MS4zOTc0NTYsCiAgc3ViOiAxNGQ2OTJjZDUzZDljMWE5ZjQ2ZmQ2OWUwZTU3NDQzZAp9Cg.QJUR3SYFrEIlbfOKjO0NYInddklytbJ2LSWNpkQ1aNThgneDCVCjIYGCaL2C9Sw-GR8j7QSUsKOwBbjZMUmVPFTjsfB4wdgObbxVt1QAXwDjAXc5w1smOerRsoahZ4yKI1an6PTaFxMwnoXUQcBZTsOS6RgXOCPPPoxibxohxoehPLieM0l7LYcF5DQKg7fTxZYOpmtiP--nibJxomXdVQNLSnZuQwnyWtlp_gYmqrYMMN1LPSmNCgZMZZZIYttaaAIA96SylglqubowJRShtDO9rSvUz_sgeCo7qo5Bfb0B5n9_PtIlr1CZSVoHyYj2lVqQldx7fnGuqqQJCfDQog"
client_assertion: File.read(client_assertion_with_nonexistent_client_id_path)
end
it "should return an error" do
......
......@@ -60,7 +60,26 @@ def photo_fixture_name
end
def jwks_file_path
@jwks_file = "../../spec/fixtures/jwks.json"
@jwks_file = File.join(File.dirname(__FILE__), "fixtures", "jwks.json")
end
def valid_client_assertion_path
@valid_client_assertion = File.join(File.dirname(__FILE__), "fixtures", "valid_client_assertion.txt")
end
def client_assertion_with_tampered_sig_path
@client_assertion_with_tampered_sig = File.join(File.dirname(__FILE__), "fixtures",
"client_assertion_with_tampered_sig.txt")
end
def client_assertion_with_nonexistent_kid_path
@client_assertion_with_nonexistent_kid = File.join(File.dirname(__FILE__), "fixtures",
"client_assertion_with_nonexistent_kid.txt")
end
def client_assertion_with_nonexistent_client_id_path
@client_assertion_with_nonexistent_client_id = File.join(File.dirname(__FILE__), "fixtures",
"client_assertion_with_nonexistent_client_id.txt")
end
# Force fixture rebuild
......
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Veuillez vous inscrire ou vous pour commenter