Verify token signature for authenticated login

We were just logging in any user without password or other verification
before. Now we verify the Keycloak signature and know that the person is
indeed logged in.
This commit is contained in:
Maikel Linke
2022-11-10 15:58:49 +11:00
committed by David Cook
parent 33ee03388f
commit 029c0afaa9
3 changed files with 42 additions and 4 deletions

View File

@@ -4,12 +4,25 @@
# It controls an OICD Access token and an enterprise.
module DfcProvider
class AuthorizationControl
# Copied from: https://login.lescommuns.org/auth/realms/data-food-consortium/
LES_COMMUNES_PUBLIC_KEY = <<~KEY
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAl68JGqAILFzoi/1+6siXXp2vylu+7mPjYKjKelTtHFYXWVkbmVptCsamHlY3jRhqSQYe6M1SKfw8D+uXrrWsWficYvpdlV44Vm7uETZOr1/XBOjpWOi1vLmBVtX6jFeqN1BxfE1PxLROAiGn+MeMg90AJKShD2c5RoNv26e20dgPhshRVFPUGru+0T1RoKyIa64z/qcTcTVD2V7KX+ANMweRODdoPAzQFGGjTnL1uUqIdUwSfHSpXYnKxXOsnPC3Mowkv8UIGWWDxS/yzhWc7sOk1NmC7pb+Cg7G8NKj+Pp9qQZnXF39Dg95ZsxJrl6fyPFvTo3zf9CPG/fUM1CkkwIDAQAB
-----END PUBLIC KEY-----
KEY
def self.public_key
OpenSSL::PKey::RSA.new(LES_COMMUNES_PUBLIC_KEY)
end
def initialize(request)
@request = request
end
def user
oidc_user || ofn_user
rescue JWT::ExpiredSignature
nil
end
private
@@ -23,7 +36,11 @@ module DfcProvider
end
def decode_token
JWT.decode(access_token, nil, false).first
JWT.decode(
access_token,
self.class.public_key,
true, { algorithm: "RS256" }
).first
end
def access_token

View File

@@ -1,13 +1,15 @@
# frozen_string_literal: true
require 'spec_helper'
require DfcProvider::Engine.root.join("spec/spec_helper")
describe DfcProvider::AuthorizationControl do
include AuthorizationHelper
let(:user) { create(:user) }
describe "with OIDC token" do
it "finds a user" do
token = JWT.encode({ email: user.email }, nil)
token = allow_token_for(email: user.email)
auth = described_class.new(
double(:request,
headers: { "Authorization" => "Bearer #{token}" })
@@ -15,5 +17,16 @@ describe DfcProvider::AuthorizationControl do
expect(auth.user).to eq user
end
it "ignores expired signatures" do
token = allow_token_for(exp: Time.now.to_i, email: user.email)
auth = described_class.new(
double(:request,
headers: { "Authorization" => "Bearer #{token}" })
)
expect(auth.user).to eq nil
end
end
end

View File

@@ -2,7 +2,15 @@
module AuthorizationHelper
def authorise(email)
token = JWT.encode({ email: email }, nil)
token = allow_token_for(email: email)
request.headers["Authorization"] = "JWT #{token}"
end
def allow_token_for(payload)
private_key = OpenSSL::PKey::RSA.generate 2048
allow(DfcProvider::AuthorizationControl).to receive(:public_key).
and_return(private_key.public_key)
JWT.encode(payload, private_key, "RS256")
end
end