FusionAuth / fusionauth-issues

FusionAuth issue submission project
https://fusionauth.io
90 stars 12 forks source link

SAML Certificate error when running on Docker #2308

Open vcampitelli opened 1 year ago

vcampitelli commented 1 year ago

SAML Certificate error when running on Docker

Description

I have a local FusionAuth instance running on Docker and I've exposed it with ngrok following our guide.

When using it as a SAML Identity Provider with a custom certificate, I'm receiving a java.lang.NullPointerException:

2023-06-07 12:27:48.348 PM ERROR io.fusionauth.app.primeframework.error.ExceptionExceptionHandler - An unhandled exception was thrown
java.lang.NullPointerException: null
    at java.base/java.util.Objects.requireNonNull(Objects.java:208)
    at io.fusionauth.pem.PEMDecoder.decode(PEMDecoder.java:106)
    at io.fusionauth.pem.domain.PEM.decode(PEM.java:111)

Here's the full stack trace: saml-certificate-issue.log.

@ColinFrick also had the same problem (see https://github.com/FusionAuth/fusionauth-site/pull/2085#pullrequestreview-1439182969).

The same certificate gives no error when using a cloud-based instance and I can log in normally.

Affects versions

Steps to reproduce

Steps to reproduce the behavior:

  1. Set up FusionAuth locally with Docker
  2. Import these private and public keys to the Key Master
  3. Create an application, enable SAML and use those keys as the signing key.
  4. Open the Metadata URL from that application.
  5. Receive error

Expected behavior

Normal login as it happens with the cloud-based instance.

Platform

Community guidelines

All issues filed in this repository must abide by the FusionAuth community guidelines.

mooreds commented 1 year ago

Does this occur only with certificates that are v3 and imported to Key Manager (using https://github.com/FusionAuth/fusionauth-example-scripts/tree/master/v3-certificate ), or also with certificates that are generated by FusionAuth?

ColinFrick commented 1 year ago

@mooreds Aiven does not support v1 certificates, so it's not possible to verify.

mooreds commented 1 year ago

Hmmm. You could see if you see the same SAML behavior with another SAML integration which does support non-v3 certs?

Also, did you all update the issuer (on the tenant) and set the http headers (as documented in the proxy guide) when using ngrok?

vcampitelli commented 1 year ago

Hi @mooreds, it seems that this is happening even when I try to access the Metadata URL for the application: issue2308.log.txt.

So I don't think it's actually related to ngrok because the same error occurs when viewing the Metadata URL with the localhost URL instead of ngrok's. Maybe it is something related to running on Docker, because it does work on https://integration-test.fusionauth.io/samlv2/metadata/ac57c653-0aeb-705e-3a51-9dca1e2032b1. I have edited the issue to remove mentions to ngrok.

jobannon commented 1 year ago

Reproduced using local dev setup and Ngrok.

robotdan commented 1 year ago

@jobannon can you add your repro steps please? Specifically the steps around how you created or imported keys, what types of keys, etc.

jobannon commented 1 year ago

I was following the aiven tutorial for this. https://fusionauth.io/docs/v1/tech/samlv2/aiven#overview

So this script that created the keys

#!/bin/bash

# Checking openssl
if [[ -z $(which openssl) ]]; then
  echo "Please download openssl and make sure it is available in your PATH variable"
  echo "Homepage: https://www.openssl.org/"
  exit 1
fi

# Checking jq
if [[ -z $(which jq) ]]; then
  echo "Please download jq and make sure it is available in your PATH variable"
  echo "jq is used to parse JSON elements"
  echo "Homepage: https://stedolan.github.io/jq/"
  exit 1
fi

# FusionAuth URL
read -r -p "Your FusionAuth instance URL (with scheme): " FA_URL
regex='^https?:\/\/[^\/]+(:[0-9]+\/)?$'
if ! [[ $FA_URL =~ $regex ]]; then
  echo "FusionAuth URL is not valid. Please make sure you have included the scheme (http:// or https://)."
  exit 2
fi

# Extracting domain from URL
FA_DOMAIN=$(echo "$FA_URL" | awk -F/ '{print $3}')
if [[ -z "$FA_DOMAIN" ]]; then
  echo "FusionAuth URL is not valid. Please make sure you have included the scheme (http:// or https://)."
  exit 2
fi

# FusionAuth API Key
read -r -p "API Key with /api/key/import endpoint:      " API_KEY
if [[ -z "$API_KEY" ]]; then
  echo "Please provide an API Key."
  exit 2
fi

# Key name
read -r -p "Name for the generated key:                 " NAME
if [[ -z "$NAME" ]]; then
  echo "Please provide a valid name for the key."
  exit 2
fi

# Creating temporary files for public and private keys
PRIVATE_KEY_FILE=$(mktemp)
if [[ -z "$PRIVATE_KEY_FILE" ]]; then
  echo "Cannot create private key. Please make sure your temporary directory is writable."
  exit 3
fi
PUBLIC_KEY_FILE=$(mktemp)
if [[ -z "$PUBLIC_KEY_FILE" ]]; then
  echo "Cannot create public key. Please make sure your temporary directory is writable."
  exit 3
fi

# Creating certificate
RSA_LENGTH=2048
echo "Generating certificate..."
if ! openssl req -x509 -newkey "rsa:$RSA_LENGTH" -nodes -keyout "$PRIVATE_KEY_FILE" -out "$PUBLIC_KEY_FILE" -sha256 -days 3650 -subj "/CN=$FA_DOMAIN/"; then
  echo "Error generating certificate. Check messages above for more details."
  exit 4
fi
PUBLIC_KEY=$(cat "$PUBLIC_KEY_FILE")
PRIVATE_KEY=$(cat "$PRIVATE_KEY_FILE")

# shellcheck disable=SC2016
JSON_TEMPLATE='{
  "key": {
    "algorithm": "RS256",
    "name": $name,
    "publicKey": $publicKey,
    "privateKey": $privateKey,
    "length": $rsaLength
  }
}'

# Uploading keys to the key master
echo "Uploading to the Key Master..."
JSON=$(jq --null-input \
  --arg name "$NAME" \
  --arg publicKey "$PUBLIC_KEY" \
  --arg privateKey "$PRIVATE_KEY" \
  --arg rsaLength "$RSA_LENGTH" \
  "$JSON_TEMPLATE")
if ! curl --fail-with-body -s -o /dev/null \
  -d "$JSON" \
  -H "Authorization: $API_KEY" \
  -H "Content-type: application/json" \
  "$FA_URL/api/key/import"; then
  echo "Error uploading certificate to the Key Master. Check messages above for more details."
  exit 5
fi

echo "Successfully uploaded key to the Key Master."
echo "Here is the generated public key:"
echo "$PUBLIC_KEY"