sources/saml: switch to new crypto
This commit is contained in:
parent
8df55f22aa
commit
dc8b89a6b9
|
@ -17,7 +17,7 @@ class SAMLSourceSerializer(ModelSerializer):
|
||||||
"idp_url",
|
"idp_url",
|
||||||
"idp_logout_url",
|
"idp_logout_url",
|
||||||
"auto_logout",
|
"auto_logout",
|
||||||
"signing_cert",
|
"signing_kp",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,19 +5,12 @@ from django.contrib.admin.widgets import FilteredSelectMultiple
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
|
|
||||||
from passbook.admin.forms.source import SOURCE_FORM_FIELDS
|
from passbook.admin.forms.source import SOURCE_FORM_FIELDS
|
||||||
from passbook.providers.saml.utils.cert import CertificateBuilder
|
|
||||||
from passbook.sources.saml.models import SAMLSource
|
from passbook.sources.saml.models import SAMLSource
|
||||||
|
|
||||||
|
|
||||||
class SAMLSourceForm(forms.ModelForm):
|
class SAMLSourceForm(forms.ModelForm):
|
||||||
"""SAML Provider form"""
|
"""SAML Provider form"""
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
builder = CertificateBuilder()
|
|
||||||
builder.build()
|
|
||||||
self.fields["signing_cert"].initial = builder.certificate
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
||||||
model = SAMLSource
|
model = SAMLSource
|
||||||
|
@ -26,7 +19,7 @@ class SAMLSourceForm(forms.ModelForm):
|
||||||
"idp_url",
|
"idp_url",
|
||||||
"idp_logout_url",
|
"idp_logout_url",
|
||||||
"auto_logout",
|
"auto_logout",
|
||||||
"signing_cert",
|
"signing_kp",
|
||||||
]
|
]
|
||||||
widgets = {
|
widgets = {
|
||||||
"name": forms.TextInput(),
|
"name": forms.TextInput(),
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
# Generated by Django 3.0.3 on 2020-03-03 22:01
|
||||||
|
|
||||||
|
import django.db.models.deletion
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("passbook_crypto", "0001_initial"),
|
||||||
|
("passbook_sources_saml", "0005_auto_20200220_1621"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(model_name="samlsource", name="signing_cert",),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="samlsource",
|
||||||
|
name="signing_kp",
|
||||||
|
field=models.ForeignKey(
|
||||||
|
default=None,
|
||||||
|
help_text="Certificate Key Pair of the IdP which Assertions are validated against.",
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.SET_NULL,
|
||||||
|
to="passbook_crypto.CertificateKeyPair",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
|
@ -5,6 +5,7 @@ from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from passbook.core.models import Source
|
from passbook.core.models import Source
|
||||||
from passbook.core.types import UILoginButton
|
from passbook.core.types import UILoginButton
|
||||||
|
from passbook.crypto.models import CertificateKeyPair
|
||||||
|
|
||||||
|
|
||||||
class SAMLSource(Source):
|
class SAMLSource(Source):
|
||||||
|
@ -22,7 +23,16 @@ class SAMLSource(Source):
|
||||||
default=None, blank=True, null=True, verbose_name=_("IDP Logout URL")
|
default=None, blank=True, null=True, verbose_name=_("IDP Logout URL")
|
||||||
)
|
)
|
||||||
auto_logout = models.BooleanField(default=False)
|
auto_logout = models.BooleanField(default=False)
|
||||||
signing_cert = models.TextField()
|
|
||||||
|
signing_kp = models.ForeignKey(
|
||||||
|
CertificateKeyPair,
|
||||||
|
default=None,
|
||||||
|
null=True,
|
||||||
|
help_text=_(
|
||||||
|
"Certificate Key Pair of the IdP which Assertions are validated against."
|
||||||
|
),
|
||||||
|
on_delete=models.SET_NULL,
|
||||||
|
)
|
||||||
|
|
||||||
form = "passbook.sources.saml.forms.SAMLSourceForm"
|
form = "passbook.sources.saml.forms.SAMLSourceForm"
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ class Processor:
|
||||||
def _verify_signed(self):
|
def _verify_signed(self):
|
||||||
"""Verify SAML Response's Signature"""
|
"""Verify SAML Response's Signature"""
|
||||||
verifier = XMLVerifier()
|
verifier = XMLVerifier()
|
||||||
verifier.verify(self._root_xml, x509_cert=self._source.signing_cert)
|
verifier.verify(self._root_xml, x509_cert=self._source.signing_kp.certificate)
|
||||||
|
|
||||||
def _get_email(self) -> Optional[str]:
|
def _get_email(self) -> Optional[str]:
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -101,9 +101,9 @@ class MetadataView(View):
|
||||||
"""Replies with the XML Metadata SPSSODescriptor."""
|
"""Replies with the XML Metadata SPSSODescriptor."""
|
||||||
source: SAMLSource = get_object_or_404(SAMLSource, slug=source_slug)
|
source: SAMLSource = get_object_or_404(SAMLSource, slug=source_slug)
|
||||||
issuer = get_issuer(request, source)
|
issuer = get_issuer(request, source)
|
||||||
cert_stripped = strip_pem_header(source.signing_cert.replace("\r", "")).replace(
|
cert_stripped = strip_pem_header(
|
||||||
"\n", ""
|
source.signing_kp.certificate_data.replace("\r", "")
|
||||||
)
|
).replace("\n", "")
|
||||||
return render_xml(
|
return render_xml(
|
||||||
request,
|
request,
|
||||||
"saml/sp/xml/sp_sso_descriptor.xml",
|
"saml/sp/xml/sp_sso_descriptor.xml",
|
||||||
|
|
Reference in New Issue