mirror of
https://github.com/goauthentik/authentik
synced 2026-04-25 17:15:26 +02:00
enterprise/providers: WS-Federation (#19583)
* init Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix metadata Signed-off-by: Jens Langhammer <jens@goauthentik.io> * aight Signed-off-by: Jens Langhammer <jens@goauthentik.io> * progress Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix timedelta Signed-off-by: Jens Langhammer <jens@goauthentik.io> * start testing metadata Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add some more tests and schemas Signed-off-by: Jens Langhammer <jens@goauthentik.io> * test signature Signed-off-by: Jens Langhammer <jens@goauthentik.io> * attempt to fix signed xml linebreak https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/issues/1258 https://github.com/robrichards/xmlseclibs/issues/28 https://github.com/xmlsec/python-xmlsec/issues/196 Signed-off-by: Jens Langhammer <jens@goauthentik.io> * format + gen Signed-off-by: Jens Langhammer <jens@goauthentik.io> * update web Signed-off-by: Jens Langhammer <jens@goauthentik.io> * more validation Signed-off-by: Jens Langhammer <jens@goauthentik.io> * hmm Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add e2e test Signed-off-by: Jens Langhammer <jens@goauthentik.io> * qol fix in wait_for_url Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add UI Signed-off-by: Jens Langhammer <jens@goauthentik.io> * acs -> reply url Signed-off-by: Jens Langhammer <jens@goauthentik.io> * sign_out Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix some XML typing Signed-off-by: Jens Langhammer <jens@goauthentik.io> * remove verification_kp as its not used Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix reply url Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add ws-fed to tests Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add logout test Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add SAMLSession Signed-off-by: Jens Langhammer <jens@goauthentik.io> * refactor Signed-off-by: Jens Langhammer <jens@goauthentik.io> * unrelated type fixes Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add backchannel logout Signed-off-by: Jens Langhammer <jens@goauthentik.io> * delete import_metadata in wsfed Signed-off-by: Jens Langhammer <jens@goauthentik.io> * include generated realm Signed-off-by: Jens Langhammer <jens@goauthentik.io> * Update web/src/admin/providers/wsfed/WSFederationProviderViewPage.ts Co-authored-by: Teffen Ellis <592134+GirlBossRush@users.noreply.github.com> Signed-off-by: Jens L. <jens@beryju.org> * include wtrealm in ui Signed-off-by: Jens Langhammer <jens@goauthentik.io> --------- Signed-off-by: Jens Langhammer <jens@goauthentik.io> Signed-off-by: Jens L. <jens@beryju.org> Co-authored-by: Teffen Ellis <592134+GirlBossRush@users.noreply.github.com>
This commit is contained in:
2
.github/workflows/ci-main.yml
vendored
2
.github/workflows/ci-main.yml
vendored
@@ -187,6 +187,8 @@ jobs:
|
||||
glob: tests/e2e/test_provider_saml* tests/e2e/test_source_saml*
|
||||
- name: ldap
|
||||
glob: tests/e2e/test_provider_ldap* tests/e2e/test_source_ldap*
|
||||
- name: ws-fed
|
||||
glob: tests/e2e/test_provider_ws_fed*
|
||||
- name: radius
|
||||
glob: tests/e2e/test_provider_radius*
|
||||
- name: scim
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
"""WSFederationProvider API Views"""
|
||||
|
||||
from django.http import HttpRequest
|
||||
from django.urls import reverse
|
||||
from rest_framework.fields import SerializerMethodField, URLField
|
||||
|
||||
from authentik.core.api.providers import ProviderSerializer
|
||||
from authentik.core.models import Application
|
||||
from authentik.enterprise.api import EnterpriseRequiredMixin
|
||||
from authentik.enterprise.providers.ws_federation.models import WSFederationProvider
|
||||
from authentik.enterprise.providers.ws_federation.processors.metadata import MetadataProcessor
|
||||
from authentik.providers.saml.api.providers import SAMLProviderSerializer, SAMLProviderViewSet
|
||||
|
||||
|
||||
class WSFederationProviderSerializer(EnterpriseRequiredMixin, SAMLProviderSerializer):
|
||||
"""WSFederationProvider Serializer"""
|
||||
|
||||
reply_url = URLField(source="acs_url")
|
||||
url_wsfed = SerializerMethodField()
|
||||
wtrealm = SerializerMethodField()
|
||||
|
||||
def get_url_wsfed(self, instance: WSFederationProvider) -> str:
|
||||
"""Get WS-Fed url"""
|
||||
if "request" not in self._context:
|
||||
return ""
|
||||
request: HttpRequest = self._context["request"]._request
|
||||
return request.build_absolute_uri(reverse("authentik_providers_ws_federation:wsfed"))
|
||||
|
||||
def get_wtrealm(self, instance: WSFederationProvider) -> str:
|
||||
try:
|
||||
return f"goauthentik.io://app/{instance.application.slug}"
|
||||
except Application.DoesNotExist:
|
||||
return None
|
||||
|
||||
class Meta(SAMLProviderSerializer.Meta):
|
||||
model = WSFederationProvider
|
||||
fields = ProviderSerializer.Meta.fields + [
|
||||
"reply_url",
|
||||
"assertion_valid_not_before",
|
||||
"assertion_valid_not_on_or_after",
|
||||
"session_valid_not_on_or_after",
|
||||
"property_mappings",
|
||||
"name_id_mapping",
|
||||
"authn_context_class_ref_mapping",
|
||||
"digest_algorithm",
|
||||
"signature_algorithm",
|
||||
"signing_kp",
|
||||
"encryption_kp",
|
||||
"sign_assertion",
|
||||
"sign_logout_request",
|
||||
"default_name_id_policy",
|
||||
"url_download_metadata",
|
||||
"url_wsfed",
|
||||
"wtrealm",
|
||||
]
|
||||
extra_kwargs = ProviderSerializer.Meta.extra_kwargs
|
||||
|
||||
|
||||
class WSFederationProviderViewSet(SAMLProviderViewSet):
|
||||
"""WSFederationProvider Viewset"""
|
||||
|
||||
queryset = WSFederationProvider.objects.all()
|
||||
serializer_class = WSFederationProviderSerializer
|
||||
filterset_fields = "__all__"
|
||||
ordering = ["name"]
|
||||
search_fields = ["name"]
|
||||
|
||||
metadata_generator_class = MetadataProcessor
|
||||
import_metadata = None
|
||||
13
authentik/enterprise/providers/ws_federation/apps.py
Normal file
13
authentik/enterprise/providers/ws_federation/apps.py
Normal file
@@ -0,0 +1,13 @@
|
||||
"""WSFed app config"""
|
||||
|
||||
from authentik.enterprise.apps import EnterpriseConfig
|
||||
|
||||
|
||||
class AuthentikEnterpriseProviderWSFederatopm(EnterpriseConfig):
|
||||
"""authentik enterprise ws federation app config"""
|
||||
|
||||
name = "authentik.enterprise.providers.ws_federation"
|
||||
label = "authentik_providers_ws_federation"
|
||||
verbose_name = "authentik Enterprise.Providers.WS-Federation"
|
||||
default = True
|
||||
mountpoint = "application/wsfed/"
|
||||
@@ -0,0 +1,37 @@
|
||||
# Generated by Django 5.2.10 on 2026-01-18 23:25
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
("authentik_providers_saml", "0020_samlprovider_logout_method_and_more"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="WSFederationProvider",
|
||||
fields=[
|
||||
(
|
||||
"samlprovider_ptr",
|
||||
models.OneToOneField(
|
||||
auto_created=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
parent_link=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
to="authentik_providers_saml.samlprovider",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "WS-Federation Provider",
|
||||
"verbose_name_plural": "WS-Federation Providers",
|
||||
},
|
||||
bases=("authentik_providers_saml.samlprovider",),
|
||||
),
|
||||
]
|
||||
32
authentik/enterprise/providers/ws_federation/models.py
Normal file
32
authentik/enterprise/providers/ws_federation/models.py
Normal file
@@ -0,0 +1,32 @@
|
||||
from django.templatetags.static import static
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework.serializers import Serializer
|
||||
|
||||
from authentik.providers.saml.models import SAMLProvider
|
||||
|
||||
|
||||
class WSFederationProvider(SAMLProvider):
|
||||
"""WS-Federation for applications which support WS-Fed."""
|
||||
|
||||
@property
|
||||
def serializer(self) -> type[Serializer]:
|
||||
from authentik.enterprise.providers.ws_federation.api.providers import (
|
||||
WSFederationProviderSerializer,
|
||||
)
|
||||
|
||||
return WSFederationProviderSerializer
|
||||
|
||||
@property
|
||||
def icon_url(self) -> str | None:
|
||||
return static("authentik/sources/wsfed.svg")
|
||||
|
||||
@property
|
||||
def component(self) -> str:
|
||||
return "ak-provider-wsfed-form"
|
||||
|
||||
def __str__(self):
|
||||
return f"WS-Federation Provider {self.name}"
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("WS-Federation Provider")
|
||||
verbose_name_plural = _("WS-Federation Providers")
|
||||
@@ -0,0 +1,39 @@
|
||||
from authentik.sources.saml.processors.constants import NS_MAP as _map
|
||||
|
||||
WS_FED_ACTION_SIGN_IN = "wsignin1.0"
|
||||
WS_FED_ACTION_SIGN_OUT = "wsignout1.0"
|
||||
WS_FED_ACTION_SIGN_OUT_CLEANUP = "wsignoutcleanup1.0"
|
||||
|
||||
WS_FED_POST_KEY_ACTION = "wa"
|
||||
WS_FED_POST_KEY_RESULT = "wresult"
|
||||
WS_FED_POST_KEY_CONTEXT = "wctx"
|
||||
|
||||
WSS_TOKEN_TYPE_SAML2 = (
|
||||
"http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0" # nosec
|
||||
)
|
||||
WSS_KEY_IDENTIFIER_SAML_ID = (
|
||||
"http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLID"
|
||||
)
|
||||
|
||||
NS_WS_FED_PROTOCOL = "http://docs.oasis-open.org/wsfed/federation/200706"
|
||||
NS_WS_FED_TRUST = "http://schemas.xmlsoap.org/ws/2005/02/trust"
|
||||
NS_WSI = "http://www.w3.org/2001/XMLSchema-instance"
|
||||
NS_ADDRESSING = "http://www.w3.org/2005/08/addressing"
|
||||
NS_POLICY = "http://schemas.xmlsoap.org/ws/2004/09/policy"
|
||||
NS_WSS_SEC = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
|
||||
NS_WSS_UTILITY = (
|
||||
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
|
||||
)
|
||||
NS_WSS_D3P1 = "http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd"
|
||||
|
||||
NS_MAP = {
|
||||
**_map,
|
||||
"fed": NS_WS_FED_PROTOCOL,
|
||||
"xsi": NS_WSI,
|
||||
"wsa": NS_ADDRESSING,
|
||||
"t": NS_WS_FED_TRUST,
|
||||
"wsu": NS_WSS_UTILITY,
|
||||
"wsp": NS_POLICY,
|
||||
"wssec": NS_WSS_SEC,
|
||||
"d3p1": NS_WSS_D3P1,
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
from django.urls import reverse
|
||||
from lxml.etree import SubElement, _Element # nosec
|
||||
|
||||
from authentik.enterprise.providers.ws_federation.processors.constants import (
|
||||
NS_ADDRESSING,
|
||||
NS_MAP,
|
||||
NS_WS_FED_PROTOCOL,
|
||||
NS_WSI,
|
||||
)
|
||||
from authentik.providers.saml.processors.metadata import MetadataProcessor as BaseMetadataProcessor
|
||||
from authentik.sources.saml.processors.constants import NS_SAML_METADATA
|
||||
|
||||
|
||||
class MetadataProcessor(BaseMetadataProcessor):
|
||||
def add_children(self, entity_descriptor: _Element):
|
||||
self.add_role_descriptor_sts(entity_descriptor)
|
||||
super().add_children(entity_descriptor)
|
||||
|
||||
def add_endpoint(self, parent: _Element, name: str):
|
||||
endpoint = SubElement(parent, f"{{{NS_WS_FED_PROTOCOL}}}{name}", nsmap=NS_MAP)
|
||||
endpoint_ref = SubElement(endpoint, f"{{{NS_ADDRESSING}}}EndpointReference", nsmap=NS_MAP)
|
||||
|
||||
address = SubElement(endpoint_ref, f"{{{NS_ADDRESSING}}}Address", nsmap=NS_MAP)
|
||||
address.text = self.http_request.build_absolute_uri(
|
||||
reverse("authentik_providers_ws_federation:wsfed")
|
||||
)
|
||||
|
||||
def add_role_descriptor_sts(self, entity_descriptor: _Element):
|
||||
role_descriptor = SubElement(
|
||||
entity_descriptor, f"{{{NS_SAML_METADATA}}}RoleDescriptor", nsmap=NS_MAP
|
||||
)
|
||||
role_descriptor.attrib[f"{{{NS_WSI}}}type"] = "fed:SecurityTokenServiceType"
|
||||
role_descriptor.attrib["protocolSupportEnumeration"] = NS_WS_FED_PROTOCOL
|
||||
|
||||
signing_descriptor = self.get_signing_key_descriptor()
|
||||
if signing_descriptor is not None:
|
||||
role_descriptor.append(signing_descriptor)
|
||||
|
||||
self.add_endpoint(role_descriptor, "SecurityTokenServiceEndpoint")
|
||||
self.add_endpoint(role_descriptor, "PassiveRequestorEndpoint")
|
||||
@@ -0,0 +1,162 @@
|
||||
from dataclasses import dataclass
|
||||
from urllib.parse import urlparse
|
||||
|
||||
from django.http import HttpRequest
|
||||
from django.shortcuts import get_object_or_404
|
||||
from lxml import etree # nosec
|
||||
from lxml.etree import Element, SubElement, _Element # nosec
|
||||
|
||||
from authentik.core.models import Application
|
||||
from authentik.enterprise.providers.ws_federation.models import WSFederationProvider
|
||||
from authentik.enterprise.providers.ws_federation.processors.constants import (
|
||||
NS_ADDRESSING,
|
||||
NS_MAP,
|
||||
NS_POLICY,
|
||||
NS_WS_FED_TRUST,
|
||||
NS_WSS_D3P1,
|
||||
NS_WSS_SEC,
|
||||
NS_WSS_UTILITY,
|
||||
WS_FED_ACTION_SIGN_IN,
|
||||
WS_FED_POST_KEY_ACTION,
|
||||
WS_FED_POST_KEY_CONTEXT,
|
||||
WS_FED_POST_KEY_RESULT,
|
||||
WSS_KEY_IDENTIFIER_SAML_ID,
|
||||
WSS_TOKEN_TYPE_SAML2,
|
||||
)
|
||||
from authentik.lib.utils.time import timedelta_from_string
|
||||
from authentik.policies.utils import delete_none_values
|
||||
from authentik.providers.saml.processors.assertion import AssertionProcessor
|
||||
from authentik.providers.saml.processors.authn_request_parser import AuthNRequest
|
||||
from authentik.providers.saml.utils.time import get_time_string
|
||||
|
||||
|
||||
@dataclass()
|
||||
class SignInRequest:
|
||||
wa: str
|
||||
wtrealm: str
|
||||
wreply: str
|
||||
wctx: str | None
|
||||
|
||||
app_slug: str
|
||||
|
||||
@staticmethod
|
||||
def parse(request: HttpRequest) -> SignInRequest:
|
||||
action = request.GET.get("wa")
|
||||
if action != WS_FED_ACTION_SIGN_IN:
|
||||
raise ValueError("Invalid action")
|
||||
realm = request.GET.get("wtrealm")
|
||||
if not realm:
|
||||
raise ValueError("Missing Realm")
|
||||
parsed = urlparse(realm)
|
||||
|
||||
req = SignInRequest(
|
||||
wa=action,
|
||||
wtrealm=realm,
|
||||
wreply=request.GET.get("wreply"),
|
||||
wctx=request.GET.get("wctx", ""),
|
||||
app_slug=parsed.path[1:],
|
||||
)
|
||||
|
||||
_, provider = req.get_app_provider()
|
||||
if not req.wreply.startswith(provider.acs_url):
|
||||
raise ValueError("Invalid wreply")
|
||||
return req
|
||||
|
||||
def get_app_provider(self):
|
||||
application = get_object_or_404(Application, slug=self.app_slug)
|
||||
provider: WSFederationProvider = get_object_or_404(
|
||||
WSFederationProvider, pk=application.provider_id
|
||||
)
|
||||
return application, provider
|
||||
|
||||
|
||||
class SignInProcessor:
|
||||
provider: WSFederationProvider
|
||||
request: HttpRequest
|
||||
sign_in_request: SignInRequest
|
||||
saml_processor: AssertionProcessor
|
||||
|
||||
def __init__(
|
||||
self, provider: WSFederationProvider, request: HttpRequest, sign_in_request: SignInRequest
|
||||
):
|
||||
self.provider = provider
|
||||
self.request = request
|
||||
self.sign_in_request = sign_in_request
|
||||
self.saml_processor = AssertionProcessor(self.provider, self.request, AuthNRequest())
|
||||
self.saml_processor.provider.audience = self.sign_in_request.wtrealm
|
||||
|
||||
def create_response_token(self):
|
||||
root = Element(f"{{{NS_WS_FED_TRUST}}}RequestSecurityTokenResponse", nsmap=NS_MAP)
|
||||
|
||||
root.append(self.response_add_lifetime())
|
||||
root.append(self.response_add_applies_to())
|
||||
root.append(self.response_add_requested_security_token())
|
||||
root.append(
|
||||
self.response_add_attached_reference(
|
||||
"RequestedAttachedReference", self.saml_processor._assertion_id
|
||||
)
|
||||
)
|
||||
root.append(
|
||||
self.response_add_attached_reference(
|
||||
"RequestedUnattachedReference", self.saml_processor._assertion_id
|
||||
)
|
||||
)
|
||||
|
||||
token_type = SubElement(root, f"{{{NS_WS_FED_TRUST}}}TokenType")
|
||||
token_type.text = WSS_TOKEN_TYPE_SAML2
|
||||
|
||||
request_type = SubElement(root, f"{{{NS_WS_FED_TRUST}}}RequestType")
|
||||
request_type.text = "http://schemas.xmlsoap.org/ws/2005/02/trust/Issue"
|
||||
|
||||
key_type = SubElement(root, f"{{{NS_WS_FED_TRUST}}}KeyType")
|
||||
key_type.text = "http://schemas.xmlsoap.org/ws/2005/05/identity/NoProofKey"
|
||||
|
||||
return root
|
||||
|
||||
def response_add_lifetime(self) -> _Element:
|
||||
"""Add Lifetime element"""
|
||||
lifetime = Element(f"{{{NS_WS_FED_TRUST}}}Lifetime", nsmap=NS_MAP)
|
||||
created = SubElement(lifetime, f"{{{NS_WSS_UTILITY}}}Created")
|
||||
created.text = get_time_string()
|
||||
expires = SubElement(lifetime, f"{{{NS_WSS_UTILITY}}}Expires")
|
||||
expires.text = get_time_string(
|
||||
timedelta_from_string(self.provider.session_valid_not_on_or_after)
|
||||
)
|
||||
return lifetime
|
||||
|
||||
def response_add_applies_to(self) -> _Element:
|
||||
"""Add AppliesTo element"""
|
||||
applies_to = Element(f"{{{NS_POLICY}}}AppliesTo")
|
||||
endpoint_ref = SubElement(applies_to, f"{{{NS_ADDRESSING}}}EndpointReference")
|
||||
address = SubElement(endpoint_ref, f"{{{NS_ADDRESSING}}}Address")
|
||||
address.text = self.sign_in_request.wtrealm
|
||||
return applies_to
|
||||
|
||||
def response_add_requested_security_token(self) -> _Element:
|
||||
"""Add RequestedSecurityToken and child assertion"""
|
||||
token = Element(f"{{{NS_WS_FED_TRUST}}}RequestedSecurityToken")
|
||||
token.append(self.saml_processor.get_assertion())
|
||||
return token
|
||||
|
||||
def response_add_attached_reference(self, tag: str, value: str) -> _Element:
|
||||
ref = Element(f"{{{NS_WS_FED_TRUST}}}{tag}")
|
||||
sec_token_ref = SubElement(ref, f"{{{NS_WSS_SEC}}}SecurityTokenReference")
|
||||
sec_token_ref.attrib[f"{{{NS_WSS_D3P1}}}TokenType"] = WSS_TOKEN_TYPE_SAML2
|
||||
|
||||
key_identifier = SubElement(sec_token_ref, f"{{{NS_WSS_SEC}}}KeyIdentifier")
|
||||
key_identifier.attrib["ValueType"] = WSS_KEY_IDENTIFIER_SAML_ID
|
||||
key_identifier.text = value
|
||||
return ref
|
||||
|
||||
def response(self) -> dict[str, str]:
|
||||
root = self.create_response_token()
|
||||
assertion = root.xpath("//saml:Assertion", namespaces=NS_MAP)[0]
|
||||
self.saml_processor._sign(assertion)
|
||||
str_token = etree.tostring(root).decode("utf-8") # nosec
|
||||
return delete_none_values(
|
||||
{
|
||||
WS_FED_POST_KEY_ACTION: WS_FED_ACTION_SIGN_IN,
|
||||
WS_FED_POST_KEY_RESULT: str_token,
|
||||
WS_FED_POST_KEY_CONTEXT: self.sign_in_request.wctx,
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,47 @@
|
||||
from dataclasses import dataclass
|
||||
from urllib.parse import urlparse
|
||||
|
||||
from django.http import HttpRequest
|
||||
from django.shortcuts import get_object_or_404
|
||||
|
||||
from authentik.core.models import Application
|
||||
from authentik.enterprise.providers.ws_federation.models import WSFederationProvider
|
||||
from authentik.enterprise.providers.ws_federation.processors.constants import WS_FED_ACTION_SIGN_OUT
|
||||
|
||||
|
||||
@dataclass()
|
||||
class SignOutRequest:
|
||||
wa: str
|
||||
wtrealm: str
|
||||
wreply: str
|
||||
|
||||
app_slug: str
|
||||
|
||||
@staticmethod
|
||||
def parse(request: HttpRequest) -> SignOutRequest:
|
||||
action = request.GET.get("wa")
|
||||
if action != WS_FED_ACTION_SIGN_OUT:
|
||||
raise ValueError("Invalid action")
|
||||
realm = request.GET.get("wtrealm")
|
||||
if not realm:
|
||||
raise ValueError("Missing Realm")
|
||||
parsed = urlparse(realm)
|
||||
|
||||
req = SignOutRequest(
|
||||
wa=action,
|
||||
wtrealm=realm,
|
||||
wreply=request.GET.get("wreply"),
|
||||
app_slug=parsed.path[1:],
|
||||
)
|
||||
|
||||
_, provider = req.get_app_provider()
|
||||
if not req.wreply.startswith(provider.acs_url):
|
||||
raise ValueError("Invalid wreply")
|
||||
return req
|
||||
|
||||
def get_app_provider(self):
|
||||
application = get_object_or_404(Application, slug=self.app_slug)
|
||||
provider: WSFederationProvider = get_object_or_404(
|
||||
WSFederationProvider, pk=application.provider_id
|
||||
)
|
||||
return application, provider
|
||||
93
authentik/enterprise/providers/ws_federation/signals.py
Normal file
93
authentik/enterprise/providers/ws_federation/signals.py
Normal file
@@ -0,0 +1,93 @@
|
||||
"""WS-Fed Provider signals"""
|
||||
|
||||
from urllib.parse import urlencode, urlparse, urlunparse
|
||||
|
||||
from django.dispatch import receiver
|
||||
from django.http import HttpRequest
|
||||
from django.urls import reverse
|
||||
from django.utils import timezone
|
||||
from structlog.stdlib import get_logger
|
||||
|
||||
from authentik.core.models import AuthenticatedSession, User
|
||||
from authentik.enterprise.providers.ws_federation.models import WSFederationProvider
|
||||
from authentik.enterprise.providers.ws_federation.processors.constants import (
|
||||
WS_FED_ACTION_SIGN_OUT_CLEANUP,
|
||||
WS_FED_POST_KEY_ACTION,
|
||||
)
|
||||
from authentik.flows.models import in_memory_stage
|
||||
from authentik.flows.views.executor import FlowExecutorView
|
||||
from authentik.providers.iframe_logout import IframeLogoutStageView
|
||||
from authentik.providers.saml.models import SAMLBindings, SAMLSession
|
||||
from authentik.providers.saml.views.flows import (
|
||||
PLAN_CONTEXT_SAML_LOGOUT_IFRAME_SESSIONS,
|
||||
PLAN_CONTEXT_SAML_RELAY_STATE,
|
||||
)
|
||||
from authentik.stages.user_logout.models import UserLogoutStage
|
||||
from authentik.stages.user_logout.stage import flow_pre_user_logout
|
||||
|
||||
LOGGER = get_logger()
|
||||
|
||||
|
||||
@receiver(flow_pre_user_logout)
|
||||
def handle_ws_fed_iframe_pre_user_logout(
|
||||
sender, request: HttpRequest, user: User, executor: FlowExecutorView, **kwargs
|
||||
):
|
||||
"""Handle WS-Fed iframe logout when user logs out via flow"""
|
||||
|
||||
# Only proceed if this is actually a UserLogoutStage
|
||||
if not isinstance(executor.current_stage, UserLogoutStage):
|
||||
return
|
||||
|
||||
if not user.is_authenticated:
|
||||
return
|
||||
|
||||
auth_session = AuthenticatedSession.from_request(request, user)
|
||||
if not auth_session:
|
||||
return
|
||||
|
||||
wsfed_sessions = SAMLSession.objects.filter(
|
||||
session=auth_session,
|
||||
user=user,
|
||||
expires__gt=timezone.now(),
|
||||
expiring=True,
|
||||
# Only get WS-Federation provider sessions
|
||||
provider__wsfederationprovider__isnull=False,
|
||||
).select_related("provider__wsfederationprovider")
|
||||
|
||||
if not wsfed_sessions.exists():
|
||||
LOGGER.debug("No sessions requiring IFrame frontchannel logout")
|
||||
return
|
||||
|
||||
saml_sessions = []
|
||||
|
||||
relay_state = request.build_absolute_uri(
|
||||
reverse("authentik_core:if-flow", kwargs={"flow_slug": executor.flow.slug})
|
||||
)
|
||||
|
||||
# Store return URL in plan context as fallback if SP doesn't echo relay_state
|
||||
executor.plan.context[PLAN_CONTEXT_SAML_RELAY_STATE] = relay_state
|
||||
|
||||
for session in wsfed_sessions:
|
||||
provider: WSFederationProvider = session.provider.wsfederationprovider
|
||||
parts = urlparse(str(provider.acs_url))
|
||||
parts = parts._replace(
|
||||
query=urlencode({WS_FED_POST_KEY_ACTION: WS_FED_ACTION_SIGN_OUT_CLEANUP})
|
||||
)
|
||||
logout_data = {
|
||||
"url": urlunparse(parts),
|
||||
"provider_name": provider.name,
|
||||
"binding": SAMLBindings.REDIRECT,
|
||||
}
|
||||
|
||||
saml_sessions.append(logout_data)
|
||||
|
||||
if saml_sessions:
|
||||
executor.plan.context[PLAN_CONTEXT_SAML_LOGOUT_IFRAME_SESSIONS] = saml_sessions
|
||||
# Stage already exists, don't reinject it
|
||||
if not any(
|
||||
binding.stage.view == IframeLogoutStageView for binding in executor.plan.bindings
|
||||
):
|
||||
iframe_stage = in_memory_stage(IframeLogoutStageView)
|
||||
executor.plan.insert_stage(iframe_stage, index=1)
|
||||
|
||||
LOGGER.debug("WSFed iframe sessions gathered")
|
||||
@@ -0,0 +1,40 @@
|
||||
from django.test import TestCase
|
||||
from lxml import etree # nosec
|
||||
|
||||
from authentik.core.models import Application
|
||||
from authentik.core.tests.utils import RequestFactory, create_test_flow
|
||||
from authentik.enterprise.providers.ws_federation.models import WSFederationProvider
|
||||
from authentik.enterprise.providers.ws_federation.processors.metadata import MetadataProcessor
|
||||
from authentik.lib.generators import generate_id
|
||||
from authentik.lib.xml import lxml_from_string
|
||||
|
||||
|
||||
class TestWSFedMetadata(TestCase):
|
||||
def setUp(self):
|
||||
self.flow = create_test_flow()
|
||||
self.provider = WSFederationProvider.objects.create(
|
||||
name=generate_id(),
|
||||
authorization_flow=self.flow,
|
||||
)
|
||||
self.app = Application.objects.create(
|
||||
name=generate_id(), slug=generate_id(), provider=self.provider
|
||||
)
|
||||
self.factory = RequestFactory()
|
||||
|
||||
def test_metadata_generation(self):
|
||||
request = self.factory.get("/")
|
||||
metadata_a = MetadataProcessor(self.provider, request).build_entity_descriptor()
|
||||
metadata_b = MetadataProcessor(self.provider, request).build_entity_descriptor()
|
||||
self.assertEqual(metadata_a, metadata_b)
|
||||
|
||||
def test_schema(self):
|
||||
"""Test that metadata generation is consistent"""
|
||||
request = self.factory.get("/")
|
||||
metadata = lxml_from_string(
|
||||
MetadataProcessor(self.provider, request).build_entity_descriptor()
|
||||
)
|
||||
|
||||
schema = etree.XMLSchema(
|
||||
etree.parse(source="schemas/ws-federation.xsd", parser=etree.XMLParser()) # nosec
|
||||
)
|
||||
self.assertTrue(schema.validate(metadata))
|
||||
@@ -0,0 +1,85 @@
|
||||
import xmlsec
|
||||
from django.test import TestCase
|
||||
from guardian.utils import get_anonymous_user
|
||||
from lxml import etree # nosec
|
||||
|
||||
from authentik.core.models import Application
|
||||
from authentik.core.tests.utils import RequestFactory, create_test_cert, create_test_flow
|
||||
from authentik.enterprise.providers.ws_federation.models import WSFederationProvider
|
||||
from authentik.enterprise.providers.ws_federation.processors.constants import (
|
||||
NS_MAP,
|
||||
WS_FED_ACTION_SIGN_IN,
|
||||
WS_FED_POST_KEY_RESULT,
|
||||
)
|
||||
from authentik.enterprise.providers.ws_federation.processors.sign_in import (
|
||||
SignInProcessor,
|
||||
SignInRequest,
|
||||
)
|
||||
from authentik.lib.generators import generate_id
|
||||
from authentik.lib.xml import lxml_from_string
|
||||
|
||||
|
||||
class TestWSFedSignIn(TestCase):
|
||||
def setUp(self):
|
||||
self.flow = create_test_flow()
|
||||
self.cert = create_test_cert()
|
||||
self.provider = WSFederationProvider.objects.create(
|
||||
name=generate_id(),
|
||||
authorization_flow=self.flow,
|
||||
signing_kp=self.cert,
|
||||
)
|
||||
self.app = Application.objects.create(
|
||||
name=generate_id(), slug=generate_id(), provider=self.provider
|
||||
)
|
||||
self.factory = RequestFactory()
|
||||
|
||||
def test_token_gen(self):
|
||||
request = self.factory.get("/", user=get_anonymous_user())
|
||||
proc = SignInProcessor(
|
||||
self.provider,
|
||||
request,
|
||||
SignInRequest(
|
||||
wa=WS_FED_ACTION_SIGN_IN,
|
||||
wtrealm="",
|
||||
wreply="",
|
||||
wctx=None,
|
||||
app_slug="",
|
||||
),
|
||||
)
|
||||
token = proc.response()[WS_FED_POST_KEY_RESULT]
|
||||
|
||||
root = lxml_from_string(token)
|
||||
|
||||
schema = etree.XMLSchema(
|
||||
etree.parse(source="schemas/ws-trust.xsd", parser=etree.XMLParser()) # nosec
|
||||
)
|
||||
self.assertTrue(schema.validate(etree=root), schema.error_log)
|
||||
|
||||
def test_signature(self):
|
||||
request = self.factory.get("/", user=get_anonymous_user())
|
||||
proc = SignInProcessor(
|
||||
self.provider,
|
||||
request,
|
||||
SignInRequest(
|
||||
wa=WS_FED_ACTION_SIGN_IN,
|
||||
wtrealm="",
|
||||
wreply="",
|
||||
wctx=None,
|
||||
app_slug="",
|
||||
),
|
||||
)
|
||||
token = proc.response()[WS_FED_POST_KEY_RESULT]
|
||||
|
||||
root = lxml_from_string(token)
|
||||
xmlsec.tree.add_ids(root, ["ID"])
|
||||
signature_nodes = root.xpath("//saml:Assertion/ds:Signature", namespaces=NS_MAP)
|
||||
self.assertEqual(len(signature_nodes), 1)
|
||||
|
||||
signature_node = signature_nodes[0]
|
||||
ctx = xmlsec.SignatureContext()
|
||||
ctx.key = xmlsec.Key.from_memory(
|
||||
self.cert.certificate_data,
|
||||
xmlsec.constants.KeyDataFormatCertPem,
|
||||
None,
|
||||
)
|
||||
ctx.verify(signature_node)
|
||||
18
authentik/enterprise/providers/ws_federation/urls.py
Normal file
18
authentik/enterprise/providers/ws_federation/urls.py
Normal file
@@ -0,0 +1,18 @@
|
||||
"""WS Fed provider URLs"""
|
||||
|
||||
from django.urls import path
|
||||
|
||||
from authentik.enterprise.providers.ws_federation.api.providers import WSFederationProviderViewSet
|
||||
from authentik.enterprise.providers.ws_federation.views import WSFedEntryView
|
||||
|
||||
urlpatterns = [
|
||||
path(
|
||||
"",
|
||||
WSFedEntryView.as_view(),
|
||||
name="wsfed",
|
||||
),
|
||||
]
|
||||
|
||||
api_urlpatterns = [
|
||||
("providers/wsfed", WSFederationProviderViewSet),
|
||||
]
|
||||
162
authentik/enterprise/providers/ws_federation/views.py
Normal file
162
authentik/enterprise/providers/ws_federation/views.py
Normal file
@@ -0,0 +1,162 @@
|
||||
from django.http import Http404, HttpRequest, HttpResponse
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.utils.translation import gettext as _
|
||||
from structlog.stdlib import get_logger
|
||||
|
||||
from authentik.core.models import Application, AuthenticatedSession
|
||||
from authentik.enterprise.providers.ws_federation.models import WSFederationProvider
|
||||
from authentik.enterprise.providers.ws_federation.processors.constants import (
|
||||
WS_FED_ACTION_SIGN_IN,
|
||||
WS_FED_ACTION_SIGN_OUT,
|
||||
)
|
||||
from authentik.enterprise.providers.ws_federation.processors.sign_in import (
|
||||
SignInProcessor,
|
||||
SignInRequest,
|
||||
)
|
||||
from authentik.enterprise.providers.ws_federation.processors.sign_out import SignOutRequest
|
||||
from authentik.flows.challenge import (
|
||||
PLAN_CONTEXT_TITLE,
|
||||
AutosubmitChallenge,
|
||||
AutoSubmitChallengeResponse,
|
||||
)
|
||||
from authentik.flows.exceptions import FlowNonApplicableException
|
||||
from authentik.flows.models import in_memory_stage
|
||||
from authentik.flows.planner import PLAN_CONTEXT_APPLICATION, PLAN_CONTEXT_SSO, FlowPlanner
|
||||
from authentik.flows.stage import ChallengeStageView, SessionEndStage
|
||||
from authentik.lib.views import bad_request_message
|
||||
from authentik.policies.views import PolicyAccessView, RequestValidationError
|
||||
from authentik.providers.saml.models import SAMLSession
|
||||
from authentik.stages.consent.stage import (
|
||||
PLAN_CONTEXT_CONSENT_HEADER,
|
||||
PLAN_CONTEXT_CONSENT_PERMISSIONS,
|
||||
)
|
||||
|
||||
PLAN_CONTEXT_WS_FED_REQUEST = "authentik/providers/ws_federation/request"
|
||||
LOGGER = get_logger()
|
||||
|
||||
|
||||
class WSFedEntryView(PolicyAccessView):
|
||||
req: SignInRequest | SignOutRequest
|
||||
|
||||
def pre_permission_check(self):
|
||||
self.action = self.request.GET.get("wa")
|
||||
try:
|
||||
if self.action == WS_FED_ACTION_SIGN_IN:
|
||||
self.req = SignInRequest.parse(self.request)
|
||||
elif self.action == WS_FED_ACTION_SIGN_OUT:
|
||||
self.req = SignOutRequest.parse(self.request)
|
||||
else:
|
||||
raise RequestValidationError(
|
||||
bad_request_message(self.request, "Invalid WS-Federation action")
|
||||
)
|
||||
except ValueError as exc:
|
||||
LOGGER.warning("Invalid WS-Fed request", exc=exc)
|
||||
raise RequestValidationError(
|
||||
bad_request_message(self.request, "Invalid WS-Federation request")
|
||||
) from None
|
||||
|
||||
def resolve_provider_application(self):
|
||||
self.application, self.provider = self.req.get_app_provider()
|
||||
|
||||
def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
|
||||
if self.action == WS_FED_ACTION_SIGN_IN:
|
||||
return self.ws_fed_sign_in()
|
||||
elif self.action == WS_FED_ACTION_SIGN_OUT:
|
||||
return self.ws_fed_sign_out()
|
||||
else:
|
||||
return HttpResponse("Unsupported WS-Federation action", status=400)
|
||||
|
||||
def ws_fed_sign_in(self) -> HttpResponse:
|
||||
planner = FlowPlanner(self.provider.authorization_flow)
|
||||
planner.allow_empty_flows = True
|
||||
try:
|
||||
plan = planner.plan(
|
||||
self.request,
|
||||
{
|
||||
PLAN_CONTEXT_SSO: True,
|
||||
PLAN_CONTEXT_APPLICATION: self.application,
|
||||
PLAN_CONTEXT_CONSENT_HEADER: _("You're about to sign into %(application)s.")
|
||||
% {"application": self.application.name},
|
||||
PLAN_CONTEXT_CONSENT_PERMISSIONS: [],
|
||||
PLAN_CONTEXT_WS_FED_REQUEST: self.req,
|
||||
},
|
||||
)
|
||||
except FlowNonApplicableException:
|
||||
raise Http404 from None
|
||||
plan.append_stage(in_memory_stage(WSFedFlowFinalView))
|
||||
return plan.to_redirect(
|
||||
self.request,
|
||||
self.provider.authorization_flow,
|
||||
)
|
||||
|
||||
def ws_fed_sign_out(self) -> HttpResponse:
|
||||
flow = self.provider.invalidation_flow or self.request.brand.flow_invalidation
|
||||
|
||||
planner = FlowPlanner(flow)
|
||||
planner.allow_empty_flows = True
|
||||
try:
|
||||
plan = planner.plan(
|
||||
self.request,
|
||||
{
|
||||
PLAN_CONTEXT_SSO: True,
|
||||
PLAN_CONTEXT_APPLICATION: self.application,
|
||||
PLAN_CONTEXT_WS_FED_REQUEST: self.req,
|
||||
},
|
||||
)
|
||||
except FlowNonApplicableException:
|
||||
raise Http404 from None
|
||||
plan.append_stage(in_memory_stage(SessionEndStage))
|
||||
return plan.to_redirect(self.request, flow)
|
||||
|
||||
|
||||
class WSFedFlowFinalView(ChallengeStageView):
|
||||
response_class = AutoSubmitChallengeResponse
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
if PLAN_CONTEXT_WS_FED_REQUEST not in self.executor.plan.context:
|
||||
self.logger.warning("No WS-Fed request in context")
|
||||
return self.executor.stage_invalid()
|
||||
return super().get(request, *args, **kwargs)
|
||||
|
||||
def get_challenge(self, *args, **kwargs):
|
||||
application: Application = self.executor.plan.context[PLAN_CONTEXT_APPLICATION]
|
||||
provider: WSFederationProvider = get_object_or_404(
|
||||
WSFederationProvider, pk=application.provider_id
|
||||
)
|
||||
sign_in_req: SignInRequest = self.executor.plan.context[PLAN_CONTEXT_WS_FED_REQUEST]
|
||||
proc = SignInProcessor(provider, self.request, sign_in_req)
|
||||
response = proc.response()
|
||||
saml_processor = proc.saml_processor
|
||||
|
||||
# Create SAMLSession to track this login
|
||||
auth_session = AuthenticatedSession.from_request(self.request, self.request.user)
|
||||
if auth_session:
|
||||
# Since samlsessions should only exist uniquely for an active session and a provider
|
||||
# any existing combination is likely an old, dead session
|
||||
SAMLSession.objects.filter(
|
||||
session_index=saml_processor.session_index, provider=provider
|
||||
).delete()
|
||||
|
||||
SAMLSession.objects.update_or_create(
|
||||
session_index=saml_processor.session_index,
|
||||
provider=provider,
|
||||
defaults={
|
||||
"user": self.request.user,
|
||||
"session": auth_session,
|
||||
"name_id": saml_processor.name_id,
|
||||
"name_id_format": saml_processor.name_id_format,
|
||||
"expires": saml_processor.session_not_on_or_after_datetime,
|
||||
"expiring": True,
|
||||
},
|
||||
)
|
||||
return AutosubmitChallenge(
|
||||
data={
|
||||
"component": "ak-stage-autosubmit",
|
||||
"title": self.executor.plan.context.get(
|
||||
PLAN_CONTEXT_TITLE,
|
||||
_("Redirecting to {app}...".format_map({"app": application.name})),
|
||||
),
|
||||
"url": sign_in_req.wreply,
|
||||
"attrs": response,
|
||||
},
|
||||
)
|
||||
@@ -10,6 +10,7 @@ TENANT_APPS = [
|
||||
"authentik.enterprise.providers.radius",
|
||||
"authentik.enterprise.providers.scim",
|
||||
"authentik.enterprise.providers.ssf",
|
||||
"authentik.enterprise.providers.ws_federation",
|
||||
"authentik.enterprise.reports",
|
||||
"authentik.enterprise.search",
|
||||
"authentik.enterprise.stages.authenticator_endpoint_gdtc",
|
||||
|
||||
@@ -10,7 +10,7 @@ from django.core.cache import cache
|
||||
from django.http import HttpRequest, HttpResponseNotFound
|
||||
from django.templatetags.static import static
|
||||
from lxml import etree # nosec
|
||||
from lxml.etree import Element, SubElement # nosec
|
||||
from lxml.etree import Element, SubElement, _Element # nosec
|
||||
from requests.exceptions import ConnectionError, HTTPError, RequestException, Timeout
|
||||
|
||||
from authentik.lib.utils.dict import get_path_from_dict
|
||||
@@ -109,7 +109,7 @@ def generate_avatar_from_name(
|
||||
shape = "circle" if rounded else "rect"
|
||||
font_weight = "600" if bold else "400"
|
||||
|
||||
root_element: Element = Element(f"{{{SVG_XML_NS}}}svg", nsmap=SVG_NS_MAP)
|
||||
root_element: _Element = Element(f"{{{SVG_XML_NS}}}svg", nsmap=SVG_NS_MAP)
|
||||
root_element.attrib["width"] = f"{size}px"
|
||||
root_element.attrib["height"] = f"{size}px"
|
||||
root_element.attrib["viewBox"] = f"0 0 {size} {size}"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""XML Utilities"""
|
||||
|
||||
from lxml.etree import XMLParser, fromstring # nosec
|
||||
from lxml.etree import XMLParser, _Element, fromstring, tostring # nosec
|
||||
|
||||
|
||||
def get_lxml_parser():
|
||||
@@ -11,3 +11,13 @@ def get_lxml_parser():
|
||||
def lxml_from_string(text: str):
|
||||
"""Wrapper around fromstring"""
|
||||
return fromstring(text, parser=get_lxml_parser()) # nosec
|
||||
|
||||
|
||||
def remove_xml_newlines(parent: _Element, element: _Element):
|
||||
"""Remove newlines in a given XML element, required for xmlsec
|
||||
|
||||
https://github.com/xmlsec/python-xmlsec/issues/196"""
|
||||
old_element = element
|
||||
new_node = fromstring(tostring(element, encoding=str).replace("\n", ""))
|
||||
parent.replace(old_element, new_node)
|
||||
return new_node
|
||||
|
||||
@@ -244,6 +244,8 @@ class SAMLProviderViewSet(UsedByMixin, ModelViewSet):
|
||||
ordering = ["name"]
|
||||
search_fields = ["name"]
|
||||
|
||||
metadata_generator_class = MetadataProcessor
|
||||
|
||||
@extend_schema(
|
||||
responses={
|
||||
200: SAMLMetadataSerializer(many=False),
|
||||
@@ -288,7 +290,7 @@ class SAMLProviderViewSet(UsedByMixin, ModelViewSet):
|
||||
except ValueError:
|
||||
raise Http404 from None
|
||||
try:
|
||||
proc = MetadataProcessor(provider, request)
|
||||
proc = self.metadata_generator_class(provider, request)
|
||||
proc.force_binding = request.query_params.get("force_binding", None)
|
||||
metadata = proc.build_entity_descriptor()
|
||||
if "download" in request.query_params:
|
||||
|
||||
@@ -8,13 +8,14 @@ import xmlsec
|
||||
from django.http import HttpRequest
|
||||
from django.utils.timezone import now
|
||||
from lxml import etree # nosec
|
||||
from lxml.etree import Element, SubElement # nosec
|
||||
from lxml.etree import Element, SubElement, _Element # nosec
|
||||
from structlog.stdlib import get_logger
|
||||
|
||||
from authentik.core.expression.exceptions import PropertyMappingExpressionException
|
||||
from authentik.events.models import Event, EventAction
|
||||
from authentik.events.signals import get_login_event
|
||||
from authentik.lib.utils.time import timedelta_from_string
|
||||
from authentik.lib.xml import remove_xml_newlines
|
||||
from authentik.providers.saml.models import SAMLPropertyMapping, SAMLProvider
|
||||
from authentik.providers.saml.processors.authn_request_parser import AuthNRequest
|
||||
from authentik.providers.saml.utils import get_random_id
|
||||
@@ -359,7 +360,7 @@ class AssertionProcessor:
|
||||
response.append(self.get_assertion())
|
||||
return response
|
||||
|
||||
def _sign(self, element: Element):
|
||||
def _sign(self, element: _Element):
|
||||
"""Sign an XML element based on the providers' configured signing settings"""
|
||||
digest_algorithm_transform = DIGEST_ALGORITHM_TRANSLATION_MAP.get(
|
||||
self.provider.digest_algorithm, xmlsec.constants.TransformSha1
|
||||
@@ -389,11 +390,11 @@ class AssertionProcessor:
|
||||
)
|
||||
ctx.key = key
|
||||
try:
|
||||
ctx.sign(signature_node)
|
||||
ctx.sign(remove_xml_newlines(element, signature_node))
|
||||
except xmlsec.Error as exc:
|
||||
raise InvalidSignature() from exc
|
||||
|
||||
def _encrypt(self, element: Element, parent: Element):
|
||||
def _encrypt(self, element: _Element, parent: _Element):
|
||||
"""Encrypt SAMLResponse EncryptedAssertion Element"""
|
||||
# Create a standalone copy so namespace declarations are included in the encrypted content
|
||||
element_xml = etree.tostring(element)
|
||||
|
||||
@@ -5,9 +5,10 @@ from urllib.parse import quote, urlencode
|
||||
|
||||
import xmlsec
|
||||
from lxml import etree # nosec
|
||||
from lxml.etree import Element
|
||||
from lxml.etree import Element, _Element
|
||||
|
||||
from authentik.core.models import User
|
||||
from authentik.lib.xml import remove_xml_newlines
|
||||
from authentik.providers.saml.models import SAMLProvider
|
||||
from authentik.providers.saml.utils import get_random_id
|
||||
from authentik.providers.saml.utils.encoding import deflate_and_base64_encode
|
||||
@@ -134,7 +135,7 @@ class LogoutRequestProcessor:
|
||||
"RelayState": self.relay_state or "",
|
||||
}
|
||||
|
||||
def _sign_logout_request(self, logout_request: Element):
|
||||
def _sign_logout_request(self, logout_request: _Element):
|
||||
"""Sign the LogoutRequest element"""
|
||||
signature_algorithm_transform = SIGN_ALGORITHM_TRANSFORM_MAP.get(
|
||||
self.provider.signature_algorithm, xmlsec.constants.TransformRsaSha1
|
||||
@@ -154,7 +155,7 @@ class LogoutRequestProcessor:
|
||||
|
||||
self._sign(logout_request)
|
||||
|
||||
def _sign(self, element: Element):
|
||||
def _sign(self, element: _Element):
|
||||
"""Sign an XML element based on the providers' configured signing settings"""
|
||||
digest_algorithm_transform = DIGEST_ALGORITHM_TRANSLATION_MAP.get(
|
||||
self.provider.digest_algorithm, xmlsec.constants.TransformSha1
|
||||
@@ -183,7 +184,7 @@ class LogoutRequestProcessor:
|
||||
xmlsec.constants.KeyDataFormatCertPem,
|
||||
)
|
||||
ctx.key = key
|
||||
ctx.sign(signature_node)
|
||||
ctx.sign(remove_xml_newlines(element, signature_node))
|
||||
|
||||
def _build_signable_query_string(self, params: dict) -> str:
|
||||
"""Build query string for signing (order matters per SAML spec)"""
|
||||
|
||||
@@ -6,8 +6,9 @@ from hashlib import sha256
|
||||
import xmlsec # nosec
|
||||
from django.http import HttpRequest
|
||||
from django.urls import reverse
|
||||
from lxml.etree import Element, SubElement, tostring # nosec
|
||||
from lxml.etree import Element, SubElement, _Element, tostring # nosec
|
||||
|
||||
from authentik.lib.xml import remove_xml_newlines
|
||||
from authentik.providers.saml.models import SAMLProvider
|
||||
from authentik.providers.saml.utils.encoding import strip_pem_header
|
||||
from authentik.sources.saml.processors.constants import (
|
||||
@@ -117,7 +118,7 @@ class MetadataProcessor:
|
||||
element.attrib["Location"] = url
|
||||
yield element
|
||||
|
||||
def _prepare_signature(self, entity_descriptor: Element):
|
||||
def _prepare_signature(self, entity_descriptor: _Element):
|
||||
sign_algorithm_transform = SIGN_ALGORITHM_TRANSFORM_MAP.get(
|
||||
self.provider.signature_algorithm, xmlsec.constants.TransformRsaSha1
|
||||
)
|
||||
@@ -129,7 +130,7 @@ class MetadataProcessor:
|
||||
)
|
||||
entity_descriptor.append(signature)
|
||||
|
||||
def _sign(self, entity_descriptor: Element):
|
||||
def _sign(self, entity_descriptor: _Element):
|
||||
digest_algorithm_transform = DIGEST_ALGORITHM_TRANSLATION_MAP.get(
|
||||
self.provider.digest_algorithm, xmlsec.constants.TransformSha1
|
||||
)
|
||||
@@ -158,17 +159,12 @@ class MetadataProcessor:
|
||||
xmlsec.constants.KeyDataFormatCertPem,
|
||||
)
|
||||
ctx.key = key
|
||||
ctx.sign(signature_node)
|
||||
ctx.sign(remove_xml_newlines(assertion, signature_node))
|
||||
|
||||
def build_entity_descriptor(self) -> str:
|
||||
"""Build full EntityDescriptor"""
|
||||
entity_descriptor = Element(f"{{{NS_SAML_METADATA}}}EntityDescriptor", nsmap=NS_MAP)
|
||||
entity_descriptor.attrib["ID"] = self.xml_id
|
||||
entity_descriptor.attrib["entityID"] = self.provider.issuer
|
||||
|
||||
if self.provider.signing_kp:
|
||||
self._prepare_signature(entity_descriptor)
|
||||
def add_children(self, entity_descriptor: _Element):
|
||||
self.add_idp_sso(entity_descriptor)
|
||||
|
||||
def add_idp_sso(self, entity_descriptor: _Element):
|
||||
idp_sso_descriptor = SubElement(
|
||||
entity_descriptor, f"{{{NS_SAML_METADATA}}}IDPSSODescriptor"
|
||||
)
|
||||
@@ -189,6 +185,17 @@ class MetadataProcessor:
|
||||
for binding in self.get_sso_bindings():
|
||||
idp_sso_descriptor.append(binding)
|
||||
|
||||
def build_entity_descriptor(self) -> str:
|
||||
"""Build full EntityDescriptor"""
|
||||
entity_descriptor = Element(f"{{{NS_SAML_METADATA}}}EntityDescriptor", nsmap=NS_MAP)
|
||||
entity_descriptor.attrib["ID"] = self.xml_id
|
||||
entity_descriptor.attrib["entityID"] = self.provider.issuer
|
||||
|
||||
if self.provider.signing_kp:
|
||||
self._prepare_signature(entity_descriptor)
|
||||
|
||||
self.add_children(entity_descriptor)
|
||||
|
||||
if self.provider.signing_kp:
|
||||
self._sign(entity_descriptor)
|
||||
|
||||
|
||||
@@ -2,12 +2,14 @@
|
||||
|
||||
from django.db.models.signals import post_save, pre_delete
|
||||
from django.dispatch import receiver
|
||||
from django.http import HttpRequest
|
||||
from django.urls import reverse
|
||||
from django.utils import timezone
|
||||
from structlog.stdlib import get_logger
|
||||
|
||||
from authentik.core.models import AuthenticatedSession, User
|
||||
from authentik.flows.models import in_memory_stage
|
||||
from authentik.flows.views.executor import FlowExecutorView
|
||||
from authentik.providers.iframe_logout import IframeLogoutStageView
|
||||
from authentik.providers.saml.models import SAMLBindings, SAMLLogoutMethods, SAMLSession
|
||||
from authentik.providers.saml.native_logout import NativeLogoutStageView
|
||||
@@ -25,7 +27,9 @@ LOGGER = get_logger()
|
||||
|
||||
|
||||
@receiver(flow_pre_user_logout)
|
||||
def handle_saml_iframe_pre_user_logout(sender, request, user, executor, **kwargs):
|
||||
def handle_saml_iframe_pre_user_logout(
|
||||
sender, request: HttpRequest, user: User, executor: FlowExecutorView, **kwargs
|
||||
):
|
||||
"""Handle SAML iframe logout when user logs out via flow"""
|
||||
|
||||
# Only proceed if this is actually a UserLogoutStage
|
||||
@@ -113,7 +117,9 @@ def handle_saml_iframe_pre_user_logout(sender, request, user, executor, **kwargs
|
||||
|
||||
|
||||
@receiver(flow_pre_user_logout)
|
||||
def handle_flow_pre_user_logout(sender, request, user, executor, **kwargs):
|
||||
def handle_flow_pre_user_logout(
|
||||
sender, request: HttpRequest, user: User, executor: FlowExecutorView, **kwargs
|
||||
):
|
||||
"""Handle SAML native logout when user logs out via logout flow"""
|
||||
|
||||
# Only proceed if this is actually a UserLogoutStage
|
||||
|
||||
@@ -191,6 +191,7 @@ SPECTACULAR_SETTINGS = {
|
||||
"DeviceFactsOSFamily": "authentik.endpoints.facts.OSFamily",
|
||||
"StageModeEnum": "authentik.endpoints.models.StageMode",
|
||||
"LicenseSummaryStatusEnum": "authentik.enterprise.models.LicenseUsageStatus",
|
||||
"SAMLLogoutMethods": "authentik.providers.saml.models.SAMLLogoutMethods",
|
||||
},
|
||||
"ENUM_ADD_EXPLICIT_BLANK_NULL_CHOICE": False,
|
||||
"ENUM_GENERATE_CHOICE_DESCRIPTION": False,
|
||||
|
||||
@@ -3,6 +3,7 @@ import warnings
|
||||
|
||||
from cryptography.hazmat.backends.openssl.backend import backend
|
||||
from defusedxml import defuse_stdlib
|
||||
from xmlsec import base64_default_line_size
|
||||
|
||||
from authentik.lib.config import CONFIG
|
||||
|
||||
@@ -19,6 +20,7 @@ def setup():
|
||||
)
|
||||
|
||||
defuse_stdlib()
|
||||
base64_default_line_size(size=8192)
|
||||
|
||||
if CONFIG.get_bool("compliance.fips.enabled", False):
|
||||
backend._enable_fips()
|
||||
|
||||
@@ -8,6 +8,7 @@ from django.http import HttpRequest
|
||||
from lxml import etree # nosec
|
||||
from lxml.etree import Element # nosec
|
||||
|
||||
from authentik.lib.xml import remove_xml_newlines
|
||||
from authentik.providers.saml.utils import get_random_id
|
||||
from authentik.providers.saml.utils.encoding import deflate_and_base64_encode
|
||||
from authentik.providers.saml.utils.time import get_time_string
|
||||
@@ -120,7 +121,7 @@ class RequestProcessor:
|
||||
key_info = xmlsec.template.ensure_key_info(signature_node)
|
||||
xmlsec.template.add_x509_data(key_info)
|
||||
|
||||
ctx.sign(signature_node)
|
||||
ctx.sign(remove_xml_newlines(auth_n_request, signature_node))
|
||||
|
||||
return etree.tostring(auth_n_request).decode()
|
||||
|
||||
|
||||
@@ -976,6 +976,46 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"model",
|
||||
"identifiers"
|
||||
],
|
||||
"properties": {
|
||||
"model": {
|
||||
"const": "authentik_providers_ws_federation.wsfederationprovider"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"state": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"absent",
|
||||
"created",
|
||||
"must_created",
|
||||
"present"
|
||||
],
|
||||
"default": "present"
|
||||
},
|
||||
"conditions": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"permissions": {
|
||||
"$ref": "#/$defs/model_authentik_providers_ws_federation.wsfederationprovider_permissions"
|
||||
},
|
||||
"attrs": {
|
||||
"$ref": "#/$defs/model_authentik_providers_ws_federation.wsfederationprovider"
|
||||
},
|
||||
"identifiers": {
|
||||
"$ref": "#/$defs/model_authentik_providers_ws_federation.wsfederationprovider"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
@@ -5727,6 +5767,10 @@
|
||||
"authentik_providers_ssf.view_ssfprovider",
|
||||
"authentik_providers_ssf.view_stream",
|
||||
"authentik_providers_ssf.view_streamevent",
|
||||
"authentik_providers_ws_federation.add_wsfederationprovider",
|
||||
"authentik_providers_ws_federation.change_wsfederationprovider",
|
||||
"authentik_providers_ws_federation.delete_wsfederationprovider",
|
||||
"authentik_providers_ws_federation.view_wsfederationprovider",
|
||||
"authentik_rbac.access_admin_interface",
|
||||
"authentik_rbac.add_initialpermissions",
|
||||
"authentik_rbac.add_role",
|
||||
@@ -7085,6 +7129,162 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"model_authentik_providers_ws_federation.wsfederationprovider": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"title": "Name"
|
||||
},
|
||||
"authentication_flow": {
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Authentication flow",
|
||||
"description": "Flow used for authentication when the associated application is accessed by an un-authenticated user."
|
||||
},
|
||||
"authorization_flow": {
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Authorization flow",
|
||||
"description": "Flow used when authorizing this provider."
|
||||
},
|
||||
"invalidation_flow": {
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Invalidation flow",
|
||||
"description": "Flow used ending the session from a provider."
|
||||
},
|
||||
"property_mappings": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
},
|
||||
"title": "Property mappings"
|
||||
},
|
||||
"reply_url": {
|
||||
"type": "string",
|
||||
"format": "uri",
|
||||
"minLength": 1,
|
||||
"title": "Reply url"
|
||||
},
|
||||
"assertion_valid_not_before": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"title": "Assertion valid not before",
|
||||
"description": "Assertion valid not before current time + this value (Format: hours=-1;minutes=-2;seconds=-3)."
|
||||
},
|
||||
"assertion_valid_not_on_or_after": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"title": "Assertion valid not on or after",
|
||||
"description": "Assertion not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3)."
|
||||
},
|
||||
"session_valid_not_on_or_after": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"title": "Session valid not on or after",
|
||||
"description": "Session not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3)."
|
||||
},
|
||||
"name_id_mapping": {
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "NameID Property Mapping",
|
||||
"description": "Configure how the NameID value will be created. When left empty, the NameIDPolicy of the incoming request will be considered"
|
||||
},
|
||||
"authn_context_class_ref_mapping": {
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "AuthnContextClassRef Property Mapping",
|
||||
"description": "Configure how the AuthnContextClassRef value will be created. When left empty, the AuthnContextClassRef will be set based on which authentication methods the user used to authenticate."
|
||||
},
|
||||
"digest_algorithm": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"http://www.w3.org/2000/09/xmldsig#sha1",
|
||||
"http://www.w3.org/2001/04/xmlenc#sha256",
|
||||
"http://www.w3.org/2001/04/xmldsig-more#sha384",
|
||||
"http://www.w3.org/2001/04/xmlenc#sha512"
|
||||
],
|
||||
"title": "Digest algorithm"
|
||||
},
|
||||
"signature_algorithm": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"http://www.w3.org/2000/09/xmldsig#rsa-sha1",
|
||||
"http://www.w3.org/2001/04/xmldsig-more#rsa-sha256",
|
||||
"http://www.w3.org/2001/04/xmldsig-more#rsa-sha384",
|
||||
"http://www.w3.org/2001/04/xmldsig-more#rsa-sha512",
|
||||
"http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1",
|
||||
"http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256",
|
||||
"http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha384",
|
||||
"http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha512",
|
||||
"http://www.w3.org/2000/09/xmldsig#dsa-sha1"
|
||||
],
|
||||
"title": "Signature algorithm"
|
||||
},
|
||||
"signing_kp": {
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Signing Keypair",
|
||||
"description": "Keypair used to sign outgoing Responses going to the Service Provider."
|
||||
},
|
||||
"encryption_kp": {
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Encryption Keypair",
|
||||
"description": "When selected, incoming assertions are encrypted by the IdP using the public key of the encryption keypair. The assertion is decrypted by the SP using the the private key."
|
||||
},
|
||||
"sign_assertion": {
|
||||
"type": "boolean",
|
||||
"title": "Sign assertion"
|
||||
},
|
||||
"sign_logout_request": {
|
||||
"type": "boolean",
|
||||
"title": "Sign logout request"
|
||||
},
|
||||
"default_name_id_policy": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress",
|
||||
"urn:oasis:names:tc:SAML:2.0:nameid-format:persistent",
|
||||
"urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName",
|
||||
"urn:oasis:names:tc:SAML:2.0:nameid-format:WindowsDomainQualifiedName",
|
||||
"urn:oasis:names:tc:SAML:2.0:nameid-format:transient",
|
||||
"urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
|
||||
],
|
||||
"title": "Default name id policy"
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"model_authentik_providers_ws_federation.wsfederationprovider_permissions": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"permission"
|
||||
],
|
||||
"properties": {
|
||||
"permission": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"add_wsfederationprovider",
|
||||
"change_wsfederationprovider",
|
||||
"delete_wsfederationprovider",
|
||||
"view_wsfederationprovider"
|
||||
]
|
||||
},
|
||||
"user": {
|
||||
"type": "integer"
|
||||
},
|
||||
"role": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"model_authentik_reports.dataexport": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -8289,6 +8489,7 @@
|
||||
"authentik.enterprise.providers.radius",
|
||||
"authentik.enterprise.providers.scim",
|
||||
"authentik.enterprise.providers.ssf",
|
||||
"authentik.enterprise.providers.ws_federation",
|
||||
"authentik.enterprise.reports",
|
||||
"authentik.enterprise.search",
|
||||
"authentik.enterprise.stages.authenticator_endpoint_gdtc",
|
||||
@@ -8417,6 +8618,7 @@
|
||||
"authentik_providers_microsoft_entra.microsoftentraprovider",
|
||||
"authentik_providers_microsoft_entra.microsoftentraprovidermapping",
|
||||
"authentik_providers_ssf.ssfprovider",
|
||||
"authentik_providers_ws_federation.wsfederationprovider",
|
||||
"authentik_reports.dataexport",
|
||||
"authentik_stages_authenticator_endpoint_gdtc.authenticatorendpointgdtcstage",
|
||||
"authentik_stages_mtls.mutualtlsstage",
|
||||
@@ -10929,6 +11131,10 @@
|
||||
"authentik_providers_ssf.view_ssfprovider",
|
||||
"authentik_providers_ssf.view_stream",
|
||||
"authentik_providers_ssf.view_streamevent",
|
||||
"authentik_providers_ws_federation.add_wsfederationprovider",
|
||||
"authentik_providers_ws_federation.change_wsfederationprovider",
|
||||
"authentik_providers_ws_federation.delete_wsfederationprovider",
|
||||
"authentik_providers_ws_federation.view_wsfederationprovider",
|
||||
"authentik_rbac.access_admin_interface",
|
||||
"authentik_rbac.add_initialpermissions",
|
||||
"authentik_rbac.add_role",
|
||||
|
||||
@@ -179,7 +179,8 @@ skip = [
|
||||
"./gen-go-api", # Generated Go API
|
||||
"./data", # Media files
|
||||
"./media", # Legacy media files
|
||||
"**vendored**" # Vendored files
|
||||
"./schemas/**", # XML Schemas
|
||||
"**vendored**", # Vendored files
|
||||
]
|
||||
dictionary = ".github/codespell-dictionary.txt,-"
|
||||
ignore-words = ".github/codespell-words.txt"
|
||||
|
||||
785
schema.yml
785
schema.yml
@@ -19432,6 +19432,433 @@ paths:
|
||||
$ref: '#/components/responses/ValidationErrorResponse'
|
||||
'403':
|
||||
$ref: '#/components/responses/GenericErrorResponse'
|
||||
/providers/wsfed/:
|
||||
get:
|
||||
operationId: providers_wsfed_list
|
||||
description: WSFederationProvider Viewset
|
||||
parameters:
|
||||
- in: query
|
||||
name: acs_url
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: assertion_valid_not_before
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: assertion_valid_not_on_or_after
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: audience
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: authentication_flow
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
- in: query
|
||||
name: authn_context_class_ref_mapping
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
- in: query
|
||||
name: authorization_flow
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
- in: query
|
||||
name: backchannel_application
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
- in: query
|
||||
name: default_name_id_policy
|
||||
schema:
|
||||
type: string
|
||||
enum:
|
||||
- urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName
|
||||
- urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress
|
||||
- urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified
|
||||
- urn:oasis:names:tc:SAML:2.0:nameid-format:WindowsDomainQualifiedName
|
||||
- urn:oasis:names:tc:SAML:2.0:nameid-format:persistent
|
||||
- urn:oasis:names:tc:SAML:2.0:nameid-format:transient
|
||||
- in: query
|
||||
name: default_relay_state
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: digest_algorithm
|
||||
schema:
|
||||
type: string
|
||||
enum:
|
||||
- http://www.w3.org/2000/09/xmldsig#sha1
|
||||
- http://www.w3.org/2001/04/xmldsig-more#sha384
|
||||
- http://www.w3.org/2001/04/xmlenc#sha256
|
||||
- http://www.w3.org/2001/04/xmlenc#sha512
|
||||
- in: query
|
||||
name: encryption_kp
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
- in: query
|
||||
name: invalidation_flow
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
- in: query
|
||||
name: is_backchannel
|
||||
schema:
|
||||
type: boolean
|
||||
- in: query
|
||||
name: issuer
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: logout_method
|
||||
schema:
|
||||
type: string
|
||||
enum:
|
||||
- backchannel
|
||||
- frontchannel_iframe
|
||||
- frontchannel_native
|
||||
description: |+
|
||||
Method to use for logout. Front-channel iframe loads all logout URLs simultaneously in hidden iframes. Front-channel native uses your active browser tab to send post requests and redirect to providers. Back-channel sends logout requests directly from the server without user interaction (requires POST SLS binding).
|
||||
|
||||
- $ref: '#/components/parameters/QueryName'
|
||||
- in: query
|
||||
name: name_id_mapping
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
- $ref: '#/components/parameters/QueryPaginationOrdering'
|
||||
- $ref: '#/components/parameters/QueryPaginationPage'
|
||||
- $ref: '#/components/parameters/QueryPaginationPageSize'
|
||||
- in: query
|
||||
name: property_mappings
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
format: uuid
|
||||
explode: true
|
||||
style: form
|
||||
- $ref: '#/components/parameters/QuerySearch'
|
||||
- in: query
|
||||
name: session_valid_not_on_or_after
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: sign_assertion
|
||||
schema:
|
||||
type: boolean
|
||||
- in: query
|
||||
name: sign_logout_request
|
||||
schema:
|
||||
type: boolean
|
||||
- in: query
|
||||
name: sign_response
|
||||
schema:
|
||||
type: boolean
|
||||
- in: query
|
||||
name: signature_algorithm
|
||||
schema:
|
||||
type: string
|
||||
enum:
|
||||
- http://www.w3.org/2000/09/xmldsig#dsa-sha1
|
||||
- http://www.w3.org/2000/09/xmldsig#rsa-sha1
|
||||
- http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1
|
||||
- http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256
|
||||
- http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha384
|
||||
- http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha512
|
||||
- http://www.w3.org/2001/04/xmldsig-more#rsa-sha256
|
||||
- http://www.w3.org/2001/04/xmldsig-more#rsa-sha384
|
||||
- http://www.w3.org/2001/04/xmldsig-more#rsa-sha512
|
||||
- in: query
|
||||
name: signing_kp
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
- in: query
|
||||
name: sls_binding
|
||||
schema:
|
||||
type: string
|
||||
enum:
|
||||
- post
|
||||
- redirect
|
||||
description: |+
|
||||
This determines how authentik sends the logout response back to the Service Provider.
|
||||
|
||||
- in: query
|
||||
name: sls_url
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: sp_binding
|
||||
schema:
|
||||
type: string
|
||||
title: Service Provider Binding
|
||||
enum:
|
||||
- post
|
||||
- redirect
|
||||
description: |+
|
||||
This determines how authentik sends the response back to the Service Provider.
|
||||
|
||||
- in: query
|
||||
name: verification_kp
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
tags:
|
||||
- providers
|
||||
security:
|
||||
- authentik: []
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/PaginatedWSFederationProviderList'
|
||||
description: ''
|
||||
'400':
|
||||
$ref: '#/components/responses/ValidationErrorResponse'
|
||||
'403':
|
||||
$ref: '#/components/responses/GenericErrorResponse'
|
||||
post:
|
||||
operationId: providers_wsfed_create
|
||||
description: WSFederationProvider Viewset
|
||||
tags:
|
||||
- providers
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/WSFederationProviderRequest'
|
||||
required: true
|
||||
security:
|
||||
- authentik: []
|
||||
responses:
|
||||
'201':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/WSFederationProvider'
|
||||
description: ''
|
||||
'400':
|
||||
$ref: '#/components/responses/ValidationErrorResponse'
|
||||
'403':
|
||||
$ref: '#/components/responses/GenericErrorResponse'
|
||||
/providers/wsfed/{id}/:
|
||||
get:
|
||||
operationId: providers_wsfed_retrieve
|
||||
description: WSFederationProvider Viewset
|
||||
parameters:
|
||||
- in: path
|
||||
name: id
|
||||
schema:
|
||||
type: integer
|
||||
description: A unique integer value identifying this WS-Federation Provider.
|
||||
required: true
|
||||
tags:
|
||||
- providers
|
||||
security:
|
||||
- authentik: []
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/WSFederationProvider'
|
||||
description: ''
|
||||
'400':
|
||||
$ref: '#/components/responses/ValidationErrorResponse'
|
||||
'403':
|
||||
$ref: '#/components/responses/GenericErrorResponse'
|
||||
put:
|
||||
operationId: providers_wsfed_update
|
||||
description: WSFederationProvider Viewset
|
||||
parameters:
|
||||
- in: path
|
||||
name: id
|
||||
schema:
|
||||
type: integer
|
||||
description: A unique integer value identifying this WS-Federation Provider.
|
||||
required: true
|
||||
tags:
|
||||
- providers
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/WSFederationProviderRequest'
|
||||
required: true
|
||||
security:
|
||||
- authentik: []
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/WSFederationProvider'
|
||||
description: ''
|
||||
'400':
|
||||
$ref: '#/components/responses/ValidationErrorResponse'
|
||||
'403':
|
||||
$ref: '#/components/responses/GenericErrorResponse'
|
||||
patch:
|
||||
operationId: providers_wsfed_partial_update
|
||||
description: WSFederationProvider Viewset
|
||||
parameters:
|
||||
- in: path
|
||||
name: id
|
||||
schema:
|
||||
type: integer
|
||||
description: A unique integer value identifying this WS-Federation Provider.
|
||||
required: true
|
||||
tags:
|
||||
- providers
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/PatchedWSFederationProviderRequest'
|
||||
security:
|
||||
- authentik: []
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/WSFederationProvider'
|
||||
description: ''
|
||||
'400':
|
||||
$ref: '#/components/responses/ValidationErrorResponse'
|
||||
'403':
|
||||
$ref: '#/components/responses/GenericErrorResponse'
|
||||
delete:
|
||||
operationId: providers_wsfed_destroy
|
||||
description: WSFederationProvider Viewset
|
||||
parameters:
|
||||
- in: path
|
||||
name: id
|
||||
schema:
|
||||
type: integer
|
||||
description: A unique integer value identifying this WS-Federation Provider.
|
||||
required: true
|
||||
tags:
|
||||
- providers
|
||||
security:
|
||||
- authentik: []
|
||||
responses:
|
||||
'204':
|
||||
description: No response body
|
||||
'400':
|
||||
$ref: '#/components/responses/ValidationErrorResponse'
|
||||
'403':
|
||||
$ref: '#/components/responses/GenericErrorResponse'
|
||||
/providers/wsfed/{id}/metadata/:
|
||||
get:
|
||||
operationId: providers_wsfed_metadata_retrieve
|
||||
description: Return metadata as XML string
|
||||
parameters:
|
||||
- in: query
|
||||
name: download
|
||||
schema:
|
||||
type: boolean
|
||||
- in: query
|
||||
name: force_binding
|
||||
schema:
|
||||
type: string
|
||||
enum:
|
||||
- urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST
|
||||
- urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect
|
||||
description: Optionally force the metadata to only include one binding.
|
||||
- in: path
|
||||
name: id
|
||||
schema:
|
||||
type: integer
|
||||
description: A unique integer value identifying this WS-Federation Provider.
|
||||
required: true
|
||||
tags:
|
||||
- providers
|
||||
security:
|
||||
- authentik: []
|
||||
- {}
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SAMLMetadata'
|
||||
application/xml:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SAMLMetadata'
|
||||
description: ''
|
||||
'404':
|
||||
description: Provider has no application assigned
|
||||
'400':
|
||||
$ref: '#/components/responses/ValidationErrorResponse'
|
||||
'403':
|
||||
$ref: '#/components/responses/GenericErrorResponse'
|
||||
/providers/wsfed/{id}/preview_user/:
|
||||
get:
|
||||
operationId: providers_wsfed_preview_user_retrieve
|
||||
description: Preview user data for provider
|
||||
parameters:
|
||||
- in: query
|
||||
name: for_user
|
||||
schema:
|
||||
type: integer
|
||||
- in: path
|
||||
name: id
|
||||
schema:
|
||||
type: integer
|
||||
description: A unique integer value identifying this WS-Federation Provider.
|
||||
required: true
|
||||
tags:
|
||||
- providers
|
||||
security:
|
||||
- authentik: []
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/PropertyMappingPreview'
|
||||
description: ''
|
||||
'400':
|
||||
description: Bad request
|
||||
'403':
|
||||
$ref: '#/components/responses/GenericErrorResponse'
|
||||
/providers/wsfed/{id}/used_by/:
|
||||
get:
|
||||
operationId: providers_wsfed_used_by_list
|
||||
description: Get a list of all objects that use this object
|
||||
parameters:
|
||||
- in: path
|
||||
name: id
|
||||
schema:
|
||||
type: integer
|
||||
description: A unique integer value identifying this WS-Federation Provider.
|
||||
required: true
|
||||
tags:
|
||||
- providers
|
||||
security:
|
||||
- authentik: []
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/UsedBy'
|
||||
description: ''
|
||||
'400':
|
||||
$ref: '#/components/responses/ValidationErrorResponse'
|
||||
'403':
|
||||
$ref: '#/components/responses/GenericErrorResponse'
|
||||
/rac/connection_tokens/:
|
||||
get:
|
||||
operationId: rac_connection_tokens_list
|
||||
@@ -20126,6 +20553,7 @@ paths:
|
||||
- authentik_providers_scim.scimmapping
|
||||
- authentik_providers_scim.scimprovider
|
||||
- authentik_providers_ssf.ssfprovider
|
||||
- authentik_providers_ws_federation.wsfederationprovider
|
||||
- authentik_rbac.initialpermissions
|
||||
- authentik_rbac.role
|
||||
- authentik_reports.dataexport
|
||||
@@ -33319,6 +33747,7 @@ components:
|
||||
- authentik.enterprise.providers.radius
|
||||
- authentik.enterprise.providers.scim
|
||||
- authentik.enterprise.providers.ssf
|
||||
- authentik.enterprise.providers.ws_federation
|
||||
- authentik.enterprise.reports
|
||||
- authentik.enterprise.search
|
||||
- authentik.enterprise.stages.authenticator_endpoint_gdtc
|
||||
@@ -41892,6 +42321,7 @@ components:
|
||||
- authentik_providers_microsoft_entra.microsoftentraprovider
|
||||
- authentik_providers_microsoft_entra.microsoftentraprovidermapping
|
||||
- authentik_providers_ssf.ssfprovider
|
||||
- authentik_providers_ws_federation.wsfederationprovider
|
||||
- authentik_reports.dataexport
|
||||
- authentik_stages_authenticator_endpoint_gdtc.authenticatorendpointgdtcstage
|
||||
- authentik_stages_mtls.mutualtlsstage
|
||||
@@ -45539,6 +45969,21 @@ components:
|
||||
- pagination
|
||||
- results
|
||||
- autocomplete
|
||||
PaginatedWSFederationProviderList:
|
||||
type: object
|
||||
properties:
|
||||
pagination:
|
||||
$ref: '#/components/schemas/Pagination'
|
||||
results:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/WSFederationProvider'
|
||||
autocomplete:
|
||||
$ref: '#/components/schemas/Autocomplete'
|
||||
required:
|
||||
- pagination
|
||||
- results
|
||||
- autocomplete
|
||||
PaginatedWebAuthnDeviceList:
|
||||
type: object
|
||||
properties:
|
||||
@@ -48868,7 +49313,7 @@ components:
|
||||
to the Service Provider.
|
||||
logout_method:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/SAMLProviderLogoutMethodEnum'
|
||||
- $ref: '#/components/schemas/SAMLLogoutMethods'
|
||||
description: Method to use for logout. Front-channel iframe loads all logout
|
||||
URLs simultaneously in hidden iframes. Front-channel native uses your
|
||||
active browser tab to send post requests and redirect to providers. Back-channel
|
||||
@@ -49725,6 +50170,91 @@ components:
|
||||
$ref: '#/components/schemas/UserTypeEnum'
|
||||
user_path_template:
|
||||
type: string
|
||||
PatchedWSFederationProviderRequest:
|
||||
type: object
|
||||
description: WSFederationProvider Serializer
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
minLength: 1
|
||||
authentication_flow:
|
||||
type: string
|
||||
format: uuid
|
||||
nullable: true
|
||||
description: Flow used for authentication when the associated application
|
||||
is accessed by an un-authenticated user.
|
||||
authorization_flow:
|
||||
type: string
|
||||
format: uuid
|
||||
description: Flow used when authorizing this provider.
|
||||
invalidation_flow:
|
||||
type: string
|
||||
format: uuid
|
||||
description: Flow used ending the session from a provider.
|
||||
property_mappings:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
format: uuid
|
||||
reply_url:
|
||||
type: string
|
||||
format: uri
|
||||
minLength: 1
|
||||
assertion_valid_not_before:
|
||||
type: string
|
||||
minLength: 1
|
||||
description: 'Assertion valid not before current time + this value (Format:
|
||||
hours=-1;minutes=-2;seconds=-3).'
|
||||
assertion_valid_not_on_or_after:
|
||||
type: string
|
||||
minLength: 1
|
||||
description: 'Assertion not valid on or after current time + this value
|
||||
(Format: hours=1;minutes=2;seconds=3).'
|
||||
session_valid_not_on_or_after:
|
||||
type: string
|
||||
minLength: 1
|
||||
description: 'Session not valid on or after current time + this value (Format:
|
||||
hours=1;minutes=2;seconds=3).'
|
||||
name_id_mapping:
|
||||
type: string
|
||||
format: uuid
|
||||
nullable: true
|
||||
title: NameID Property Mapping
|
||||
description: Configure how the NameID value will be created. When left empty,
|
||||
the NameIDPolicy of the incoming request will be considered
|
||||
authn_context_class_ref_mapping:
|
||||
type: string
|
||||
format: uuid
|
||||
nullable: true
|
||||
title: AuthnContextClassRef Property Mapping
|
||||
description: Configure how the AuthnContextClassRef value will be created.
|
||||
When left empty, the AuthnContextClassRef will be set based on which authentication
|
||||
methods the user used to authenticate.
|
||||
digest_algorithm:
|
||||
$ref: '#/components/schemas/DigestAlgorithmEnum'
|
||||
signature_algorithm:
|
||||
$ref: '#/components/schemas/SignatureAlgorithmEnum'
|
||||
signing_kp:
|
||||
type: string
|
||||
format: uuid
|
||||
nullable: true
|
||||
title: Signing Keypair
|
||||
description: Keypair used to sign outgoing Responses going to the Service
|
||||
Provider.
|
||||
encryption_kp:
|
||||
type: string
|
||||
format: uuid
|
||||
nullable: true
|
||||
title: Encryption Keypair
|
||||
description: When selected, incoming assertions are encrypted by the IdP
|
||||
using the public key of the encryption keypair. The assertion is decrypted
|
||||
by the SP using the the private key.
|
||||
sign_assertion:
|
||||
type: boolean
|
||||
sign_logout_request:
|
||||
type: boolean
|
||||
default_name_id_policy:
|
||||
$ref: '#/components/schemas/SAMLNameIDPolicyEnum'
|
||||
PatchedWebAuthnDeviceRequest:
|
||||
type: object
|
||||
description: Serializer for WebAuthn authenticator devices
|
||||
@@ -50711,6 +51241,7 @@ components:
|
||||
- authentik_providers_saml.samlprovider
|
||||
- authentik_providers_scim.scimprovider
|
||||
- authentik_providers_ssf.ssfprovider
|
||||
- authentik_providers_ws_federation.wsfederationprovider
|
||||
type: string
|
||||
ProviderTypeEnum:
|
||||
enum:
|
||||
@@ -51929,6 +52460,12 @@ components:
|
||||
- redirect
|
||||
- post
|
||||
type: string
|
||||
SAMLLogoutMethods:
|
||||
enum:
|
||||
- frontchannel_iframe
|
||||
- frontchannel_native
|
||||
- backchannel
|
||||
type: string
|
||||
SAMLMetadata:
|
||||
type: object
|
||||
description: SAML Provider Metadata serializer
|
||||
@@ -52183,7 +52720,7 @@ components:
|
||||
to the Service Provider.
|
||||
logout_method:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/SAMLProviderLogoutMethodEnum'
|
||||
- $ref: '#/components/schemas/SAMLLogoutMethods'
|
||||
description: Method to use for logout. Front-channel iframe loads all logout
|
||||
URLs simultaneously in hidden iframes. Front-channel native uses your
|
||||
active browser tab to send post requests and redirect to providers. Back-channel
|
||||
@@ -52259,12 +52796,6 @@ components:
|
||||
- file
|
||||
- invalidation_flow
|
||||
- name
|
||||
SAMLProviderLogoutMethodEnum:
|
||||
enum:
|
||||
- frontchannel_iframe
|
||||
- frontchannel_native
|
||||
- backchannel
|
||||
type: string
|
||||
SAMLProviderRequest:
|
||||
type: object
|
||||
description: SAMLProvider Serializer
|
||||
@@ -52383,7 +52914,7 @@ components:
|
||||
to the Service Provider.
|
||||
logout_method:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/SAMLProviderLogoutMethodEnum'
|
||||
- $ref: '#/components/schemas/SAMLLogoutMethods'
|
||||
description: Method to use for logout. Front-channel iframe loads all logout
|
||||
URLs simultaneously in hidden iframes. Front-channel native uses your
|
||||
active browser tab to send post requests and redirect to providers. Back-channel
|
||||
@@ -56489,6 +57020,240 @@ components:
|
||||
- id
|
||||
- timestamp
|
||||
- version
|
||||
WSFederationProvider:
|
||||
type: object
|
||||
description: WSFederationProvider Serializer
|
||||
properties:
|
||||
pk:
|
||||
type: integer
|
||||
readOnly: true
|
||||
title: ID
|
||||
name:
|
||||
type: string
|
||||
authentication_flow:
|
||||
type: string
|
||||
format: uuid
|
||||
nullable: true
|
||||
description: Flow used for authentication when the associated application
|
||||
is accessed by an un-authenticated user.
|
||||
authorization_flow:
|
||||
type: string
|
||||
format: uuid
|
||||
description: Flow used when authorizing this provider.
|
||||
invalidation_flow:
|
||||
type: string
|
||||
format: uuid
|
||||
description: Flow used ending the session from a provider.
|
||||
property_mappings:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
format: uuid
|
||||
component:
|
||||
type: string
|
||||
description: Get object component so that we know how to edit the object
|
||||
readOnly: true
|
||||
assigned_application_slug:
|
||||
type: string
|
||||
description: Internal application name, used in URLs.
|
||||
readOnly: true
|
||||
assigned_application_name:
|
||||
type: string
|
||||
description: Application's display Name.
|
||||
readOnly: true
|
||||
assigned_backchannel_application_slug:
|
||||
type: string
|
||||
description: Internal application name, used in URLs.
|
||||
readOnly: true
|
||||
assigned_backchannel_application_name:
|
||||
type: string
|
||||
description: Application's display Name.
|
||||
readOnly: true
|
||||
verbose_name:
|
||||
type: string
|
||||
description: Return object's verbose_name
|
||||
readOnly: true
|
||||
verbose_name_plural:
|
||||
type: string
|
||||
description: Return object's plural verbose_name
|
||||
readOnly: true
|
||||
meta_model_name:
|
||||
type: string
|
||||
description: Return internal model name
|
||||
readOnly: true
|
||||
reply_url:
|
||||
type: string
|
||||
format: uri
|
||||
assertion_valid_not_before:
|
||||
type: string
|
||||
description: 'Assertion valid not before current time + this value (Format:
|
||||
hours=-1;minutes=-2;seconds=-3).'
|
||||
assertion_valid_not_on_or_after:
|
||||
type: string
|
||||
description: 'Assertion not valid on or after current time + this value
|
||||
(Format: hours=1;minutes=2;seconds=3).'
|
||||
session_valid_not_on_or_after:
|
||||
type: string
|
||||
description: 'Session not valid on or after current time + this value (Format:
|
||||
hours=1;minutes=2;seconds=3).'
|
||||
name_id_mapping:
|
||||
type: string
|
||||
format: uuid
|
||||
nullable: true
|
||||
title: NameID Property Mapping
|
||||
description: Configure how the NameID value will be created. When left empty,
|
||||
the NameIDPolicy of the incoming request will be considered
|
||||
authn_context_class_ref_mapping:
|
||||
type: string
|
||||
format: uuid
|
||||
nullable: true
|
||||
title: AuthnContextClassRef Property Mapping
|
||||
description: Configure how the AuthnContextClassRef value will be created.
|
||||
When left empty, the AuthnContextClassRef will be set based on which authentication
|
||||
methods the user used to authenticate.
|
||||
digest_algorithm:
|
||||
$ref: '#/components/schemas/DigestAlgorithmEnum'
|
||||
signature_algorithm:
|
||||
$ref: '#/components/schemas/SignatureAlgorithmEnum'
|
||||
signing_kp:
|
||||
type: string
|
||||
format: uuid
|
||||
nullable: true
|
||||
title: Signing Keypair
|
||||
description: Keypair used to sign outgoing Responses going to the Service
|
||||
Provider.
|
||||
encryption_kp:
|
||||
type: string
|
||||
format: uuid
|
||||
nullable: true
|
||||
title: Encryption Keypair
|
||||
description: When selected, incoming assertions are encrypted by the IdP
|
||||
using the public key of the encryption keypair. The assertion is decrypted
|
||||
by the SP using the the private key.
|
||||
sign_assertion:
|
||||
type: boolean
|
||||
sign_logout_request:
|
||||
type: boolean
|
||||
default_name_id_policy:
|
||||
$ref: '#/components/schemas/SAMLNameIDPolicyEnum'
|
||||
url_download_metadata:
|
||||
type: string
|
||||
description: Get metadata download URL
|
||||
readOnly: true
|
||||
url_wsfed:
|
||||
type: string
|
||||
description: Get WS-Fed url
|
||||
readOnly: true
|
||||
wtrealm:
|
||||
type: string
|
||||
readOnly: true
|
||||
required:
|
||||
- assigned_application_name
|
||||
- assigned_application_slug
|
||||
- assigned_backchannel_application_name
|
||||
- assigned_backchannel_application_slug
|
||||
- authorization_flow
|
||||
- component
|
||||
- invalidation_flow
|
||||
- meta_model_name
|
||||
- name
|
||||
- pk
|
||||
- reply_url
|
||||
- url_download_metadata
|
||||
- url_wsfed
|
||||
- verbose_name
|
||||
- verbose_name_plural
|
||||
- wtrealm
|
||||
WSFederationProviderRequest:
|
||||
type: object
|
||||
description: WSFederationProvider Serializer
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
minLength: 1
|
||||
authentication_flow:
|
||||
type: string
|
||||
format: uuid
|
||||
nullable: true
|
||||
description: Flow used for authentication when the associated application
|
||||
is accessed by an un-authenticated user.
|
||||
authorization_flow:
|
||||
type: string
|
||||
format: uuid
|
||||
description: Flow used when authorizing this provider.
|
||||
invalidation_flow:
|
||||
type: string
|
||||
format: uuid
|
||||
description: Flow used ending the session from a provider.
|
||||
property_mappings:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
format: uuid
|
||||
reply_url:
|
||||
type: string
|
||||
format: uri
|
||||
minLength: 1
|
||||
assertion_valid_not_before:
|
||||
type: string
|
||||
minLength: 1
|
||||
description: 'Assertion valid not before current time + this value (Format:
|
||||
hours=-1;minutes=-2;seconds=-3).'
|
||||
assertion_valid_not_on_or_after:
|
||||
type: string
|
||||
minLength: 1
|
||||
description: 'Assertion not valid on or after current time + this value
|
||||
(Format: hours=1;minutes=2;seconds=3).'
|
||||
session_valid_not_on_or_after:
|
||||
type: string
|
||||
minLength: 1
|
||||
description: 'Session not valid on or after current time + this value (Format:
|
||||
hours=1;minutes=2;seconds=3).'
|
||||
name_id_mapping:
|
||||
type: string
|
||||
format: uuid
|
||||
nullable: true
|
||||
title: NameID Property Mapping
|
||||
description: Configure how the NameID value will be created. When left empty,
|
||||
the NameIDPolicy of the incoming request will be considered
|
||||
authn_context_class_ref_mapping:
|
||||
type: string
|
||||
format: uuid
|
||||
nullable: true
|
||||
title: AuthnContextClassRef Property Mapping
|
||||
description: Configure how the AuthnContextClassRef value will be created.
|
||||
When left empty, the AuthnContextClassRef will be set based on which authentication
|
||||
methods the user used to authenticate.
|
||||
digest_algorithm:
|
||||
$ref: '#/components/schemas/DigestAlgorithmEnum'
|
||||
signature_algorithm:
|
||||
$ref: '#/components/schemas/SignatureAlgorithmEnum'
|
||||
signing_kp:
|
||||
type: string
|
||||
format: uuid
|
||||
nullable: true
|
||||
title: Signing Keypair
|
||||
description: Keypair used to sign outgoing Responses going to the Service
|
||||
Provider.
|
||||
encryption_kp:
|
||||
type: string
|
||||
format: uuid
|
||||
nullable: true
|
||||
title: Encryption Keypair
|
||||
description: When selected, incoming assertions are encrypted by the IdP
|
||||
using the public key of the encryption keypair. The assertion is decrypted
|
||||
by the SP using the the private key.
|
||||
sign_assertion:
|
||||
type: boolean
|
||||
sign_logout_request:
|
||||
type: boolean
|
||||
default_name_id_policy:
|
||||
$ref: '#/components/schemas/SAMLNameIDPolicyEnum'
|
||||
required:
|
||||
- authorization_flow
|
||||
- invalidation_flow
|
||||
- name
|
||||
- reply_url
|
||||
WebAuthnDevice:
|
||||
type: object
|
||||
description: Serializer for WebAuthn authenticator devices
|
||||
@@ -56570,6 +57335,7 @@ components:
|
||||
- $ref: '#/components/schemas/SAMLProviderRequest'
|
||||
- $ref: '#/components/schemas/SCIMProviderRequest'
|
||||
- $ref: '#/components/schemas/SSFProviderRequest'
|
||||
- $ref: '#/components/schemas/WSFederationProviderRequest'
|
||||
discriminator:
|
||||
propertyName: provider_model
|
||||
mapping:
|
||||
@@ -56583,6 +57349,7 @@ components:
|
||||
authentik_providers_saml.samlprovider: '#/components/schemas/SAMLProviderRequest'
|
||||
authentik_providers_scim.scimprovider: '#/components/schemas/SCIMProviderRequest'
|
||||
authentik_providers_ssf.ssfprovider: '#/components/schemas/SSFProviderRequest'
|
||||
authentik_providers_ws_federation.wsfederationprovider: '#/components/schemas/WSFederationProviderRequest'
|
||||
securitySchemes:
|
||||
authentik:
|
||||
type: http
|
||||
|
||||
145
schemas/authorization.xsd
Normal file
145
schemas/authorization.xsd
Normal file
@@ -0,0 +1,145 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
OASIS takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain to the
|
||||
implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available;
|
||||
neither does it represent that it has made any effort to identify any such rights. Information on OASIS's procedures with respect to rights in OASIS
|
||||
specifications can be found at the OASIS website. Copies of claims of rights made available for publication and any assurances of licenses to be made
|
||||
available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementors or users
|
||||
of this specification, can be obtained from the OASIS Executive Director.
|
||||
OASIS invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights which may
|
||||
cover technology that may be required to implement this specification. Please address the information to the OASIS Executive Director.
|
||||
Copyright © OASIS Open 2002-2007. All Rights Reserved.
|
||||
This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist
|
||||
in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the
|
||||
above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself does not be modified
|
||||
in any way, such as by removing the copyright notice or references to OASIS, except as needed for the purpose of developing OASIS specifications,
|
||||
in which case the procedures for copyrights defined in the OASIS Intellectual Property Rights document must be followed, or as required to translate
|
||||
it into languages other than English.
|
||||
The limited permissions granted above are perpetual and will not be revoked by OASIS or its successors or assigns.
|
||||
This document and the information contained herein is provided on an AS IS basis and OASIS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED,
|
||||
INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
-->
|
||||
|
||||
<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'
|
||||
xmlns:xenc='http://www.w3.org/2001/04/xmlenc#'
|
||||
xmlns:tns='http://docs.oasis-open.org/wsfed/authorization/200706'
|
||||
targetNamespace='http://docs.oasis-open.org/wsfed/authorization/200706'
|
||||
elementFormDefault='qualified' >
|
||||
<xs:import namespace='http://www.w3.org/2001/04/xmlenc#'
|
||||
schemaLocation='http://www.w3.org/TR/2002/REC-xmlenc-core-20021210/xenc-schema.xsd'/>
|
||||
|
||||
<!-- Section 9.2 -->
|
||||
<xs:element name='AdditionalContext' type='tns:AdditionalContextType' />
|
||||
<xs:complexType name='AdditionalContextType' >
|
||||
<xs:sequence>
|
||||
<xs:element name='ContextItem' type='tns:ContextItemType' minOccurs='0' maxOccurs='unbounded' />
|
||||
<xs:any namespace='##other' processContents='lax' minOccurs='0' maxOccurs='unbounded' />
|
||||
</xs:sequence>
|
||||
<xs:anyAttribute namespace='##other' processContents='lax' />
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name='ContextItemType' >
|
||||
<xs:choice minOccurs='0'>
|
||||
<xs:element name='Value' type='xs:string' minOccurs='1' maxOccurs='1' />
|
||||
<xs:any namespace='##other' processContents='lax' minOccurs='1' maxOccurs='1' />
|
||||
</xs:choice>
|
||||
<xs:attribute name='Name' type='xs:anyURI' use='required' />
|
||||
<xs:attribute name='Scope' type='xs:anyURI' use='optional' />
|
||||
<xs:anyAttribute namespace='##other' processContents='lax' />
|
||||
</xs:complexType>
|
||||
|
||||
<!-- Section 9.3 -->
|
||||
<xs:element name='ClaimType' type='tns:ClaimType' />
|
||||
<xs:complexType name='ClaimType' >
|
||||
<xs:sequence>
|
||||
<xs:element name="DisplayName" type="tns:DisplayNameType" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element name="Description" type="tns:DescriptionType" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element name="DisplayValue" type="tns:DisplayValueType" minOccurs="0" maxOccurs="1" />
|
||||
<xs:choice minOccurs='0'>
|
||||
<xs:element name='Value' type='xs:string' minOccurs='1' maxOccurs='1' />
|
||||
<xs:element name='EncryptedValue' type='tns:EncryptedValueType' minOccurs='1' maxOccurs='1' />
|
||||
<xs:element name='StructuredValue' type='tns:StructuredValueType' minOccurs='1' maxOccurs='1' />
|
||||
<xs:element name='ConstrainedValue' type='tns:ConstrainedValueType' minOccurs='1' maxOccurs='1' />
|
||||
<xs:any namespace='##other' processContents='lax' minOccurs='1' maxOccurs='1' />
|
||||
</xs:choice>
|
||||
</xs:sequence>
|
||||
<xs:attribute name='Uri' type='xs:anyURI' use='required' />
|
||||
<xs:attribute name='Optional' type='xs:boolean' use='optional' />
|
||||
<xs:anyAttribute namespace='##other' processContents='lax' />
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="DisplayNameType">
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="xs:string">
|
||||
<xs:anyAttribute namespace="##other" processContents="lax" />
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
<xs:complexType name="DescriptionType">
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="xs:string">
|
||||
<xs:anyAttribute namespace="##other" processContents="lax" />
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
<xs:complexType name="DisplayValueType">
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="xs:string">
|
||||
<xs:anyAttribute namespace="##other" processContents="lax" />
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="EncryptedValueType">
|
||||
<xs:sequence>
|
||||
<xs:element ref="xenc:EncryptedData" minOccurs="1" maxOccurs="1"/>
|
||||
</xs:sequence>
|
||||
<xs:attribute name="DecryptionCondition" type="xs:anyURI" use="optional"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="StructuredValueType">
|
||||
<xs:sequence>
|
||||
<xs:any namespace='##other' processContents='lax' minOccurs='1' maxOccurs='unbounded' />
|
||||
</xs:sequence>
|
||||
<xs:anyAttribute namespace='##other' processContents='lax' />
|
||||
</xs:complexType>
|
||||
|
||||
<!-- Section 9.3.1 -->
|
||||
|
||||
<xs:complexType name='ConstrainedValueType'>
|
||||
<xs:sequence>
|
||||
<xs:choice minOccurs='1'>
|
||||
<xs:element name='ValueLessThan' type='tns:ConstrainedSingleValueType' minOccurs='1' maxOccurs='1'/>
|
||||
<xs:element name='ValueLessThanOrEqual' type='tns:ConstrainedSingleValueType' minOccurs='1' maxOccurs='1'/>
|
||||
<xs:element name='ValueGreaterThan' type='tns:ConstrainedSingleValueType' minOccurs='1' maxOccurs='1'/>
|
||||
<xs:element name='ValueGreaterThanOrEqual' type='tns:ConstrainedSingleValueType' minOccurs='1' maxOccurs='1'/>
|
||||
<xs:element name='ValueInRangen' type='tns:ValueInRangeType' minOccurs='1' maxOccurs='1'/>
|
||||
<xs:element name='ValueOneOf' type='tns:ConstrainedManyValueType' minOccurs='1' maxOccurs='1'/>
|
||||
</xs:choice>
|
||||
<xs:any namespace='##other' processContents='lax' minOccurs='1' maxOccurs='unbounded' />
|
||||
</xs:sequence>
|
||||
<xs:attribute name='AssertConstraint' type='xs:boolean' use='optional' />
|
||||
</xs:complexType>
|
||||
<xs:complexType name='ValueInRangeType'>
|
||||
<xs:sequence>
|
||||
<xs:element name='ValueUpperBound' type='tns:ConstrainedSingleValueType' minOccurs='1' maxOccurs='1'/>
|
||||
<xs:element name='ValueLowerBound' type='tns:ConstrainedSingleValueType' minOccurs='1' maxOccurs='1'/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name='ConstrainedSingleValueType'>
|
||||
<xs:choice minOccurs='0'>
|
||||
<xs:element name='Value' type='xs:string' minOccurs='1' maxOccurs='1' />
|
||||
<xs:element name='StructuredValue' type='tns:StructuredValueType' minOccurs='1' maxOccurs='1' />
|
||||
</xs:choice>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name='ConstrainedManyValueType'>
|
||||
<xs:choice minOccurs='0'>
|
||||
<xs:element name='Value' type='xs:string' minOccurs='1' maxOccurs='unbounded' />
|
||||
<xs:element name='StructuredValue' type='tns:StructuredValueType' minOccurs='1' maxOccurs='unbounded' />
|
||||
</xs:choice>
|
||||
</xs:complexType>
|
||||
|
||||
</xs:schema>
|
||||
195
schemas/oasis-200401-wss-wssecurity-secext-1.0.xsd
Normal file
195
schemas/oasis-200401-wss-wssecurity-secext-1.0.xsd
Normal file
@@ -0,0 +1,195 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
OASIS takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; neither does it represent that it has made any effort to identify any such rights. Information on OASIS's procedures with respect to rights in OASIS specifications can be found at the OASIS website. Copies of claims of rights made available for publication and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementors or users of this specification, can be obtained from the OASIS Executive Director.
|
||||
OASIS invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights which may cover technology that may be required to implement this specification. Please address the information to the OASIS Executive Director.
|
||||
Copyright © OASIS Open 2002-2004. All Rights Reserved.
|
||||
This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself does not be modified in any way, such as by removing the copyright notice or references to OASIS, except as needed for the purpose of developing OASIS specifications, in which case the procedures for copyrights defined in the OASIS Intellectual Property Rights document must be followed, or as required to translate it into languages other than English.
|
||||
The limited permissions granted above are perpetual and will not be revoked by OASIS or its successors or assigns.
|
||||
This document and the information contained herein is provided on an “AS IS” basis and OASIS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
-->
|
||||
<xsd:schema targetNamespace="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" elementFormDefault="qualified" attributeFormDefault="unqualified" blockDefault="#all" version="0.2">
|
||||
<xsd:import namespace="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" schemaLocation="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"/>
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="http://www.w3.org/2001/xml.xsd"/>
|
||||
<xsd:import namespace="http://www.w3.org/2000/09/xmldsig#" schemaLocation="http://www.w3.org/TR/xmldsig-core/xmldsig-core-schema.xsd"/>
|
||||
<xsd:complexType name="AttributedString">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>This type represents an element with arbitrary attributes.</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleContent>
|
||||
<xsd:extension base="xsd:string">
|
||||
<xsd:attribute ref="wsu:Id"/>
|
||||
<xsd:anyAttribute namespace="##other" processContents="lax"/>
|
||||
</xsd:extension>
|
||||
</xsd:simpleContent>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="PasswordString">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>This type is used for password elements per Section 4.1.</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleContent>
|
||||
<xsd:extension base="wsse:AttributedString">
|
||||
<xsd:attribute name="Type" type="xsd:anyURI"/>
|
||||
</xsd:extension>
|
||||
</xsd:simpleContent>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="EncodedString">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>This type is used for elements containing stringified binary data.</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleContent>
|
||||
<xsd:extension base="wsse:AttributedString">
|
||||
<xsd:attribute name="EncodingType" type="xsd:anyURI"/>
|
||||
</xsd:extension>
|
||||
</xsd:simpleContent>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="UsernameTokenType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>This type represents a username token per Section 4.1</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="Username" type="wsse:AttributedString"/>
|
||||
<xsd:any processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute ref="wsu:Id"/>
|
||||
<xsd:anyAttribute namespace="##other" processContents="lax"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="BinarySecurityTokenType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>A security token that is encoded in binary</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleContent>
|
||||
<xsd:extension base="wsse:EncodedString">
|
||||
<xsd:attribute name="ValueType" type="xsd:anyURI"/>
|
||||
</xsd:extension>
|
||||
</xsd:simpleContent>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="KeyIdentifierType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>A security token key identifier</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleContent>
|
||||
<xsd:extension base="wsse:EncodedString">
|
||||
<xsd:attribute name="ValueType" type="xsd:anyURI"/>
|
||||
</xsd:extension>
|
||||
</xsd:simpleContent>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="tUsage">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>Typedef to allow a list of usages (as URIs).</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:list itemType="xsd:anyURI"/>
|
||||
</xsd:simpleType>
|
||||
<xsd:attribute name="Usage" type="tUsage">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>This global attribute is used to indicate the usage of a referenced or indicated token within the containing context</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:complexType name="ReferenceType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>This type represents a reference to an external security token.</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:attribute name="URI" type="xsd:anyURI"/>
|
||||
<xsd:attribute name="ValueType" type="xsd:anyURI"/>
|
||||
<xsd:anyAttribute namespace="##other" processContents="lax"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="EmbeddedType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>This type represents a reference to an embedded security token.</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:any processContents="lax"/>
|
||||
</xsd:choice>
|
||||
<xsd:attribute name="ValueType" type="xsd:anyURI"/>
|
||||
<xsd:anyAttribute namespace="##other" processContents="lax"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="SecurityTokenReferenceType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>This type is used reference a security token.</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:any processContents="lax"/>
|
||||
</xsd:choice>
|
||||
<xsd:attribute ref="wsu:Id"/>
|
||||
<xsd:attribute ref="wsse:Usage"/>
|
||||
<xsd:anyAttribute namespace="##other" processContents="lax"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="SecurityHeaderType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>This complexType defines header block to use for security-relevant data directed at a specific SOAP actor.</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:sequence>
|
||||
<xsd:any processContents="lax" minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>The use of "any" is to allow extensibility and different forms of security data.</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:any>
|
||||
</xsd:sequence>
|
||||
<xsd:anyAttribute namespace="##other" processContents="lax"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="TransformationParametersType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>This complexType defines a container for elements to be specified from any namespace as properties/parameters of a DSIG transformation.</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:sequence>
|
||||
<xsd:any processContents="lax" minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>The use of "any" is to allow extensibility from any namespace.</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:any>
|
||||
</xsd:sequence>
|
||||
<xsd:anyAttribute namespace="##other" processContents="lax"/>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="UsernameToken" type="wsse:UsernameTokenType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>This element defines the wsse:UsernameToken element per Section 4.1.</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:element name="BinarySecurityToken" type="wsse:BinarySecurityTokenType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>This element defines the wsse:BinarySecurityToken element per Section 4.2.</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:element name="Reference" type="wsse:ReferenceType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>This element defines a security token reference</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:element name="Embedded" type="wsse:EmbeddedType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>This element defines a security token embedded reference</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:element name="KeyIdentifier" type="wsse:KeyIdentifierType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>This element defines a key identifier reference</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:element name="SecurityTokenReference" type="wsse:SecurityTokenReferenceType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>This element defines the wsse:SecurityTokenReference per Section 4.3.</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:element name="Security" type="wsse:SecurityHeaderType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>This element defines the wsse:Security SOAP header element per Section 4.</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:element name="TransformationParameters" type="wsse:TransformationParametersType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>This element contains properties for transformations from any namespace, including DSIG.</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:element name="Password" type="wsse:PasswordString"/>
|
||||
<xsd:element name="Nonce" type="wsse:EncodedString"/>
|
||||
<xsd:simpleType name="FaultcodeEnum">
|
||||
<xsd:restriction base="xsd:QName">
|
||||
<xsd:enumeration value="wsse:UnsupportedSecurityToken"/>
|
||||
<xsd:enumeration value="wsse:UnsupportedAlgorithm"/>
|
||||
<xsd:enumeration value="wsse:InvalidSecurity"/>
|
||||
<xsd:enumeration value="wsse:InvalidSecurityToken"/>
|
||||
<xsd:enumeration value="wsse:FailedAuthentication"/>
|
||||
<xsd:enumeration value="wsse:FailedCheck"/>
|
||||
<xsd:enumeration value="wsse:SecurityTokenUnavailable"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:schema>
|
||||
108
schemas/oasis-200401-wss-wssecurity-utility-1.0.xsd
Normal file
108
schemas/oasis-200401-wss-wssecurity-utility-1.0.xsd
Normal file
@@ -0,0 +1,108 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
OASIS takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; neither does it represent that it has made any effort to identify any such rights. Information on OASIS's procedures with respect to rights in OASIS specifications can be found at the OASIS website. Copies of claims of rights made available for publication and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementors or users of this specification, can be obtained from the OASIS Executive Director.
|
||||
OASIS invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights which may cover technology that may be required to implement this specification. Please address the information to the OASIS Executive Director.
|
||||
Copyright © OASIS Open 2002-2004. All Rights Reserved.
|
||||
This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself does not be modified in any way, such as by removing the copyright notice or references to OASIS, except as needed for the purpose of developing OASIS specifications, in which case the procedures for copyrights defined in the OASIS Intellectual Property Rights document must be followed, or as required to translate it into languages other than English.
|
||||
The limited permissions granted above are perpetual and will not be revoked by OASIS or its successors or assigns.
|
||||
This document and the information contained herein is provided on an “AS IS” basis and OASIS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
-->
|
||||
<xsd:schema targetNamespace="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
|
||||
|
||||
|
||||
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
|
||||
elementFormDefault="qualified" attributeFormDefault="unqualified" version="0.1">
|
||||
<!-- // Fault Codes /////////////////////////////////////////// -->
|
||||
<xsd:simpleType name="tTimestampFault">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
This type defines the fault code value for Timestamp message expiration.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:restriction base="xsd:QName">
|
||||
<xsd:enumeration value="wsu:MessageExpired"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<!-- // Global attributes //////////////////////////////////// -->
|
||||
<xsd:attribute name="Id" type="xsd:ID">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
This global attribute supports annotating arbitrary elements with an ID.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attributeGroup name="commonAtts">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Convenience attribute group used to simplify this schema.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:attribute ref="wsu:Id" use="optional"/>
|
||||
<xsd:anyAttribute namespace="##other" processContents="lax"/>
|
||||
</xsd:attributeGroup>
|
||||
<!-- // Utility types //////////////////////////////////////// -->
|
||||
<xsd:complexType name="AttributedDateTime">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
This type is for elements whose [children] is a psuedo-dateTime and can have arbitrary attributes.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleContent>
|
||||
<xsd:extension base="xsd:string">
|
||||
<xsd:attributeGroup ref="wsu:commonAtts"/>
|
||||
</xsd:extension>
|
||||
</xsd:simpleContent>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="AttributedURI">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
This type is for elements whose [children] is an anyURI and can have arbitrary attributes.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleContent>
|
||||
<xsd:extension base="xsd:anyURI">
|
||||
<xsd:attributeGroup ref="wsu:commonAtts"/>
|
||||
</xsd:extension>
|
||||
</xsd:simpleContent>
|
||||
</xsd:complexType>
|
||||
<!-- // Timestamp header components /////////////////////////// -->
|
||||
<xsd:complexType name="TimestampType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
This complex type ties together the timestamp related elements into a composite type.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:sequence>
|
||||
<xsd:element ref="wsu:Created" minOccurs="0"/>
|
||||
<xsd:element ref="wsu:Expires" minOccurs="0"/>
|
||||
<xsd:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:any namespace="##other" processContents="lax"/>
|
||||
</xsd:choice>
|
||||
</xsd:sequence>
|
||||
<xsd:attributeGroup ref="wsu:commonAtts"/>
|
||||
</xsd:complexType>
|
||||
<xsd:element name="Timestamp" type="wsu:TimestampType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
This element allows Timestamps to be applied anywhere element wildcards are present,
|
||||
including as a SOAP header.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<!-- global element decls to allow individual elements to appear anywhere -->
|
||||
<xsd:element name="Expires" type="wsu:AttributedDateTime">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
This element allows an expiration time to be applied anywhere element wildcards are present.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:element name="Created" type="wsu:AttributedDateTime">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
This element allows a creation time to be applied anywhere element wildcards are present.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
137
schemas/w3-addr.xsd
Normal file
137
schemas/w3-addr.xsd
Normal file
@@ -0,0 +1,137 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
W3C XML Schema defined in the Web Services Addressing 1.0 specification
|
||||
http://www.w3.org/TR/ws-addr-core
|
||||
|
||||
Copyright © 2005 World Wide Web Consortium,
|
||||
|
||||
(Massachusetts Institute of Technology, European Research Consortium for
|
||||
Informatics and Mathematics, Keio University). All Rights Reserved. This
|
||||
work is distributed under the W3C® Software License [1] in the hope that
|
||||
it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
[1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231
|
||||
|
||||
$Id: ws-addr.xsd,v 1.2 2008/07/23 13:38:16 plehegar Exp $
|
||||
-->
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://www.w3.org/2005/08/addressing" targetNamespace="http://www.w3.org/2005/08/addressing" blockDefault="#all" elementFormDefault="qualified" finalDefault="" attributeFormDefault="unqualified">
|
||||
|
||||
<!-- Constructs from the WS-Addressing Core -->
|
||||
|
||||
<xs:element name="EndpointReference" type="tns:EndpointReferenceType"/>
|
||||
<xs:complexType name="EndpointReferenceType" mixed="false">
|
||||
<xs:sequence>
|
||||
<xs:element name="Address" type="tns:AttributedURIType"/>
|
||||
<xs:element ref="tns:ReferenceParameters" minOccurs="0"/>
|
||||
<xs:element ref="tns:Metadata" minOccurs="0"/>
|
||||
<xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xs:sequence>
|
||||
<xs:anyAttribute namespace="##other" processContents="lax"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:element name="ReferenceParameters" type="tns:ReferenceParametersType"/>
|
||||
<xs:complexType name="ReferenceParametersType" mixed="false">
|
||||
<xs:sequence>
|
||||
<xs:any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xs:sequence>
|
||||
<xs:anyAttribute namespace="##other" processContents="lax"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:element name="Metadata" type="tns:MetadataType"/>
|
||||
<xs:complexType name="MetadataType" mixed="false">
|
||||
<xs:sequence>
|
||||
<xs:any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xs:sequence>
|
||||
<xs:anyAttribute namespace="##other" processContents="lax"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:element name="MessageID" type="tns:AttributedURIType"/>
|
||||
<xs:element name="RelatesTo" type="tns:RelatesToType"/>
|
||||
<xs:complexType name="RelatesToType" mixed="false">
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="xs:anyURI">
|
||||
<xs:attribute name="RelationshipType" type="tns:RelationshipTypeOpenEnum" use="optional" default="http://www.w3.org/2005/08/addressing/reply"/>
|
||||
<xs:anyAttribute namespace="##other" processContents="lax"/>
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:simpleType name="RelationshipTypeOpenEnum">
|
||||
<xs:union memberTypes="tns:RelationshipType xs:anyURI"/>
|
||||
</xs:simpleType>
|
||||
|
||||
<xs:simpleType name="RelationshipType">
|
||||
<xs:restriction base="xs:anyURI">
|
||||
<xs:enumeration value="http://www.w3.org/2005/08/addressing/reply"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
|
||||
<xs:element name="ReplyTo" type="tns:EndpointReferenceType"/>
|
||||
<xs:element name="From" type="tns:EndpointReferenceType"/>
|
||||
<xs:element name="FaultTo" type="tns:EndpointReferenceType"/>
|
||||
<xs:element name="To" type="tns:AttributedURIType"/>
|
||||
<xs:element name="Action" type="tns:AttributedURIType"/>
|
||||
|
||||
<xs:complexType name="AttributedURIType" mixed="false">
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="xs:anyURI">
|
||||
<xs:anyAttribute namespace="##other" processContents="lax"/>
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
|
||||
<!-- Constructs from the WS-Addressing SOAP binding -->
|
||||
|
||||
<xs:attribute name="IsReferenceParameter" type="xs:boolean"/>
|
||||
|
||||
<xs:simpleType name="FaultCodesOpenEnumType">
|
||||
<xs:union memberTypes="tns:FaultCodesType xs:QName"/>
|
||||
</xs:simpleType>
|
||||
|
||||
<xs:simpleType name="FaultCodesType">
|
||||
<xs:restriction base="xs:QName">
|
||||
<xs:enumeration value="tns:InvalidAddressingHeader"/>
|
||||
<xs:enumeration value="tns:InvalidAddress"/>
|
||||
<xs:enumeration value="tns:InvalidEPR"/>
|
||||
<xs:enumeration value="tns:InvalidCardinality"/>
|
||||
<xs:enumeration value="tns:MissingAddressInEPR"/>
|
||||
<xs:enumeration value="tns:DuplicateMessageID"/>
|
||||
<xs:enumeration value="tns:ActionMismatch"/>
|
||||
<xs:enumeration value="tns:MessageAddressingHeaderRequired"/>
|
||||
<xs:enumeration value="tns:DestinationUnreachable"/>
|
||||
<xs:enumeration value="tns:ActionNotSupported"/>
|
||||
<xs:enumeration value="tns:EndpointUnavailable"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
|
||||
<xs:element name="RetryAfter" type="tns:AttributedUnsignedLongType"/>
|
||||
<xs:complexType name="AttributedUnsignedLongType" mixed="false">
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="xs:unsignedLong">
|
||||
<xs:anyAttribute namespace="##other" processContents="lax"/>
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:element name="ProblemHeaderQName" type="tns:AttributedQNameType"/>
|
||||
<xs:complexType name="AttributedQNameType" mixed="false">
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="xs:QName">
|
||||
<xs:anyAttribute namespace="##other" processContents="lax"/>
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:element name="ProblemIRI" type="tns:AttributedURIType"/>
|
||||
|
||||
<xs:element name="ProblemAction" type="tns:ProblemActionType"/>
|
||||
<xs:complexType name="ProblemActionType" mixed="false">
|
||||
<xs:sequence>
|
||||
<xs:element ref="tns:Action" minOccurs="0"/>
|
||||
<xs:element name="SoapAction" minOccurs="0" type="xs:anyURI"/>
|
||||
</xs:sequence>
|
||||
<xs:anyAttribute namespace="##other" processContents="lax"/>
|
||||
</xs:complexType>
|
||||
|
||||
</xs:schema>
|
||||
149
schemas/ws-addr.xsd
Normal file
149
schemas/ws-addr.xsd
Normal file
@@ -0,0 +1,149 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright © 2002-2004 BEA Systems Inc., International Business Machines Corporation,
|
||||
Microsoft Corporation, Inc, SAP AG, and Sun Microsystems, Inc.. All rights reserved.
|
||||
|
||||
Permission to copy, display, perform, modify and distribute the WS-Addressing Specification,
|
||||
and to authorize others to do the foregoing, in any medium without fee or royalty is hereby
|
||||
granted for the purpose of developing and evaluating the WS-Addressing Specification.
|
||||
|
||||
BEA, IBM, Microsoft, SAP AG, and Sun Microsystems (collectively, the "Authors") each agree
|
||||
to grant a license to third parties, under royalty-free and otherwise reasonable,
|
||||
non-discriminatory terms and conditions, to their respective essential patent claims that
|
||||
they deem necessary to implement the WS-Addressing Specification.
|
||||
|
||||
DISCLAIMERS:
|
||||
|
||||
THE WS-Addressing Specification IS PROVIDED "AS IS", AND THE AUTHORS MAKE NO REPRESENTATIONS
|
||||
OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, OR TITLE; THAT THE
|
||||
CONTENTS OF THE WS-Addressing Specification IS SUITABLE FOR ANY PURPOSE; NOR THAT THE
|
||||
IMPLEMENTATION OF SUCH CONTENTS WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS,
|
||||
TRADEMARKS OR OTHER RIGHTS.
|
||||
|
||||
THE AUTHORS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL
|
||||
DAMAGES ARISING OUT OF ANY USE OF THE WS-Addressing Specification OR THE PERFORMANCE OR
|
||||
IMPLEMENTATION OF THE CONTENTS THEREOF.
|
||||
|
||||
You may remove these disclaimers from your modified versions of the WS-Addressing
|
||||
Specification provided that you effectively disclaim all warranties and liabilities on behalf
|
||||
of all copyright holders in the copies of any such modified versions you distribute.
|
||||
|
||||
The name and trademarks of the Authors may NOT be used in any manner, including advertising
|
||||
or publicity pertaining to the WS-Addressing Specification or its contents without specific,
|
||||
written prior permission. Title to copyright in the WS-Addressing Specification will at all
|
||||
times remain with the Authors.
|
||||
|
||||
No other rights are granted by implication, estoppel or otherwise.
|
||||
|
||||
-->
|
||||
<xs:schema targetNamespace="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" elementFormDefault="qualified" blockDefault="#all">
|
||||
<!-- //////////////////// WS-Addressing //////////////////// -->
|
||||
<!-- Endpoint reference -->
|
||||
<xs:element name="EndpointReference" type="wsa:EndpointReferenceType"/>
|
||||
<xs:complexType name="EndpointReferenceType">
|
||||
<xs:sequence>
|
||||
<xs:element name="Address" type="wsa:AttributedURI"/>
|
||||
<xs:element name="ReferenceProperties" type="wsa:ReferencePropertiesType" minOccurs="0"/>
|
||||
<xs:element name="ReferenceParameters" type="wsa:ReferenceParametersType" minOccurs="0"/>
|
||||
<xs:element name="PortType" type="wsa:AttributedQName" minOccurs="0"/>
|
||||
<xs:element name="ServiceName" type="wsa:ServiceNameType" minOccurs="0"/>
|
||||
<xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
If "Policy" elements from namespace "http://schemas.xmlsoap.org/ws/2002/12/policy#policy" are used, they must appear first (before any extensibility elements).
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:any>
|
||||
</xs:sequence>
|
||||
<xs:anyAttribute namespace="##other" processContents="lax"/>
|
||||
</xs:complexType>
|
||||
<xs:complexType name="ReferencePropertiesType">
|
||||
<xs:sequence>
|
||||
<xs:any processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
<xs:complexType name="ReferenceParametersType">
|
||||
<xs:sequence>
|
||||
<xs:any processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
<xs:complexType name="ServiceNameType">
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="xs:QName">
|
||||
<xs:attribute name="PortName" type="xs:NCName"/>
|
||||
<xs:anyAttribute namespace="##other" processContents="lax"/>
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
<!-- Message information header blocks -->
|
||||
<xs:element name="MessageID" type="wsa:AttributedURI"/>
|
||||
<xs:element name="RelatesTo" type="wsa:Relationship"/>
|
||||
<xs:element name="To" type="wsa:AttributedURI"/>
|
||||
<xs:element name="Action" type="wsa:AttributedURI"/>
|
||||
<xs:element name="From" type="wsa:EndpointReferenceType"/>
|
||||
<xs:element name="ReplyTo" type="wsa:EndpointReferenceType"/>
|
||||
<xs:element name="FaultTo" type="wsa:EndpointReferenceType"/>
|
||||
<xs:complexType name="Relationship">
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="xs:anyURI">
|
||||
<xs:attribute name="RelationshipType" type="xs:QName" use="optional"/>
|
||||
<xs:anyAttribute namespace="##other" processContents="lax"/>
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
<xs:simpleType name="RelationshipTypeValues">
|
||||
<xs:restriction base="xs:QName">
|
||||
<xs:enumeration value="wsa:Reply"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
<!--
|
||||
June 19, 2007: The ReplyAfter element is deprecated. The name of this element does not match the
|
||||
name (RetryAfter) used in the specification (http://www.w3.org/Submission/2004/SUBM-ws-addressing-20040810/).
|
||||
-->
|
||||
<xs:element name="ReplyAfter" type="wsa:ReplyAfterType"/>
|
||||
<xs:complexType name="ReplyAfterType">
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="xs:nonNegativeInteger">
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
<!--
|
||||
June 19, 2007: The RetryAfter element has been added to be consistent with the specification
|
||||
(http://www.w3.org/Submission/2004/SUBM-ws-addressing-20040810/).
|
||||
-->
|
||||
<xs:element name="RetryAfter" type="wsa:RetryAfterType"/>
|
||||
<xs:complexType name="RetryAfterType">
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="xs:nonNegativeInteger">
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
<xs:simpleType name="FaultSubcodeValues">
|
||||
<xs:restriction base="xs:QName">
|
||||
<xs:enumeration value="wsa:InvalidMessageInformationHeader"/>
|
||||
<xs:enumeration value="wsa:MessageInformationHeaderRequired"/>
|
||||
<xs:enumeration value="wsa:DestinationUnreachable"/>
|
||||
<xs:enumeration value="wsa:ActionNotSupported"/>
|
||||
<xs:enumeration value="wsa:EndpointUnavailable"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
<xs:attribute name="Action" type="xs:anyURI"/>
|
||||
<!-- Common declarations and definitions -->
|
||||
<xs:complexType name="AttributedQName">
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="xs:QName">
|
||||
<xs:anyAttribute namespace="##other" processContents="lax"/>
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
<xs:complexType name="AttributedURI">
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="xs:anyURI">
|
||||
<xs:anyAttribute namespace="##other" processContents="lax"/>
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
</xs:schema>
|
||||
145
schemas/ws-authorization.xsd
Normal file
145
schemas/ws-authorization.xsd
Normal file
@@ -0,0 +1,145 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
OASIS takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain to the
|
||||
implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available;
|
||||
neither does it represent that it has made any effort to identify any such rights. Information on OASIS's procedures with respect to rights in OASIS
|
||||
specifications can be found at the OASIS website. Copies of claims of rights made available for publication and any assurances of licenses to be made
|
||||
available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementors or users
|
||||
of this specification, can be obtained from the OASIS Executive Director.
|
||||
OASIS invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights which may
|
||||
cover technology that may be required to implement this specification. Please address the information to the OASIS Executive Director.
|
||||
Copyright © OASIS Open 2002-2007. All Rights Reserved.
|
||||
This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist
|
||||
in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the
|
||||
above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself does not be modified
|
||||
in any way, such as by removing the copyright notice or references to OASIS, except as needed for the purpose of developing OASIS specifications,
|
||||
in which case the procedures for copyrights defined in the OASIS Intellectual Property Rights document must be followed, or as required to translate
|
||||
it into languages other than English.
|
||||
The limited permissions granted above are perpetual and will not be revoked by OASIS or its successors or assigns.
|
||||
This document and the information contained herein is provided on an AS IS basis and OASIS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED,
|
||||
INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
-->
|
||||
|
||||
<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'
|
||||
xmlns:xenc='http://www.w3.org/2001/04/xmlenc#'
|
||||
xmlns:tns='http://docs.oasis-open.org/wsfed/authorization/200706'
|
||||
targetNamespace='http://docs.oasis-open.org/wsfed/authorization/200706'
|
||||
elementFormDefault='qualified' >
|
||||
<xs:import namespace='http://www.w3.org/2001/04/xmlenc#'
|
||||
schemaLocation='http://www.w3.org/TR/2002/REC-xmlenc-core-20021210/xenc-schema.xsd'/>
|
||||
|
||||
<!-- Section 9.2 -->
|
||||
<xs:element name='AdditionalContext' type='tns:AdditionalContextType' />
|
||||
<xs:complexType name='AdditionalContextType' >
|
||||
<xs:sequence>
|
||||
<xs:element name='ContextItem' type='tns:ContextItemType' minOccurs='0' maxOccurs='unbounded' />
|
||||
<xs:any namespace='##other' processContents='lax' minOccurs='0' maxOccurs='unbounded' />
|
||||
</xs:sequence>
|
||||
<xs:anyAttribute namespace='##other' processContents='lax' />
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name='ContextItemType' >
|
||||
<xs:choice minOccurs='0'>
|
||||
<xs:element name='Value' type='xs:string' minOccurs='1' maxOccurs='1' />
|
||||
<xs:any namespace='##other' processContents='lax' minOccurs='1' maxOccurs='1' />
|
||||
</xs:choice>
|
||||
<xs:attribute name='Name' type='xs:anyURI' use='required' />
|
||||
<xs:attribute name='Scope' type='xs:anyURI' use='optional' />
|
||||
<xs:anyAttribute namespace='##other' processContents='lax' />
|
||||
</xs:complexType>
|
||||
|
||||
<!-- Section 9.3 -->
|
||||
<xs:element name='ClaimType' type='tns:ClaimType' />
|
||||
<xs:complexType name='ClaimType' >
|
||||
<xs:sequence>
|
||||
<xs:element name="DisplayName" type="tns:DisplayNameType" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element name="Description" type="tns:DescriptionType" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element name="DisplayValue" type="tns:DisplayValueType" minOccurs="0" maxOccurs="1" />
|
||||
<xs:choice minOccurs='0'>
|
||||
<xs:element name='Value' type='xs:string' minOccurs='1' maxOccurs='1' />
|
||||
<xs:element name='EncryptedValue' type='tns:EncryptedValueType' minOccurs='1' maxOccurs='1' />
|
||||
<xs:element name='StructuredValue' type='tns:StructuredValueType' minOccurs='1' maxOccurs='1' />
|
||||
<xs:element name='ConstrainedValue' type='tns:ConstrainedValueType' minOccurs='1' maxOccurs='1' />
|
||||
<xs:any namespace='##other' processContents='lax' minOccurs='1' maxOccurs='1' />
|
||||
</xs:choice>
|
||||
</xs:sequence>
|
||||
<xs:attribute name='Uri' type='xs:anyURI' use='required' />
|
||||
<xs:attribute name='Optional' type='xs:boolean' use='optional' />
|
||||
<xs:anyAttribute namespace='##other' processContents='lax' />
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="DisplayNameType">
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="xs:string">
|
||||
<xs:anyAttribute namespace="##other" processContents="lax" />
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
<xs:complexType name="DescriptionType">
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="xs:string">
|
||||
<xs:anyAttribute namespace="##other" processContents="lax" />
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
<xs:complexType name="DisplayValueType">
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="xs:string">
|
||||
<xs:anyAttribute namespace="##other" processContents="lax" />
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="EncryptedValueType">
|
||||
<xs:sequence>
|
||||
<xs:element ref="xenc:EncryptedData" minOccurs="1" maxOccurs="1"/>
|
||||
</xs:sequence>
|
||||
<xs:attribute name="DecryptionCondition" type="xs:anyURI" use="optional"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="StructuredValueType">
|
||||
<xs:sequence>
|
||||
<xs:any namespace='##other' processContents='lax' minOccurs='1' maxOccurs='unbounded' />
|
||||
</xs:sequence>
|
||||
<xs:anyAttribute namespace='##other' processContents='lax' />
|
||||
</xs:complexType>
|
||||
|
||||
<!-- Section 9.3.1 -->
|
||||
|
||||
<xs:complexType name='ConstrainedValueType'>
|
||||
<xs:sequence>
|
||||
<xs:choice minOccurs='1'>
|
||||
<xs:element name='ValueLessThan' type='tns:ConstrainedSingleValueType' minOccurs='1' maxOccurs='1'/>
|
||||
<xs:element name='ValueLessThanOrEqual' type='tns:ConstrainedSingleValueType' minOccurs='1' maxOccurs='1'/>
|
||||
<xs:element name='ValueGreaterThan' type='tns:ConstrainedSingleValueType' minOccurs='1' maxOccurs='1'/>
|
||||
<xs:element name='ValueGreaterThanOrEqual' type='tns:ConstrainedSingleValueType' minOccurs='1' maxOccurs='1'/>
|
||||
<xs:element name='ValueInRangen' type='tns:ValueInRangeType' minOccurs='1' maxOccurs='1'/>
|
||||
<xs:element name='ValueOneOf' type='tns:ConstrainedManyValueType' minOccurs='1' maxOccurs='1'/>
|
||||
</xs:choice>
|
||||
<xs:any namespace='##other' processContents='lax' minOccurs='1' maxOccurs='unbounded' />
|
||||
</xs:sequence>
|
||||
<xs:attribute name='AssertConstraint' type='xs:boolean' use='optional' />
|
||||
</xs:complexType>
|
||||
<xs:complexType name='ValueInRangeType'>
|
||||
<xs:sequence>
|
||||
<xs:element name='ValueUpperBound' type='tns:ConstrainedSingleValueType' minOccurs='1' maxOccurs='1'/>
|
||||
<xs:element name='ValueLowerBound' type='tns:ConstrainedSingleValueType' minOccurs='1' maxOccurs='1'/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name='ConstrainedSingleValueType'>
|
||||
<xs:choice minOccurs='0'>
|
||||
<xs:element name='Value' type='xs:string' minOccurs='1' maxOccurs='1' />
|
||||
<xs:element name='StructuredValue' type='tns:StructuredValueType' minOccurs='1' maxOccurs='1' />
|
||||
</xs:choice>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name='ConstrainedManyValueType'>
|
||||
<xs:choice minOccurs='0'>
|
||||
<xs:element name='Value' type='xs:string' minOccurs='1' maxOccurs='unbounded' />
|
||||
<xs:element name='StructuredValue' type='tns:StructuredValueType' minOccurs='1' maxOccurs='unbounded' />
|
||||
</xs:choice>
|
||||
</xs:complexType>
|
||||
|
||||
</xs:schema>
|
||||
470
schemas/ws-federation.xsd
Normal file
470
schemas/ws-federation.xsd
Normal file
@@ -0,0 +1,470 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!--
|
||||
OASIS takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain to the
|
||||
implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available;
|
||||
neither does it represent that it has made any effort to identify any such rights. Information on OASIS's procedures with respect to rights in OASIS
|
||||
specifications can be found at the OASIS website. Copies of claims of rights made available for publication and any assurances of licenses to be made
|
||||
available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementors or users
|
||||
of this specification, can be obtained from the OASIS Executive Director.
|
||||
OASIS invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights which may
|
||||
cover technology that may be required to implement this specification. Please address the information to the OASIS Executive Director.
|
||||
Copyright © OASIS Open 2002-2007. All Rights Reserved.
|
||||
This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist
|
||||
in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the
|
||||
above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself does not be modified
|
||||
in any way, such as by removing the copyright notice or references to OASIS, except as needed for the purpose of developing OASIS specifications,
|
||||
in which case the procedures for copyrights defined in the OASIS Intellectual Property Rights document must be followed, or as required to translate
|
||||
it into languages other than English.
|
||||
The limited permissions granted above are perpetual and will not be revoked by OASIS or its successors or assigns.
|
||||
This document and the information contained herein is provided on an AS IS basis and OASIS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED,
|
||||
INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
-->
|
||||
<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'
|
||||
xmlns:sp='http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702'
|
||||
xmlns:tns='http://docs.oasis-open.org/wsfed/federation/200706'
|
||||
xmlns:wsa='http://www.w3.org/2005/08/addressing'
|
||||
xmlns:mex='http://schemas.xmlsoap.org/ws/2004/09/mex'
|
||||
xmlns:wsse='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd'
|
||||
xmlns:wsu='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd'
|
||||
xmlns:md='urn:oasis:names:tc:SAML:2.0:metadata'
|
||||
xmlns:auth='http://docs.oasis-open.org/wsfed/authorization/200706'
|
||||
targetNamespace='http://docs.oasis-open.org/wsfed/federation/200706'
|
||||
elementFormDefault='qualified' >
|
||||
|
||||
<xs:import namespace='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd'
|
||||
schemaLocation='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd' />
|
||||
<xs:import namespace='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd'
|
||||
schemaLocation='oasis-200401-wss-wssecurity-utility-1.0.xsd' />
|
||||
<xs:import namespace='http://www.w3.org/2005/08/addressing'
|
||||
schemaLocation='w3-addr.xsd' />
|
||||
<xs:import namespace='http://schemas.xmlsoap.org/ws/2004/09/mex'
|
||||
schemaLocation='http://schemas.xmlsoap.org/ws/2004/09/mex/MetadataExchange.xsd' />
|
||||
<xs:import namespace='urn:oasis:names:tc:SAML:2.0:metadata'
|
||||
schemaLocation='saml-schema-metadata-2.0.xsd' />
|
||||
<xs:import namespace='http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702'
|
||||
schemaLocation='ws-securitypolicy-1.2.xsd'/>
|
||||
<xs:import namespace='http://docs.oasis-open.org/wsfed/authorization/200706'
|
||||
schemaLocation='ws-authorization.xsd'/>
|
||||
|
||||
<!-- Section 3.1 -->
|
||||
<!-- Note: Use of this root element is discouraged in favor of use of md:EntitiesDescriptor or md EntityDescriptor -->
|
||||
<xs:element name='FederationMetadata' type='tns:FederationMetadataType' />
|
||||
|
||||
<xs:complexType name='FederationMetadataType' >
|
||||
<xs:sequence>
|
||||
<!--
|
||||
*** Accurate content model is nondeterministic ***
|
||||
<xs:element name='Federation' type='tns:FederationType' minOccurs='1' maxOccurs='unbounded' />
|
||||
<xs:any namespace='##any' processContents='lax' minOccurs='0' maxOccurs='unbounded' />
|
||||
-->
|
||||
<xs:any namespace='##any' processContents='lax' minOccurs='0' maxOccurs='unbounded' />
|
||||
</xs:sequence>
|
||||
<xs:anyAttribute namespace='##other' processContents='lax' />
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name='FederationType' >
|
||||
<xs:sequence>
|
||||
<xs:any namespace='##any' processContents='lax' minOccurs='0' maxOccurs='unbounded' />
|
||||
</xs:sequence>
|
||||
<xs:attribute name='FederationID' type='xs:anyURI' />
|
||||
<xs:anyAttribute namespace='##other' processContents='lax' />
|
||||
</xs:complexType>
|
||||
|
||||
<!-- Section 3.1.2.1 -->
|
||||
<xs:complexType name="WebServiceDescriptorType" abstract="true">
|
||||
<xs:complexContent>
|
||||
<xs:extension base="md:RoleDescriptorType">
|
||||
<xs:sequence>
|
||||
<xs:element ref="tns:LogicalServiceNamesOffered" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element ref="tns:TokenTypesOffered" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element ref="tns:ClaimDialectsOffered" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element ref="tns:ClaimTypesOffered" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element ref="tns:ClaimTypesRequested" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element ref="tns:AutomaticPseudonyms" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element ref="tns:TargetScopes" minOccurs="0" maxOccurs="1"/>
|
||||
</xs:sequence>
|
||||
<xs:attribute name="ServiceDisplayName" type="xs:string" use="optional"/>
|
||||
<xs:attribute name="ServiceDescription" type="xs:string" use="optional"/>
|
||||
</xs:extension>
|
||||
</xs:complexContent>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:element name='LogicalServiceNamesOffered' type='tns:LogicalServiceNamesOfferedType' />
|
||||
<xs:element name='TokenTypesOffered' type='tns:TokenTypesOfferedType' />
|
||||
<xs:element name='ClaimDialectsOffered' type='tns:ClaimDialectsOfferedType' />
|
||||
<xs:element name='ClaimTypesOffered' type='tns:ClaimTypesOfferedType' />
|
||||
<xs:element name='ClaimTypesRequested' type='tns:ClaimTypesRequestedType' />
|
||||
<xs:element name="AutomaticPseudonyms" type="xs:boolean"/>
|
||||
<xs:element name='TargetScopes' type='tns:EndpointType'/>
|
||||
|
||||
<!-- Section 3.1.2.2 -->
|
||||
<xs:complexType name="SecurityTokenServiceType">
|
||||
<xs:complexContent>
|
||||
<xs:extension base="tns:WebServiceDescriptorType">
|
||||
<xs:sequence>
|
||||
<xs:element ref="tns:SecurityTokenServiceEndpoint" minOccurs="1" maxOccurs="unbounded"/>
|
||||
<xs:element ref="tns:SingleSignOutSubscriptionEndpoint" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<xs:element ref="tns:SingleSignOutNotificationEndpoint" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<xs:element ref="tns:PassiveRequestorEndpoint" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xs:sequence>
|
||||
</xs:extension>
|
||||
</xs:complexContent>
|
||||
</xs:complexType>
|
||||
<xs:element name="SecurityTokenServiceEndpoint" type="tns:EndpointType"/>
|
||||
<xs:element name="SingleSignOutSubscriptionEndpoint" type="tns:EndpointType"/>
|
||||
<xs:element name="SingleSignOutNotificationEndpoint" type="tns:EndpointType"/>
|
||||
<xs:element name="PassiveRequestorEndpoint" type="tns:EndpointType"/>
|
||||
|
||||
<!-- Section 3.1.2.3 -->
|
||||
<xs:complexType name="PseudonymServiceType">
|
||||
<xs:complexContent>
|
||||
<xs:extension base="tns:WebServiceDescriptorType">
|
||||
<xs:sequence>
|
||||
<xs:element ref="tns:PseudonymServiceEndpoint" minOccurs="1" maxOccurs="unbounded"/>
|
||||
<xs:element ref="tns:SingleSignOutNotificationEndpoint" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xs:sequence>
|
||||
</xs:extension>
|
||||
</xs:complexContent>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:element name="PseudonymServiceEndpoint" type="tns:EndpointType"/>
|
||||
<!-- Defined above -->
|
||||
<!-- <xs:element name="SingleSignOutNotificationEndpoint" type="tns:EndpointType"/> -->
|
||||
|
||||
<!-- Section 3.1.2.4 -->
|
||||
<xs:complexType name="AttributeServiceType">
|
||||
<xs:complexContent>
|
||||
<xs:extension base="tns:WebServiceDescriptorType">
|
||||
<xs:sequence>
|
||||
<xs:element ref="tns:AttributeServiceEndpoint" minOccurs="1" maxOccurs="unbounded"/>
|
||||
<xs:element ref="tns:SingleSignOutNotificationEndpoint" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xs:sequence>
|
||||
</xs:extension>
|
||||
</xs:complexContent>
|
||||
</xs:complexType>
|
||||
<xs:element name="AttributeServiceEndpoint" type="tns:EndpointType"/>
|
||||
<!-- Defined above -->
|
||||
<!-- <xs:element name="SingleSignOutNotificationEndpoint" type="tns:EndpointType"/> -->
|
||||
|
||||
<!-- Section 3.1.2.5 -->
|
||||
<xs:complexType name="ApplicationServiceType">
|
||||
<xs:complexContent>
|
||||
<xs:extension base="tns:WebServiceDescriptorType">
|
||||
<xs:sequence>
|
||||
<xs:element ref="tns:ApplicationServiceEndpoint" minOccurs="1" maxOccurs="unbounded"/>
|
||||
<xs:element ref="tns:SingleSignOutNotificationEndpoint" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<xs:element ref="tns:PassiveRequestorEndpoint" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xs:sequence>
|
||||
</xs:extension>
|
||||
</xs:complexContent>
|
||||
</xs:complexType>
|
||||
<xs:element name="ApplicationServiceEndpoint" type="tns:EndpointType"/>
|
||||
<!-- Defined above -->
|
||||
<!-- <xs:element name="SingleSignOutNotificationEndpoint" type="tns:EndpointType"/> -->
|
||||
<!-- <xs:element name="PassiveRequestorEndpoint" type="tns:EndpointType"/> -->
|
||||
|
||||
|
||||
<!-- Section 3.1.3 -->
|
||||
<!-- Defined above -->
|
||||
<!--<xs:element name='LogicalServiceNamesOffered' type='tns:LogicalServiceNamesOfferedType' />-->
|
||||
|
||||
<xs:complexType name='LogicalServiceNamesOfferedType' >
|
||||
<xs:sequence>
|
||||
<xs:element name='IssuerName' type='tns:IssuerNameType' minOccurs='1' maxOccurs='unbounded' />
|
||||
</xs:sequence>
|
||||
<xs:anyAttribute namespace='##other' processContents='lax' />
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name='IssuerNameType' >
|
||||
<xs:attribute name='Uri' type='xs:anyURI' use='required' />
|
||||
<xs:anyAttribute namespace='##other' processContents='lax' />
|
||||
</xs:complexType>
|
||||
|
||||
<!-- Section 3.1.4 -->
|
||||
<xs:element name='PsuedonymServiceEndpoints' type='tns:EndpointType' />
|
||||
<xs:complexType name='EndpointType' >
|
||||
<xs:sequence>
|
||||
<xs:element ref='wsa:EndpointReference' minOccurs='1' maxOccurs='unbounded'/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
|
||||
<!-- Section 3.1.5 -->
|
||||
<xs:element name='AttributeServiceEndpoints' type='tns:EndpointType' />
|
||||
|
||||
<!-- Section 3.1.6 -->
|
||||
<xs:element name='SingleSignOutSubscriptionEndpoints' type='tns:EndpointType' />
|
||||
|
||||
<!-- Section 3.1.7 -->
|
||||
<xs:element name='SingleSignOutNotificationEndpoints' type='tns:EndpointType' />
|
||||
|
||||
<!-- Section 3.1.8 -->
|
||||
<!-- Defined above -->
|
||||
<!--<xs:element name='TokenTypesOffered' type='tns:TokenTypesOfferedType' />-->
|
||||
<xs:complexType name='TokenTypesOfferedType' >
|
||||
<xs:sequence>
|
||||
<xs:element name='TokenType' type='tns:TokenType' minOccurs='1' maxOccurs='unbounded' />
|
||||
<xs:any namespace='##other' processContents='lax' minOccurs='0' maxOccurs='unbounded' />
|
||||
</xs:sequence>
|
||||
<xs:anyAttribute namespace='##other' processContents='lax' />
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name='TokenType' >
|
||||
<xs:sequence>
|
||||
<xs:any namespace='##any' processContents='lax' minOccurs='0' maxOccurs='unbounded' />
|
||||
</xs:sequence>
|
||||
<xs:attribute name='Uri' type='xs:anyURI' />
|
||||
<xs:anyAttribute namespace='##other' processContents='lax' />
|
||||
</xs:complexType>
|
||||
|
||||
<!-- Section 3.1.9 -->
|
||||
<!-- Defined above -->
|
||||
<!-- <xs:element name='ClaimTypesOffered' type='tns:ClaimTypesOfferedType' /> -->
|
||||
<xs:complexType name='ClaimTypesOfferedType'>
|
||||
<xs:sequence>
|
||||
<xs:element ref='auth:ClaimType' minOccurs='1' maxOccurs='unbounded' />
|
||||
</xs:sequence>
|
||||
<xs:anyAttribute namespace='##other' processContents='lax' />
|
||||
</xs:complexType>
|
||||
|
||||
<!-- Section 3.1.10 -->
|
||||
<!-- Defined above -->
|
||||
<!-- <xs:element name='ClaimTypesRequested' ype='tns:ClaimTypesRequestedType' /> -->
|
||||
<xs:complexType name='ClaimTypesRequestedType'>
|
||||
<xs:sequence>
|
||||
<xs:element ref='auth:ClaimType' minOccurs='1' maxOccurs='unbounded' />
|
||||
</xs:sequence>
|
||||
<xs:anyAttribute namespace='##other' processContents='lax' />
|
||||
</xs:complexType>
|
||||
|
||||
<!-- Section 3.1.11 -->
|
||||
<!-- Defined above -->
|
||||
<!--<xs:element name='ClaimDialectsOffered' type='tns:ClaimDialectsOfferedType' />-->
|
||||
<xs:complexType name='ClaimDialectsOfferedType'>
|
||||
<xs:sequence>
|
||||
<xs:element name='ClaimDialect' type='tns:ClaimDialectType' minOccurs='1' maxOccurs='unbounded' />
|
||||
</xs:sequence>
|
||||
<xs:anyAttribute namespace='##other' processContents='lax' />
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name='ClaimDialectType' >
|
||||
<xs:sequence>
|
||||
<xs:any namespace='##other' processContents='lax' minOccurs='0' maxOccurs='unbounded' />
|
||||
</xs:sequence>
|
||||
<xs:attribute name='Uri' type='xs:anyURI' />
|
||||
<xs:anyAttribute namespace='##other' processContents='lax' />
|
||||
</xs:complexType>
|
||||
|
||||
<!-- Section 3.1.12 -->
|
||||
<!-- Defined above -->
|
||||
<!-- <xs:element name='AutomaticPseudonyms' type='xs:boolean' /> -->
|
||||
|
||||
<!-- Section 3.1.13 -->
|
||||
<xs:element name='PassiveRequestorEnpoints' type='tns:EndpointType'/>
|
||||
|
||||
<!-- Section 3.1.14 -->
|
||||
<!-- Defined above -->
|
||||
<!--<xs:element name='TargetScopes' type='tns:EndpointType'/>-->
|
||||
|
||||
<!-- Section 3.2.4 -->
|
||||
<xs:element name='FederationMetadataHandler' type='tns:FederationMetadataHandlerType' />
|
||||
<xs:complexType name='FederationMetadataHandlerType' >
|
||||
<xs:anyAttribute namespace='##other' processContents='lax' />
|
||||
</xs:complexType>
|
||||
|
||||
<!-- Section 4.1 -->
|
||||
<xs:element name='SignOut' type='tns:SignOutType' />
|
||||
<xs:complexType name='SignOutType' >
|
||||
<xs:sequence>
|
||||
<xs:element ref='tns:Realm' minOccurs='0' />
|
||||
<xs:element name='SignOutBasis' type='tns:SignOutBasisType' minOccurs='1' maxOccurs='1' />
|
||||
<xs:any namespace='##other' processContents='lax' minOccurs='0' maxOccurs='unbounded' />
|
||||
</xs:sequence>
|
||||
<xs:attribute ref='wsu:Id' use='optional' />
|
||||
<xs:anyAttribute namespace='##other' processContents='lax' />
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name='SignOutBasisType' >
|
||||
<xs:sequence>
|
||||
<xs:any namespace='##other' processContents='lax' minOccurs='1' maxOccurs='unbounded' />
|
||||
</xs:sequence>
|
||||
<xs:anyAttribute namespace='##other' processContents='lax' />
|
||||
</xs:complexType>
|
||||
|
||||
<!-- Section 4.2 -->
|
||||
<xs:element name='Realm' type='xs:anyURI' />
|
||||
|
||||
<!-- Section 6.1 -->
|
||||
<xs:element name='FilterPseudonyms' type='tns:FilterPseudonymsType' />
|
||||
<xs:complexType name='FilterPseudonymsType' >
|
||||
<xs:sequence>
|
||||
<xs:element ref='tns:PseudonymBasis' minOccurs='0' maxOccurs='1' />
|
||||
<xs:element ref='tns:RelativeTo' minOccurs='0' maxOccurs='1' />
|
||||
<xs:any namespace='##other' minOccurs='0' maxOccurs='unbounded' />
|
||||
</xs:sequence>
|
||||
<xs:anyAttribute namespace='##other' processContents='lax' />
|
||||
</xs:complexType>
|
||||
|
||||
<xs:element name='PseudonymBasis' type='tns:PseudonymBasisType' />
|
||||
<xs:complexType name='PseudonymBasisType' >
|
||||
<xs:sequence>
|
||||
<xs:any namespace='##other' processContents='lax' minOccurs='1' maxOccurs='1' />
|
||||
</xs:sequence>
|
||||
<xs:anyAttribute namespace='##other' processContents='lax' />
|
||||
</xs:complexType>
|
||||
|
||||
<xs:element name='RelativeTo' type='tns:RelativeToType' />
|
||||
<xs:complexType name='RelativeToType' >
|
||||
<xs:sequence>
|
||||
<xs:any namespace='##any' processContents='lax' minOccurs='0' maxOccurs='unbounded' />
|
||||
</xs:sequence>
|
||||
<xs:anyAttribute namespace='##other' processContents='lax' />
|
||||
</xs:complexType>
|
||||
|
||||
<!-- Section 6.2 -->
|
||||
<xs:element name='Pseudonym' type='tns:PseudonymType' />
|
||||
|
||||
<xs:complexType name='PseudonymType' >
|
||||
<xs:sequence>
|
||||
<!--
|
||||
*** Accurate content model is nondeterministic ***
|
||||
<xs:element ref='tns:PseudonymBasis' minOccurs='1' maxOccurs='1' />
|
||||
<xs:element ref='tns:RelativeTo' minOccurs='1' maxOccurs='1' />
|
||||
<xs:element ref='wsu:Expires' minOccurs='0' maxOccurs='1' />
|
||||
<xs:element ref='tns:SecurityToken' minOccurs='0' maxOccurs='unbounded' />
|
||||
<xs:element ref='tns:ProofToken' minOccurs='0' maxOccurs='unbounded' />
|
||||
<xs:any namespace='##other' processContents='lax' minOccurs='0' maxOccurs='unbounded' />
|
||||
-->
|
||||
|
||||
<xs:element ref='tns:PseudonymBasis' minOccurs='1' maxOccurs='1' />
|
||||
<xs:element ref='tns:RelativeTo' minOccurs='1' maxOccurs='1' />
|
||||
<xs:any namespace='##any' processContents='lax' minOccurs='0' maxOccurs='unbounded' />
|
||||
</xs:sequence>
|
||||
<xs:anyAttribute namespace='##other' processContents='lax' />
|
||||
</xs:complexType>
|
||||
|
||||
<xs:element name='SecurityToken' type='tns:SecurityTokenType' />
|
||||
<xs:complexType name='SecurityTokenType' >
|
||||
<xs:sequence>
|
||||
<xs:any namespace='##other' processContents='lax' minOccurs='1' maxOccurs='1' />
|
||||
</xs:sequence>
|
||||
<xs:anyAttribute namespace='##other' processContents='lax' />
|
||||
</xs:complexType>
|
||||
|
||||
<xs:element name='ProofToken' type='tns:ProofTokenType' />
|
||||
<xs:complexType name='ProofTokenType' >
|
||||
<xs:sequence>
|
||||
<xs:any namespace='##other' processContents='lax' minOccurs='1' maxOccurs='1' />
|
||||
</xs:sequence>
|
||||
<xs:anyAttribute namespace='##other' processContents='lax' />
|
||||
</xs:complexType>
|
||||
|
||||
<!-- Section 7.1 -->
|
||||
<xs:element name='RequestPseudonym' type='tns:RequestPseudonymType' />
|
||||
<xs:complexType name='RequestPseudonymType' >
|
||||
<xs:sequence>
|
||||
<xs:any namespace='##other' processContents='lax' minOccurs='0' maxOccurs='unbounded' />
|
||||
</xs:sequence>
|
||||
<xs:attribute name='SingleUse' type='xs:boolean' use='optional' />
|
||||
<xs:attribute name='Lookup' type='xs:boolean' use='optional' />
|
||||
<xs:anyAttribute namespace='##other' processContents='lax' />
|
||||
</xs:complexType>
|
||||
|
||||
<!-- Section 8.1 -->
|
||||
<xs:element name='ReferenceToken' type='tns:ReferenceTokenType' />
|
||||
<xs:complexType name='ReferenceTokenType'>
|
||||
<xs:sequence>
|
||||
<xs:element name='ReferenceEPR' type='wsa:EndpointReferenceType' minOccurs='1' maxOccurs='unbounded' />
|
||||
<xs:element name='ReferenceDigest' type='tns:ReferenceDigestType' minOccurs='0' maxOccurs='1' />
|
||||
<xs:element name='ReferenceType' type='tns:AttributeExtensibleURI' minOccurs='0' maxOccurs='1' />
|
||||
<xs:element name='SerialNo' type='tns:AttributeExtensibleURI' minOccurs='0' maxOccurs='1' />
|
||||
<xs:any namespace='##other' processContents='lax' minOccurs='0' maxOccurs='unbounded' />
|
||||
</xs:sequence>
|
||||
<xs:anyAttribute namespace='##other' processContents='lax' />
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name='ReferenceDigestType' >
|
||||
<xs:simpleContent>
|
||||
<xs:extension base='xs:base64Binary' >
|
||||
<xs:anyAttribute namespace='##other' processContents='lax' />
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
<xs:complexType name='AttributeExtensibleURI' >
|
||||
<xs:simpleContent>
|
||||
<xs:extension base='xs:anyURI' >
|
||||
<xs:anyAttribute namespace='##other' processContents='lax' />
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
|
||||
<!-- Section 8.2 -->
|
||||
<xs:element name='FederationID' type='tns:AttributeExtensibleURI' />
|
||||
|
||||
<!-- Section 8.3 -->
|
||||
<xs:element name='RequestProofToken' type='tns:RequestProofTokenType' />
|
||||
<xs:complexType name='RequestProofTokenType' >
|
||||
<xs:sequence>
|
||||
<xs:any namespace='##any' processContents='lax' minOccurs='0' maxOccurs='unbounded' />
|
||||
</xs:sequence>
|
||||
<xs:anyAttribute namespace='##other' processContents='lax' />
|
||||
</xs:complexType>
|
||||
|
||||
<!-- Section 8.4 -->
|
||||
<xs:element name='ClientPseudonym' type='tns:ClientPseudonymType' />
|
||||
<xs:complexType name='ClientPseudonymType' >
|
||||
<xs:sequence>
|
||||
<xs:element name='PPID' type='tns:AttributeExtensibleString' minOccurs='0' />
|
||||
<xs:element name='DisplayName' type='tns:AttributeExtensibleString' minOccurs='0' />
|
||||
<xs:element name='EMail' type='tns:AttributeExtensibleString' minOccurs='0' />
|
||||
<xs:any namespace='##other' processContents='lax' minOccurs='0' maxOccurs='unbounded' />
|
||||
</xs:sequence>
|
||||
<xs:anyAttribute namespace='##other' processContents='lax' />
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name='AttributeExtensibleString' >
|
||||
<xs:simpleContent>
|
||||
<xs:extension base='xs:string' >
|
||||
<xs:anyAttribute namespace='##other' processContents='lax' />
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
|
||||
<!-- Section 8.5 -->
|
||||
<xs:element name='Freshness' type='tns:Freshness' />
|
||||
<xs:complexType name='Freshness'>
|
||||
<xs:simpleContent>
|
||||
<xs:extension base='xs:unsignedInt' >
|
||||
<xs:attribute name='AllowCache' type='xs:boolean' use='optional' />
|
||||
<xs:anyAttribute namespace='##other' processContents='lax' />
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
|
||||
<!-- Section 14.1 -->
|
||||
<xs:element name='RequireReferenceToken' type='sp:TokenAssertionType' />
|
||||
<xs:element name='ReferenceToken11' type='tns:AssertionType' />
|
||||
|
||||
<xs:complexType name='AssertionType' >
|
||||
<xs:sequence>
|
||||
<xs:any namespace='##any' processContents='lax' minOccurs='0' maxOccurs='unbounded' />
|
||||
</xs:sequence>
|
||||
<xs:anyAttribute namespace='##other' processContents='lax' />
|
||||
</xs:complexType>
|
||||
|
||||
<!-- Section 14.2 -->
|
||||
<xs:element name='WebBinding' type='sp:NestedPolicyType' />
|
||||
<xs:element name='AuthenticationToken' type='sp:NestedPolicyType' />
|
||||
<!-- ReferenceToken defined above -->
|
||||
<xs:element name='RequireSignedTokens' type='tns:AssertionType' />
|
||||
<xs:element name='RequireBearerTokens' type='tns:AssertionType' />
|
||||
<xs:element name='RequireSharedCookies' type='tns:AssertionType' />
|
||||
|
||||
|
||||
<!-- Section 14.3 -->
|
||||
<xs:element name='RequiresGenericClaimDialect' type='tns:AssertionType' />
|
||||
<xs:element name='IssuesSpecificPolicyFault' type='tns:AssertionType' />
|
||||
<xs:element name='AdditionalContextProcessed' type='tns:AssertionType' />
|
||||
|
||||
|
||||
</xs:schema>
|
||||
1205
schemas/ws-securitypolicy-1.2.xsd
Normal file
1205
schemas/ws-securitypolicy-1.2.xsd
Normal file
File diff suppressed because it is too large
Load Diff
451
schemas/ws-trust.xsd
Normal file
451
schemas/ws-trust.xsd
Normal file
@@ -0,0 +1,451 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
|
||||
Copyright Notice
|
||||
|
||||
(c) 2001-2005 Actional Corporation, BEA Systems, Inc.,
|
||||
Computer Associates International, Inc., International Business Machines Corporation,
|
||||
Layer 7 Technologies, Microsoft Corporation, Netegrity, Inc., Oblix Inc.,
|
||||
OpenNetwork Technologies Inc., Ping Identity Corporation, Reactivity Inc.,
|
||||
RSA Security Inc., and VeriSign Inc.
|
||||
All rights reserved.
|
||||
|
||||
Permission to copy and display the WS-Trust Specification (the "Specification", which
|
||||
includes WSDL and schema documents), in any medium without fee or royalty
|
||||
is hereby granted, provided that you include the following on ALL copies of the
|
||||
Specification, that you make:
|
||||
|
||||
1. A link or URL to the Specification at one of the Authors' websites
|
||||
2. The copyright notice as shown in the Specification.
|
||||
|
||||
IBM, Microsoft and Actional, BEA, Computer Associates, Layer 7, Netegrity, Oblix,
|
||||
OpenNetwork, Ping Identity, Reactivity, and Verisign (collectively, the "Authors") each
|
||||
agree to grant you a license, under royalty-free and otherwise reasonable,
|
||||
non-discriminatory terms and conditions, to their respective essential patent claims
|
||||
that they deem necessary to implement the Specification.
|
||||
|
||||
THE SPECIFICATION IS PROVIDED "AS IS," AND THE AUTHORS MAKE
|
||||
NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING, BUT
|
||||
NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE, NON-INFRINGEMENT, OR TITLE; THAT THE CONTENTS OF
|
||||
THE SPECIFICATION ARE SUITABLE FOR ANY PURPOSE; NOR THAT THE
|
||||
IMPLEMENTATION OF SUCH CONTENTS WILL NOT INFRINGE ANY THIRD PARTY
|
||||
PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
|
||||
|
||||
THE AUTHORS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL,
|
||||
INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR RELATING TO ANY
|
||||
USE OR DISTRIBUTION OF THE SPECIFICATION.
|
||||
|
||||
The name and trademarks of the Authors may NOT be used in any manner,
|
||||
including advertising or publicity pertaining to the Specification or
|
||||
its contents without specific, written prior permission. Title to
|
||||
copyright in the Specification will at all times remain with the Authors.
|
||||
|
||||
No other rights are granted by implication, estoppel or otherwise.
|
||||
|
||||
-->
|
||||
<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'
|
||||
xmlns:wsse='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd'
|
||||
xmlns:wsu='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd'
|
||||
xmlns:wsp='http://schemas.xmlsoap.org/ws/2004/09/policy'
|
||||
xmlns:wsa='http://schemas.xmlsoap.org/ws/2004/08/addressing'
|
||||
xmlns:wst='http://schemas.xmlsoap.org/ws/2005/02/trust'
|
||||
targetNamespace='http://schemas.xmlsoap.org/ws/2005/02/trust'
|
||||
elementFormDefault='qualified' >
|
||||
|
||||
<xs:import namespace='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd'
|
||||
schemaLocation='oasis-200401-wss-wssecurity-secext-1.0.xsd' />
|
||||
<xs:import namespace='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd'
|
||||
schemaLocation='oasis-200401-wss-wssecurity-utility-1.0.xsd' />
|
||||
<xs:import namespace='http://schemas.xmlsoap.org/ws/2004/09/policy'
|
||||
schemaLocation='http://schemas.xmlsoap.org/ws/2004/09/policy/ws-policy.xsd' />
|
||||
<xs:import namespace='http://schemas.xmlsoap.org/ws/2004/08/addressing'
|
||||
schemaLocation='ws-addr.xsd' />
|
||||
|
||||
<!-- WS-Trust Section 5.1 -->
|
||||
<xs:element name='RequestSecurityToken' type='wst:RequestSecurityTokenType' />
|
||||
<xs:complexType name='RequestSecurityTokenType' >
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
Actual content model is non-deterministic, hence wildcard. The following shows intended content model:
|
||||
|
||||
<xs:element ref='wst:TokenType' minOccurs='0' />
|
||||
<xs:element ref='wst:RequestType' />
|
||||
<xs:element ref='wsp:AppliesTo' minOccurs='0' />
|
||||
<xs:element ref='wst:Claims' minOccurs='0' />
|
||||
<xs:element ref='wst:Entropy' minOccurs='0' />
|
||||
<xs:element ref='wst:Lifetime' minOccurs='0' />
|
||||
<xs:element ref='wst:AllowPostdating' minOccurs='0' />
|
||||
<xs:element ref='wst:Renewing' minOccurs='0' />
|
||||
<xs:element ref='wst:OnBehalfOf' minOccurs='0' />
|
||||
<xs:element ref='wst:Issuer' minOccurs='0' />
|
||||
<xs:element ref='wst:AuthenticationType' minOccurs='0' />
|
||||
<xs:element ref='wst:KeyType' minOccurs='0' />
|
||||
<xs:element ref='wst:KeySize' minOccurs='0' />
|
||||
<xs:element ref='wst:SignatureAlgorithm' minOccurs='0' />
|
||||
<xs:element ref='wst:Encryption' minOccurs='0' />
|
||||
<xs:element ref='wst:EncryptionAlgorithm' minOccurs='0' />
|
||||
<xs:element ref='wst:CanonicalizationAlgorithm' minOccurs='0' />
|
||||
<xs:element ref='wst:ProofEncryption' minOccurs='0' />
|
||||
<xs:element ref='wst:UseKey' minOccurs='0' />
|
||||
<xs:element ref='wst:SignWith' minOccurs='0' />
|
||||
<xs:element ref='wst:EncryptWith' minOccurs='0' />
|
||||
<xs:element ref='wst:DelegateTo' minOccurs='0' />
|
||||
<xs:element ref='wst:Forwardable' minOccurs='0' />
|
||||
<xs:element ref='wst:Delegatable' minOccurs='0' />
|
||||
<xs:element ref='wsp:Policy' minOccurs='0' />
|
||||
<xs:element ref='wsp:PolicyReference' minOccurs='0' />
|
||||
<xs:any namespace='##other' processContents='lax' minOccurs='0' maxOccurs='unbounded' />
|
||||
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
<xs:sequence>
|
||||
<xs:any namespace='##any' processContents='lax' minOccurs='0' maxOccurs='unbounded' />
|
||||
</xs:sequence>
|
||||
<xs:attribute name='Context' type='xs:anyURI' use='optional' />
|
||||
<xs:anyAttribute namespace='##other' processContents='lax' />
|
||||
</xs:complexType>
|
||||
|
||||
<xs:element name='TokenType' type='xs:anyURI' />
|
||||
|
||||
<xs:element name='RequestType' type='wst:RequestTypeOpenEnum' />
|
||||
|
||||
<xs:simpleType name='RequestTypeOpenEnum' >
|
||||
<xs:union memberTypes='wst:RequestTypeEnum xs:anyURI' />
|
||||
</xs:simpleType>
|
||||
|
||||
<xs:simpleType name='RequestTypeEnum' >
|
||||
<xs:restriction base='xs:anyURI' >
|
||||
<xs:enumeration value='http://schemas.xmlsoap.org/ws/2005/02/trust/Issue' />
|
||||
<xs:enumeration value='http://schemas.xmlsoap.org/ws/2005/02/trust/Renew' />
|
||||
<xs:enumeration value='http://schemas.xmlsoap.org/ws/2005/02/trust/Cancel' />
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
|
||||
<!-- WS-Trust Section 5.2 -->
|
||||
<xs:element name='RequestSecurityTokenResponse' type='wst:RequestSecurityTokenResponseType' />
|
||||
<xs:complexType name='RequestSecurityTokenResponseType' >
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
Actual content model is non-deterministic, hence wildcard. The following shows intended content model:
|
||||
|
||||
<xs:element ref='wst:TokenType' minOccurs='0' />
|
||||
<xs:element ref='wst:RequestType' />
|
||||
<xs:element ref='wst:RequestedSecurityToken' minOccurs='0' />
|
||||
<xs:element ref='wsp:AppliesTo' minOccurs='0' />
|
||||
<xs:element ref='wst:RequestedAttachedReference' minOccurs='0' />
|
||||
<xs:element ref='wst:RequestedUnattachedReference' minOccurs='0' />
|
||||
<xs:element ref='wst:RequestedProofToken' minOccurs='0' />
|
||||
<xs:element ref='wst:Entropy' minOccurs='0' />
|
||||
<xs:element ref='wst:Lifetime' minOccurs='0' />
|
||||
<xs:element ref='wst:Status' minOccurs='0' />
|
||||
<xs:element ref='wst:AllowPostdating' minOccurs='0' />
|
||||
<xs:element ref='wst:Renewing' minOccurs='0' />
|
||||
<xs:element ref='wst:OnBehalfOf' minOccurs='0' />
|
||||
<xs:element ref='wst:Issuer' minOccurs='0' />
|
||||
<xs:element ref='wst:AuthenticationType' minOccurs='0' />
|
||||
<xs:element ref='wst:Authenticator' minOccurs='0' />
|
||||
<xs:element ref='wst:KeyType' minOccurs='0' />
|
||||
<xs:element ref='wst:KeySize' minOccurs='0' />
|
||||
<xs:element ref='wst:SignatureAlgorithm' minOccurs='0' />
|
||||
<xs:element ref='wst:Encryption' minOccurs='0' />
|
||||
<xs:element ref='wst:EncryptionAlgorithm' minOccurs='0' />
|
||||
<xs:element ref='wst:CanonicalizationAlgorithm' minOccurs='0' />
|
||||
<xs:element ref='wst:ProofEncryption' minOccurs='0' />
|
||||
<xs:element ref='wst:UseKey' minOccurs='0' />
|
||||
<xs:element ref='wst:SignWith' minOccurs='0' />
|
||||
<xs:element ref='wst:EncryptWith' minOccurs='0' />
|
||||
<xs:element ref='wst:DelegateTo' minOccurs='0' />
|
||||
<xs:element ref='wst:Forwardable' minOccurs='0' />
|
||||
<xs:element ref='wst:Delegatable' minOccurs='0' />
|
||||
<xs:element ref='wsp:Policy' minOccurs='0' />
|
||||
<xs:element ref='wsp:PolicyReference' minOccurs='0' />
|
||||
<xs:any namespace='##other' processContents='lax' minOccurs='0' maxOccurs='unbounded' />
|
||||
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
<xs:sequence>
|
||||
<xs:any namespace='##any' processContents='lax' minOccurs='0' maxOccurs='unbounded' />
|
||||
</xs:sequence>
|
||||
<xs:attribute name='Context' type='xs:anyURI' use='optional' />
|
||||
<xs:anyAttribute namespace='##other' processContents='lax' />
|
||||
</xs:complexType>
|
||||
|
||||
<xs:element name='RequestedSecurityToken' type='wst:RequestedSecurityTokenType' />
|
||||
<xs:complexType name='RequestedSecurityTokenType' >
|
||||
<xs:sequence>
|
||||
<xs:any namespace='##any' processContents='lax' />
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
|
||||
<!-- WS-Trust Section 5.3 -->
|
||||
<xs:element name='BinarySecret' type='wst:BinarySecretType' />
|
||||
<xs:complexType name='BinarySecretType' >
|
||||
<xs:simpleContent>
|
||||
<xs:extension base='xs:base64Binary' >
|
||||
<xs:attribute name='Type' type='wst:BinarySecretTypeOpenEnum' use='optional' />
|
||||
<xs:anyAttribute namespace='##other' processContents='lax' />
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:simpleType name='BinarySecretTypeEnum' >
|
||||
<xs:restriction base='xs:anyURI' >
|
||||
<xs:enumeration value='http://schemas.xmlsoap.org/ws/2005/02/trust/AsymmetricKey' />
|
||||
<xs:enumeration value='http://schemas.xmlsoap.org/ws/2005/02/trust/SymmetricKey' />
|
||||
<xs:enumeration value='http://schemas.xmlsoap.org/ws/2005/02/trust/Nonce' />
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
|
||||
<xs:simpleType name='BinarySecretTypeOpenEnum' >
|
||||
<xs:union memberTypes='wst:BinarySecretTypeEnum xs:anyURI' />
|
||||
</xs:simpleType>
|
||||
|
||||
|
||||
<!-- WS-Trust Section 6.1 -->
|
||||
<xs:element name='Claims' type='wst:ClaimsType' />
|
||||
<xs:complexType name='ClaimsType' >
|
||||
<xs:sequence>
|
||||
<xs:any namespace='##any' processContents='lax' minOccurs='0' maxOccurs='unbounded' />
|
||||
</xs:sequence>
|
||||
<xs:attribute name='Dialect' type='xs:anyURI' use='optional' />
|
||||
<xs:anyAttribute namespace='##other' processContents='lax' />
|
||||
</xs:complexType>
|
||||
|
||||
<xs:element name='Entropy' type='wst:EntropyType' />
|
||||
<xs:complexType name='EntropyType' >
|
||||
<xs:sequence>
|
||||
<xs:any namespace='##any' processContents='lax' minOccurs='0' maxOccurs='unbounded' />
|
||||
</xs:sequence>
|
||||
<xs:anyAttribute namespace='##other' processContents='lax' />
|
||||
</xs:complexType>
|
||||
|
||||
<xs:element name='Lifetime' type='wst:LifetimeType' />
|
||||
<xs:complexType name='LifetimeType' >
|
||||
<xs:sequence>
|
||||
<xs:element ref='wsu:Created' minOccurs='0' />
|
||||
<xs:element ref='wsu:Expires' minOccurs='0' />
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
|
||||
<!-- WS-Trust Section 6.2 -->
|
||||
<xs:element name='ComputedKey' type='wst:ComputedKeyOpenEnum' />
|
||||
<xs:simpleType name='ComputedKeyEnum' >
|
||||
<xs:restriction base='xs:anyURI' >
|
||||
<xs:enumeration value='http://schemas.xmlsoap.org/ws/2005/02/trust/CK/PSHA1' />
|
||||
<xs:enumeration value='http://schemas.xmlsoap.org/ws/2005/02/trust/CK/HASH' />
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
|
||||
<xs:simpleType name='ComputedKeyOpenEnum' >
|
||||
<xs:union memberTypes='wst:ComputedKeyEnum xs:anyURI' />
|
||||
</xs:simpleType>
|
||||
|
||||
<xs:element name='RequestedAttachedReference' type='wst:RequestedReferenceType' />
|
||||
<xs:element name='RequestedUnattachedReference' type='wst:RequestedReferenceType' />
|
||||
<xs:complexType name='RequestedReferenceType' >
|
||||
<xs:sequence>
|
||||
<xs:element ref='wsse:SecurityTokenReference' />
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:element name='RequestedProofToken' type='wst:RequestedProofTokenType' />
|
||||
<xs:complexType name='RequestedProofTokenType' >
|
||||
<xs:sequence>
|
||||
<xs:any namespace='##any' processContents='lax' />
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
|
||||
<!-- WS-Trust Section 6.3 -->
|
||||
<xs:element name='RequestSecurityTokenResponseCollection' type='wst:RequestSecurityTokenResponseCollectionType' />
|
||||
<xs:complexType name='RequestSecurityTokenResponseCollectionType' >
|
||||
<xs:sequence>
|
||||
<xs:element ref='wst:RequestSecurityTokenResponse' minOccurs='1' maxOccurs='unbounded' />
|
||||
</xs:sequence>
|
||||
<xs:anyAttribute namespace='##other' processContents='lax' />
|
||||
</xs:complexType>
|
||||
|
||||
<!-- WS-Trust Section 6.4 -->
|
||||
<xs:element name='IssuedTokens' type='wst:RequestSecurityTokenResponseCollectionType' />
|
||||
|
||||
<!-- WS-Trust Section 7 -->
|
||||
<xs:element name='RenewTarget' type='wst:RenewTargetType' />
|
||||
<xs:complexType name='RenewTargetType' >
|
||||
<xs:sequence>
|
||||
<xs:any namespace='##other' minOccurs='1' maxOccurs='1' />
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:element name='AllowPostdating' type='wst:AllowPostdatingType' />
|
||||
<xs:complexType name='AllowPostdatingType' />
|
||||
|
||||
<xs:element name='Renewing' type='wst:RenewingType' />
|
||||
<xs:complexType name='RenewingType' >
|
||||
<xs:attribute name='Allow' type='xs:boolean' use='optional' />
|
||||
<xs:attribute name='OK' type='xs:boolean' use='optional' />
|
||||
</xs:complexType>
|
||||
|
||||
<!-- WS-Trust Section 8 -->
|
||||
<xs:element name='CancelTarget' type='wst:CancelTargetType' />
|
||||
<xs:complexType name='CancelTargetType' >
|
||||
<xs:sequence>
|
||||
<xs:any namespace='##other' minOccurs='1' maxOccurs='1' />
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:element name='RequestedTokenCancelled' type='wst:RequestedTokenCancelledType' />
|
||||
<xs:complexType name='RequestedTokenCancelledType' />
|
||||
|
||||
<!-- WS-Trust Section 9 -->
|
||||
<xs:element name='Status' type='wst:StatusType' />
|
||||
<xs:complexType name='StatusType' >
|
||||
<xs:sequence>
|
||||
<xs:element name='Code' type='wst:StatusCodeOpenEnum' />
|
||||
<xs:element name='Reason' type='xs:string' minOccurs='0' />
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:simpleType name='StatusCodeEnum' >
|
||||
<xs:restriction base='xs:anyURI' >
|
||||
<xs:enumeration value='http://schemas.xmlsoap.org/ws/2005/02/trust/status/valid' />
|
||||
<xs:enumeration value='http://schemas.xmlsoap.org/ws/2005/02/trust/status/invalid' />
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
|
||||
<xs:simpleType name='StatusCodeOpenEnum' >
|
||||
<xs:union memberTypes='wst:StatusCodeEnum xs:anyURI' />
|
||||
</xs:simpleType>
|
||||
|
||||
<!-- WS-Trust Section 10.2 -->
|
||||
<xs:element name='SignChallenge' type='wst:SignChallengeType' />
|
||||
<xs:element name='SignChallengeResponse' type='wst:SignChallengeType' />
|
||||
<xs:complexType name='SignChallengeType' >
|
||||
<xs:sequence>
|
||||
<xs:element ref='wst:Challenge' />
|
||||
<xs:any namespace='##any' processContents='lax' minOccurs='0' maxOccurs='unbounded' />
|
||||
</xs:sequence>
|
||||
<xs:anyAttribute namespace='##any' processContents='lax' />
|
||||
</xs:complexType>
|
||||
|
||||
<xs:element name='Challenge' type='xs:string'/>
|
||||
|
||||
|
||||
<!-- WS-Trust Section 10.3 -->
|
||||
<xs:element name='BinaryExchange' type='wst:BinaryExchangeType' />
|
||||
<xs:complexType name='BinaryExchangeType' >
|
||||
<xs:simpleContent>
|
||||
<xs:extension base='xs:string' >
|
||||
<xs:attribute name='ValueType' type='xs:anyURI' use='required' />
|
||||
<xs:attribute name='EncodingType' type='xs:anyURI' use='required' />
|
||||
<xs:anyAttribute namespace='##other' processContents='lax' />
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
|
||||
<!-- WS-Trust Section 10.4 -->
|
||||
<xs:element name='RequestKET' type='wst:RequestKETType' />
|
||||
<xs:complexType name='RequestKETType' />
|
||||
|
||||
<xs:element name='KeyExchangeToken' type='wst:KeyExchangeTokenType' />
|
||||
<xs:complexType name='KeyExchangeTokenType' >
|
||||
<xs:sequence>
|
||||
<xs:any namespace='##any' processContents='lax' minOccurs='0' maxOccurs='unbounded' />
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
|
||||
<!-- WS-Trust Section 10.9 -->
|
||||
<xs:element name='Authenticator' type='wst:AuthenticatorType' />
|
||||
<xs:complexType name='AuthenticatorType' >
|
||||
<xs:sequence>
|
||||
<xs:element ref='wst:CombinedHash' minOccurs='0' />
|
||||
<xs:any namespace='##other' processContents='lax' minOccurs='0' maxOccurs='unbounded' />
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:element name='CombinedHash' type='xs:base64Binary' />
|
||||
|
||||
<!-- WS-Trust Section 11.1 -->
|
||||
<xs:element name='OnBehalfOf' type='wst:OnBehalfOfType' />
|
||||
<xs:complexType name='OnBehalfOfType' >
|
||||
<xs:sequence>
|
||||
<xs:any namespace='##any' processContents='lax' />
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:element name='Issuer' type='wsa:EndpointReferenceType' />
|
||||
|
||||
<!-- WS-Trust Section 11.2 -->
|
||||
<xs:element name='AuthenticationType' type='xs:anyURI' />
|
||||
|
||||
<xs:element name='KeyType' type='wst:KeyTypeOpenEnum' />
|
||||
<xs:simpleType name='KeyTypeEnum' >
|
||||
<xs:restriction base='xs:anyURI' >
|
||||
<xs:enumeration value='http://schemas.xmlsoap.org/ws/2005/02/trust/PublicKey' />
|
||||
<xs:enumeration value='http://schemas.xmlsoap.org/ws/2005/02/trust/SymmetricKey' />
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
|
||||
<xs:simpleType name='KeyTypeOpenEnum' >
|
||||
<xs:union memberTypes='wst:KeyTypeEnum xs:anyURI' />
|
||||
</xs:simpleType>
|
||||
|
||||
<xs:element name='KeySize' type='xs:unsignedInt' />
|
||||
|
||||
<xs:element name='SignatureAlgorithm' type='xs:anyURI' />
|
||||
<xs:element name='EncryptionAlgorithm' type='xs:anyURI' />
|
||||
<xs:element name='CanonicalizationAlgorithm' type='xs:anyURI' />
|
||||
<xs:element name='ComputedKeyAlgorithm' type='xs:anyURI' />
|
||||
|
||||
<xs:element name='Encryption' type='wst:EncryptionType' />
|
||||
<xs:complexType name='EncryptionType' >
|
||||
<xs:sequence>
|
||||
<xs:any namespace='##any' processContents='lax' />
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:element name='ProofEncryption' type='wst:ProofEncryptionType' />
|
||||
<xs:complexType name='ProofEncryptionType' >
|
||||
<xs:sequence>
|
||||
<xs:any namespace='##any' processContents='lax' />
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:element name='UseKey' type='wst:UseKeyType' />
|
||||
<xs:complexType name='UseKeyType' >
|
||||
<xs:sequence>
|
||||
<xs:any namespace='##any' processContents='lax' minOccurs='0' />
|
||||
</xs:sequence>
|
||||
<xs:attribute name='Sig' type='xs:anyURI' use='optional' />
|
||||
</xs:complexType>
|
||||
|
||||
<xs:element name='SignWith' type='xs:anyURI' />
|
||||
<xs:element name='EncryptWith' type='xs:anyURI' />
|
||||
|
||||
<!-- WS-Trust Section 11.3 -->
|
||||
<xs:element name='DelegateTo' type='wst:DelegateToType' />
|
||||
<xs:complexType name='DelegateToType' >
|
||||
<xs:sequence>
|
||||
<xs:any namespace='##any' processContents='lax' />
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:element name='Forwardable' type='xs:boolean' />
|
||||
<xs:element name='Delegatable' type='xs:boolean' />
|
||||
|
||||
<!-- WS-Trust Section 11.5 -->
|
||||
<xs:element name='Participants' type='wst:ParticipantsType' />
|
||||
<xs:complexType name='ParticipantsType' >
|
||||
<xs:sequence>
|
||||
<xs:element name='Primary' type='wst:ParticipantType' minOccurs='0' />
|
||||
<xs:element name='Participant' type='wst:ParticipantType' minOccurs='0' maxOccurs='unbounded' />
|
||||
<xs:any namespace='##other' processContents='lax' minOccurs='0' maxOccurs='unbounded' />
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name='ParticipantType' >
|
||||
<xs:sequence>
|
||||
<xs:any namespace='##any' processContents='lax' />
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
|
||||
</xs:schema>
|
||||
218
tests/e2e/test_provider_ws_fed.py
Normal file
218
tests/e2e/test_provider_ws_fed.py
Normal file
@@ -0,0 +1,218 @@
|
||||
"""test WSFed Provider flow"""
|
||||
|
||||
from json import dumps
|
||||
|
||||
from selenium.webdriver.common.by import By
|
||||
from selenium.webdriver.support import expected_conditions as ec
|
||||
|
||||
from authentik.blueprints.tests import apply_blueprint, reconcile_app
|
||||
from authentik.core.models import Application
|
||||
from authentik.core.tests.utils import create_test_cert
|
||||
from authentik.enterprise.providers.ws_federation.models import WSFederationProvider
|
||||
from authentik.flows.models import Flow
|
||||
from authentik.lib.generators import generate_id
|
||||
from authentik.providers.saml.models import SAMLPropertyMapping
|
||||
from tests.e2e.utils import SeleniumTestCase, retry
|
||||
|
||||
|
||||
class TestProviderWSFed(SeleniumTestCase):
|
||||
"""test WS Federation flow"""
|
||||
|
||||
def setup_client(self, provider: WSFederationProvider, app: Application, **kwargs):
|
||||
metadata_url = (
|
||||
self.url(
|
||||
"authentik_api:wsfederationprovider-metadata",
|
||||
pk=provider.pk,
|
||||
)
|
||||
+ "?download"
|
||||
)
|
||||
self.run_container(
|
||||
image="ghcr.io/beryju/wsfed-test-sp:v0.1.2",
|
||||
ports={
|
||||
"8080": "8080",
|
||||
},
|
||||
environment={
|
||||
"WSFED_TEST_SP_WTREALM": f"goauthentik.io://app/{app.slug}",
|
||||
"WSFED_TEST_SP_METADATA": metadata_url,
|
||||
**kwargs,
|
||||
},
|
||||
)
|
||||
|
||||
@retry()
|
||||
@apply_blueprint(
|
||||
"default/flow-default-authentication-flow.yaml",
|
||||
"default/flow-default-invalidation-flow.yaml",
|
||||
)
|
||||
@apply_blueprint(
|
||||
"default/flow-default-provider-authorization-implicit-consent.yaml",
|
||||
"default/flow-default-provider-invalidation.yaml",
|
||||
)
|
||||
@apply_blueprint(
|
||||
"system/providers-saml.yaml",
|
||||
)
|
||||
@reconcile_app("authentik_crypto")
|
||||
def test_sp_initiated_implicit(self):
|
||||
"""test WSFed Provider flow SP-initiated flow (implicit consent)"""
|
||||
# Bootstrap all needed objects
|
||||
authorization_flow = Flow.objects.get(
|
||||
slug="default-provider-authorization-implicit-consent"
|
||||
)
|
||||
invalidation_flow = Flow.objects.get(slug="default-provider-invalidation-flow")
|
||||
provider = WSFederationProvider.objects.create(
|
||||
name=generate_id(),
|
||||
acs_url="http://localhost:8080",
|
||||
authorization_flow=authorization_flow,
|
||||
invalidation_flow=invalidation_flow,
|
||||
signing_kp=create_test_cert(),
|
||||
)
|
||||
provider.property_mappings.set(SAMLPropertyMapping.objects.all())
|
||||
provider.save()
|
||||
app = Application.objects.create(
|
||||
name="WSFed",
|
||||
slug=generate_id(),
|
||||
provider=provider,
|
||||
)
|
||||
self.setup_client(provider, app)
|
||||
self.driver.get("http://localhost:8080")
|
||||
self.login()
|
||||
self.wait_for_url("http://localhost:8080/")
|
||||
|
||||
body = self.parse_json_content(self.driver.find_element(By.CSS_SELECTOR, "pre"))
|
||||
snippet = dumps(body, indent=2)[:500].replace("\n", " ")
|
||||
|
||||
self.assertEqual(
|
||||
body.get("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"),
|
||||
self.user.name,
|
||||
f"Claim 'name' mismatch at {self.driver.current_url}: {snippet}",
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
body.get("http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname"),
|
||||
self.user.username,
|
||||
f"Claim 'windowsaccountname' mismatch at {self.driver.current_url}: {snippet}",
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
body.get("http://schemas.goauthentik.io/2021/02/saml/username"),
|
||||
self.user.username,
|
||||
f"Claim 'saml/username' mismatch at {self.driver.current_url}: {snippet}",
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
body.get("http://schemas.goauthentik.io/2021/02/saml/uid"),
|
||||
str(self.user.pk),
|
||||
f"Claim 'saml/uid' mismatch at {self.driver.current_url}: {snippet}",
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
body.get("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"),
|
||||
self.user.email,
|
||||
f"Claim 'emailaddress' mismatch at {self.driver.current_url}: {snippet}",
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
body.get("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn"),
|
||||
self.user.email,
|
||||
f"Claim 'upn' mismatch at {self.driver.current_url}: {snippet}",
|
||||
)
|
||||
|
||||
self.driver.get("http://localhost:8080/Logout")
|
||||
should_url = self.url(
|
||||
"authentik_core:if-flow",
|
||||
flow_slug=invalidation_flow.slug,
|
||||
)
|
||||
self.wait.until(
|
||||
lambda driver: driver.current_url.startswith(should_url),
|
||||
f"URL {self.driver.current_url} doesn't match expected URL {should_url}",
|
||||
)
|
||||
|
||||
@retry()
|
||||
@apply_blueprint(
|
||||
"default/flow-default-authentication-flow.yaml",
|
||||
"default/flow-default-invalidation-flow.yaml",
|
||||
)
|
||||
@apply_blueprint(
|
||||
"default/flow-default-provider-authorization-explicit-consent.yaml",
|
||||
)
|
||||
@apply_blueprint(
|
||||
"system/providers-saml.yaml",
|
||||
)
|
||||
@reconcile_app("authentik_crypto")
|
||||
def test_sp_initiated_explicit(self):
|
||||
"""test WSFed Provider flow SP-initiated flow (explicit consent)"""
|
||||
# Bootstrap all needed objects
|
||||
authorization_flow = Flow.objects.get(
|
||||
slug="default-provider-authorization-explicit-consent"
|
||||
)
|
||||
provider = WSFederationProvider.objects.create(
|
||||
name=generate_id(),
|
||||
acs_url="http://localhost:8080",
|
||||
authorization_flow=authorization_flow,
|
||||
signing_kp=create_test_cert(),
|
||||
)
|
||||
provider.property_mappings.set(SAMLPropertyMapping.objects.all())
|
||||
provider.save()
|
||||
app = Application.objects.create(
|
||||
name="WSFed",
|
||||
slug=generate_id(),
|
||||
provider=provider,
|
||||
)
|
||||
self.setup_client(provider, app)
|
||||
self.driver.get("http://localhost:8080")
|
||||
self.login()
|
||||
|
||||
self.wait.until(ec.presence_of_element_located((By.CSS_SELECTOR, "ak-flow-executor")))
|
||||
|
||||
flow_executor = self.get_shadow_root("ak-flow-executor")
|
||||
consent_stage = self.get_shadow_root("ak-stage-consent", flow_executor)
|
||||
|
||||
self.assertIn(
|
||||
app.name,
|
||||
consent_stage.find_element(By.CSS_SELECTOR, "[data-test-id='stage-heading']").text,
|
||||
"Consent stage header mismatch",
|
||||
)
|
||||
consent_stage.find_element(
|
||||
By.CSS_SELECTOR,
|
||||
"[type=submit]",
|
||||
).click()
|
||||
|
||||
self.wait_for_url("http://localhost:8080/")
|
||||
|
||||
body = self.parse_json_content(self.driver.find_element(By.CSS_SELECTOR, "pre"))
|
||||
snippet = dumps(body, indent=2)[:500].replace("\n", " ")
|
||||
|
||||
self.assertEqual(
|
||||
body.get("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"),
|
||||
self.user.name,
|
||||
f"Claim 'name' mismatch at {self.driver.current_url}: {snippet}",
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
body.get("http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname"),
|
||||
self.user.username,
|
||||
f"Claim 'windowsaccountname' mismatch at {self.driver.current_url}: {snippet}",
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
body.get("http://schemas.goauthentik.io/2021/02/saml/username"),
|
||||
self.user.username,
|
||||
f"Claim 'saml/username' mismatch at {self.driver.current_url}: {snippet}",
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
body.get("http://schemas.goauthentik.io/2021/02/saml/uid"),
|
||||
str(self.user.pk),
|
||||
f"Claim 'saml/uid' mismatch at {self.driver.current_url}: {snippet}",
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
body.get("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"),
|
||||
self.user.email,
|
||||
f"Claim 'emailaddress' mismatch at {self.driver.current_url}: {snippet}",
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
body.get("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn"),
|
||||
self.user.email,
|
||||
f"Claim 'upn' mismatch at {self.driver.current_url}: {snippet}",
|
||||
)
|
||||
@@ -164,11 +164,20 @@ class SeleniumTestCase(DockerTestCase, StaticLiveServerTestCase):
|
||||
def wait_for_url(self, desired_url: str):
|
||||
"""Wait until URL is `desired_url`."""
|
||||
|
||||
self.wait.until(
|
||||
lambda driver: driver.current_url == desired_url,
|
||||
f"URL {self.driver.current_url} doesn't match expected URL {desired_url}. "
|
||||
f"HTML: {self.driver.page_source[:1000]}",
|
||||
)
|
||||
def waiter(driver: WebDriver):
|
||||
current = driver.current_url
|
||||
return current == desired_url
|
||||
|
||||
# We catch and re-throw the exception from `wait.until`, as we can supply it
|
||||
# an error message, however that message is evaluated when we call `.until()`,
|
||||
# not when the error is thrown, so the URL in the error message will be incorrect.
|
||||
try:
|
||||
self.wait.until(waiter)
|
||||
except TimeoutException as exc:
|
||||
raise TimeoutException(
|
||||
f"URL {self.driver.current_url} doesn't match expected URL {desired_url}. "
|
||||
f"HTML: {self.driver.page_source[:1000]}"
|
||||
) from exc
|
||||
|
||||
def url(self, view: str, query: dict | None = None, **kwargs) -> str:
|
||||
"""reverse `view` with `**kwargs` into full URL using live_server_url"""
|
||||
|
||||
6
web/authentik/sources/wsfed.svg
Normal file
6
web/authentik/sources/wsfed.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 23 23">
|
||||
<path fill="#000000" d="M1 1h10v10H1z"/>
|
||||
<path fill="#000000" d="M12 1h10v10H12z"/>
|
||||
<path fill="#000000" d="M1 12h10v10H1z"/>
|
||||
<path fill="#000000" d="M12 12h10v10H12z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 254 B |
@@ -6,7 +6,7 @@ import { ApplicationWizardProviderForm } from "./ApplicationWizardProviderForm.j
|
||||
import { type AkCryptoCertificateSearch } from "#admin/common/ak-crypto-certificate-search";
|
||||
import { renderForm } from "#admin/providers/saml/SAMLProviderFormForm";
|
||||
|
||||
import { SAMLBindingsEnum, SAMLProvider, SAMLProviderLogoutMethodEnum } from "@goauthentik/api";
|
||||
import { SAMLBindingsEnum, SAMLLogoutMethods, SAMLProvider } from "@goauthentik/api";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
import { customElement, state } from "@lit/reactive-element/decorators.js";
|
||||
@@ -26,18 +26,18 @@ export class ApplicationWizardProviderSamlForm extends ApplicationWizardProvider
|
||||
protected hasPostBinding = false;
|
||||
|
||||
@state()
|
||||
protected logoutMethod: string = SAMLProviderLogoutMethodEnum.FrontchannelIframe;
|
||||
protected logoutMethod: string = SAMLLogoutMethods.FrontchannelIframe;
|
||||
|
||||
get formValues() {
|
||||
const values = super.formValues;
|
||||
// If SLS binding is redirect, ensure logout method is not backchannel
|
||||
if (
|
||||
values.slsBinding === SAMLBindingsEnum.Redirect &&
|
||||
values.logoutMethod === SAMLProviderLogoutMethodEnum.Backchannel
|
||||
values.logoutMethod === SAMLLogoutMethods.Backchannel
|
||||
) {
|
||||
return {
|
||||
...values,
|
||||
logoutMethod: SAMLProviderLogoutMethodEnum.FrontchannelIframe,
|
||||
logoutMethod: SAMLLogoutMethods.FrontchannelIframe,
|
||||
};
|
||||
}
|
||||
return values;
|
||||
@@ -65,9 +65,9 @@ export class ApplicationWizardProviderSamlForm extends ApplicationWizardProvider
|
||||
// If switching to redirect binding, change logout method from backchannel if needed
|
||||
if (
|
||||
target.value === SAMLBindingsEnum.Redirect &&
|
||||
this.logoutMethod === SAMLProviderLogoutMethodEnum.Backchannel
|
||||
this.logoutMethod === SAMLLogoutMethods.Backchannel
|
||||
) {
|
||||
this.logoutMethod = SAMLProviderLogoutMethodEnum.FrontchannelIframe;
|
||||
this.logoutMethod = SAMLLogoutMethods.FrontchannelIframe;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import "#admin/providers/radius/RadiusProviderForm";
|
||||
import "#admin/providers/saml/SAMLProviderForm";
|
||||
import "#admin/providers/scim/SCIMProviderForm";
|
||||
import "#admin/providers/ssf/SSFProviderFormPage";
|
||||
import "#admin/providers/wsfed/WSFederationProviderForm";
|
||||
import "#elements/buttons/SpinnerButton/index";
|
||||
import "#elements/forms/DeleteBulkForm";
|
||||
import "#elements/forms/ModalForm";
|
||||
|
||||
@@ -8,6 +8,7 @@ import "#admin/providers/radius/RadiusProviderViewPage";
|
||||
import "#admin/providers/saml/SAMLProviderViewPage";
|
||||
import "#admin/providers/scim/SCIMProviderViewPage";
|
||||
import "#admin/providers/ssf/SSFProviderViewPage";
|
||||
import "#admin/providers/wsfed/WSFederationProviderViewPage";
|
||||
import "#elements/EmptyState";
|
||||
import "#elements/buttons/SpinnerButton/ak-spinner-button";
|
||||
|
||||
@@ -86,6 +87,8 @@ export class ProviderViewPage extends AKElement {
|
||||
></ak-provider-microsoft-entra-view>`;
|
||||
case "ak-provider-ssf-form":
|
||||
return html`<ak-provider-ssf-view ${spread(props)}></ak-provider-ssf-view>`;
|
||||
case "ak-provider-wsfed-form":
|
||||
return html`<ak-provider-wsfed-view ${spread(props)}></ak-provider-wsfed-view>`;
|
||||
default:
|
||||
return html`<p>Invalid provider type ${this.provider?.component}</p>`;
|
||||
}
|
||||
|
||||
@@ -5,12 +5,7 @@ import { DEFAULT_CONFIG } from "#common/api/config";
|
||||
import { type AkCryptoCertificateSearch } from "#admin/common/ak-crypto-certificate-search";
|
||||
import { BaseProviderForm } from "#admin/providers/BaseProviderForm";
|
||||
|
||||
import {
|
||||
ProvidersApi,
|
||||
SAMLBindingsEnum,
|
||||
SAMLProvider,
|
||||
SAMLProviderLogoutMethodEnum,
|
||||
} from "@goauthentik/api";
|
||||
import { ProvidersApi, SAMLBindingsEnum, SAMLLogoutMethods, SAMLProvider } from "@goauthentik/api";
|
||||
|
||||
import { customElement, state } from "lit/decorators.js";
|
||||
|
||||
@@ -26,8 +21,7 @@ export class SAMLProviderFormPage extends BaseProviderForm<SAMLProvider> {
|
||||
protected hasPostBinding = false;
|
||||
|
||||
@state()
|
||||
protected logoutMethod: SAMLProviderLogoutMethodEnum =
|
||||
SAMLProviderLogoutMethodEnum.FrontchannelIframe;
|
||||
protected logoutMethod: SAMLLogoutMethods = SAMLLogoutMethods.FrontchannelIframe;
|
||||
|
||||
public override reset(): void {
|
||||
super.reset();
|
||||
@@ -35,7 +29,7 @@ export class SAMLProviderFormPage extends BaseProviderForm<SAMLProvider> {
|
||||
this.hasSigningKp = false;
|
||||
this.hasSlsUrl = false;
|
||||
this.hasPostBinding = false;
|
||||
this.logoutMethod = SAMLProviderLogoutMethodEnum.FrontchannelIframe;
|
||||
this.logoutMethod = SAMLLogoutMethods.FrontchannelIframe;
|
||||
}
|
||||
|
||||
async loadInstance(pk: number): Promise<SAMLProvider> {
|
||||
@@ -45,8 +39,7 @@ export class SAMLProviderFormPage extends BaseProviderForm<SAMLProvider> {
|
||||
this.hasSigningKp = !!provider.signingKp;
|
||||
this.hasSlsUrl = !!provider.slsUrl;
|
||||
this.hasPostBinding = provider.slsBinding === SAMLBindingsEnum.Post;
|
||||
this.logoutMethod =
|
||||
provider.logoutMethod ?? SAMLProviderLogoutMethodEnum.FrontchannelIframe;
|
||||
this.logoutMethod = provider.logoutMethod ?? SAMLLogoutMethods.FrontchannelIframe;
|
||||
return provider;
|
||||
}
|
||||
|
||||
@@ -54,9 +47,9 @@ export class SAMLProviderFormPage extends BaseProviderForm<SAMLProvider> {
|
||||
// If SLS binding is redirect, ensure logout method is not backchannel
|
||||
if (
|
||||
data.slsBinding === SAMLBindingsEnum.Redirect &&
|
||||
data.logoutMethod === SAMLProviderLogoutMethodEnum.Backchannel
|
||||
data.logoutMethod === SAMLLogoutMethods.Backchannel
|
||||
) {
|
||||
data.logoutMethod = SAMLProviderLogoutMethodEnum.FrontchannelIframe;
|
||||
data.logoutMethod = SAMLLogoutMethods.FrontchannelIframe;
|
||||
}
|
||||
|
||||
if (this.instance) {
|
||||
@@ -92,15 +85,15 @@ export class SAMLProviderFormPage extends BaseProviderForm<SAMLProvider> {
|
||||
// If switching to redirect binding, change logout method from backchannel if needed
|
||||
if (
|
||||
target.value === SAMLBindingsEnum.Redirect &&
|
||||
this.logoutMethod === SAMLProviderLogoutMethodEnum.Backchannel
|
||||
this.logoutMethod === SAMLLogoutMethods.Backchannel
|
||||
) {
|
||||
this.logoutMethod = SAMLProviderLogoutMethodEnum.FrontchannelIframe;
|
||||
this.logoutMethod = SAMLLogoutMethods.FrontchannelIframe;
|
||||
}
|
||||
};
|
||||
|
||||
const setLogoutMethod = (ev: Event) => {
|
||||
const target = ev.target as HTMLInputElement;
|
||||
this.logoutMethod = target.value as SAMLProviderLogoutMethodEnum;
|
||||
this.logoutMethod = target.value as SAMLLogoutMethods;
|
||||
};
|
||||
|
||||
return renderForm({
|
||||
|
||||
@@ -22,10 +22,10 @@ import {
|
||||
PropertymappingsApi,
|
||||
PropertymappingsProviderSamlListRequest,
|
||||
SAMLBindingsEnum,
|
||||
SAMLLogoutMethods,
|
||||
SAMLNameIDPolicyEnum,
|
||||
SAMLPropertyMapping,
|
||||
SAMLProvider,
|
||||
SAMLProviderLogoutMethodEnum,
|
||||
ValidationError,
|
||||
} from "@goauthentik/api";
|
||||
|
||||
@@ -79,16 +79,16 @@ function renderHasSlsUrl(
|
||||
const logoutMethodOptions: RadioOption<string>[] = [
|
||||
{
|
||||
label: msg("Front-channel (Iframe)"),
|
||||
value: SAMLProviderLogoutMethodEnum.FrontchannelIframe,
|
||||
value: SAMLLogoutMethods.FrontchannelIframe,
|
||||
default: true,
|
||||
},
|
||||
{
|
||||
label: msg("Front-channel (Native)"),
|
||||
value: SAMLProviderLogoutMethodEnum.FrontchannelNative,
|
||||
value: SAMLLogoutMethods.FrontchannelNative,
|
||||
},
|
||||
{
|
||||
label: msg("Back-channel (POST)"),
|
||||
value: SAMLProviderLogoutMethodEnum.Backchannel,
|
||||
value: SAMLLogoutMethods.Backchannel,
|
||||
disabled: !hasPostBinding,
|
||||
},
|
||||
];
|
||||
|
||||
@@ -47,7 +47,7 @@ import PFList from "@patternfly/patternfly/components/List/list.css";
|
||||
import PFPage from "@patternfly/patternfly/components/Page/page.css";
|
||||
import PFGrid from "@patternfly/patternfly/layouts/Grid/grid.css";
|
||||
|
||||
interface SAMLPreviewAttribute {
|
||||
export interface SAMLPreviewAttribute {
|
||||
attributes: {
|
||||
Name: string;
|
||||
Value: string[];
|
||||
|
||||
372
web/src/admin/providers/wsfed/WSFederationProviderForm.ts
Normal file
372
web/src/admin/providers/wsfed/WSFederationProviderForm.ts
Normal file
@@ -0,0 +1,372 @@
|
||||
import "#admin/common/ak-crypto-certificate-search";
|
||||
import "#components/ak-text-input";
|
||||
import "#elements/ak-dual-select/ak-dual-select-dynamic-selected-provider";
|
||||
import "#elements/ak-dual-select/ak-dual-select-provider";
|
||||
import "#elements/forms/FormGroup";
|
||||
import "#elements/forms/HorizontalFormElement";
|
||||
import "#elements/forms/SearchSelect/index";
|
||||
import "#elements/utils/TimeDeltaHelp";
|
||||
import "#components/ak-radio-input";
|
||||
import "#components/ak-switch-input";
|
||||
import "#admin/common/ak-flow-search/ak-flow-search";
|
||||
import "#elements/forms/Radio";
|
||||
|
||||
import { DEFAULT_CONFIG } from "#common/api/config";
|
||||
|
||||
import AkCryptoCertificateSearch from "#admin/common/ak-crypto-certificate-search";
|
||||
import { BaseProviderForm } from "#admin/providers/BaseProviderForm";
|
||||
import {
|
||||
propertyMappingsProvider,
|
||||
propertyMappingsSelector,
|
||||
} from "#admin/providers/saml/SAMLProviderFormHelpers";
|
||||
import {
|
||||
digestAlgorithmOptions,
|
||||
signatureAlgorithmOptions,
|
||||
} from "#admin/providers/saml/SAMLProviderOptions";
|
||||
|
||||
import {
|
||||
FlowsInstancesListDesignationEnum,
|
||||
PropertymappingsApi,
|
||||
PropertymappingsProviderSamlListRequest,
|
||||
ProvidersApi,
|
||||
SAMLNameIDPolicyEnum,
|
||||
SAMLPropertyMapping,
|
||||
WSFederationProvider,
|
||||
} from "@goauthentik/api";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
import { html, nothing, TemplateResult } from "lit";
|
||||
import { customElement, state } from "lit/decorators.js";
|
||||
import { ifDefined } from "lit/directives/if-defined.js";
|
||||
|
||||
/**
|
||||
* Form page for SSF Authentication Method
|
||||
*
|
||||
* @element ak-provider-ssf-form
|
||||
*
|
||||
*/
|
||||
|
||||
@customElement("ak-provider-wsfed-form")
|
||||
export class WSFederationProviderForm extends BaseProviderForm<WSFederationProvider> {
|
||||
@state()
|
||||
protected hasSigningKp = false;
|
||||
|
||||
async loadInstance(pk: number): Promise<WSFederationProvider> {
|
||||
const provider = await new ProvidersApi(DEFAULT_CONFIG).providersWsfedRetrieve({
|
||||
id: pk,
|
||||
});
|
||||
this.hasSigningKp = !!provider.signingKp;
|
||||
return provider;
|
||||
}
|
||||
|
||||
async send(data: WSFederationProvider): Promise<WSFederationProvider> {
|
||||
if (this.instance) {
|
||||
return new ProvidersApi(DEFAULT_CONFIG).providersWsfedUpdate({
|
||||
id: this.instance.pk,
|
||||
wSFederationProviderRequest: data,
|
||||
});
|
||||
}
|
||||
return new ProvidersApi(DEFAULT_CONFIG).providersWsfedCreate({
|
||||
wSFederationProviderRequest: data,
|
||||
});
|
||||
}
|
||||
|
||||
renderForm(): TemplateResult {
|
||||
const provider = this.instance;
|
||||
|
||||
return html`<ak-text-input
|
||||
name="name"
|
||||
label=${msg("Provider Name")}
|
||||
placeholder=${msg("Type a provider name...")}
|
||||
spellcheck="false"
|
||||
value=${ifDefined(provider?.name)}
|
||||
required
|
||||
></ak-text-input>
|
||||
<ak-form-element-horizontal
|
||||
name="authorizationFlow"
|
||||
label=${msg("Authorization flow")}
|
||||
required
|
||||
>
|
||||
<ak-flow-search
|
||||
flowType=${FlowsInstancesListDesignationEnum.Authorization}
|
||||
.currentFlow=${this.instance?.authorizationFlow}
|
||||
required
|
||||
></ak-flow-search>
|
||||
<p class="pf-c-form__helper-text">
|
||||
${msg("Flow used when authorizing this this.instance?.")}
|
||||
</p>
|
||||
</ak-form-element-horizontal>
|
||||
<ak-form-group open label="${msg("Protocol settings")}">
|
||||
<div class="pf-c-form">
|
||||
<ak-text-input
|
||||
name="replyUrl"
|
||||
label=${msg("Reply URL")}
|
||||
placeholder=${msg("https://...")}
|
||||
input-hint="code"
|
||||
inputmode="url"
|
||||
value="${ifDefined(this.instance?.replyUrl)}"
|
||||
required
|
||||
></ak-text-input>
|
||||
</div>
|
||||
</ak-form-group>
|
||||
|
||||
<ak-form-group label="${msg("Advanced flow settings")}">
|
||||
<div class="pf-c-form">
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("Authentication flow")}
|
||||
name="authenticationFlow"
|
||||
>
|
||||
<ak-flow-search
|
||||
flowType=${FlowsInstancesListDesignationEnum.Authentication}
|
||||
.currentFlow=${this.instance?.authenticationFlow}
|
||||
></ak-flow-search>
|
||||
<p class="pf-c-form__helper-text">
|
||||
${msg(
|
||||
"Flow used when a user access this provider and is not authenticated.",
|
||||
)}
|
||||
</p>
|
||||
</ak-form-element-horizontal>
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("Invalidation flow")}
|
||||
name="invalidationFlow"
|
||||
required
|
||||
>
|
||||
<ak-flow-search
|
||||
flowType=${FlowsInstancesListDesignationEnum.Invalidation}
|
||||
.currentFlow=${this.instance?.invalidationFlow}
|
||||
defaultFlowSlug="default-provider-invalidation-flow"
|
||||
required
|
||||
></ak-flow-search>
|
||||
<p class="pf-c-form__helper-text">
|
||||
${msg("Flow used when logging out of this this.instance?.")}
|
||||
</p>
|
||||
</ak-form-element-horizontal>
|
||||
</div>
|
||||
</ak-form-group>
|
||||
|
||||
<ak-form-group label="${msg("Advanced protocol settings")}">
|
||||
<div class="pf-c-form">
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("Signing Certificate")}
|
||||
name="signingKp"
|
||||
>
|
||||
<ak-crypto-certificate-search
|
||||
.certificate=${this.instance?.signingKp}
|
||||
@input=${(ev: InputEvent) => {
|
||||
const target = ev.target as AkCryptoCertificateSearch;
|
||||
if (!target) return;
|
||||
this.hasSigningKp = !!target.selectedKeypair;
|
||||
}}
|
||||
singleton
|
||||
></ak-crypto-certificate-search>
|
||||
<p class="pf-c-form__helper-text">
|
||||
${msg(
|
||||
"Certificate used to sign outgoing Responses going to the Service this.instance?.",
|
||||
)}
|
||||
</p>
|
||||
</ak-form-element-horizontal>
|
||||
${this.hasSigningKp
|
||||
? html`<ak-switch-input
|
||||
name="signAssertion"
|
||||
label=${msg("Sign assertions")}
|
||||
?checked=${this.instance?.signAssertion ?? true}
|
||||
help=${msg(
|
||||
"When enabled, the assertion element of the SAML response will be signed.",
|
||||
)}
|
||||
>
|
||||
</ak-switch-input>
|
||||
<ak-switch-input
|
||||
name="signLogoutRequest"
|
||||
label=${msg("Sign logout requests")}
|
||||
?checked=${this.instance?.signLogoutRequest ?? false}
|
||||
help=${msg("When enabled, SAML logout requests will be signed.")}
|
||||
>
|
||||
</ak-switch-input>`
|
||||
: nothing}
|
||||
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("Encryption Certificate")}
|
||||
name="encryptionKp"
|
||||
>
|
||||
<ak-crypto-certificate-search
|
||||
.certificate=${this.instance?.encryptionKp}
|
||||
></ak-crypto-certificate-search>
|
||||
<p class="pf-c-form__helper-text">
|
||||
${msg(
|
||||
"When selected, assertions will be encrypted using this keypair.",
|
||||
)}
|
||||
</p>
|
||||
</ak-form-element-horizontal>
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("Property mappings")}
|
||||
name="propertyMappings"
|
||||
>
|
||||
<ak-dual-select-dynamic-selected
|
||||
.provider=${propertyMappingsProvider}
|
||||
.selector=${propertyMappingsSelector(this.instance?.propertyMappings)}
|
||||
available-label=${msg("Available User Property Mappings")}
|
||||
selected-label=${msg("Selected User Property Mappings")}
|
||||
></ak-dual-select-dynamic-selected>
|
||||
</ak-form-element-horizontal>
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("NameID Property Mapping")}
|
||||
name="nameIdMapping"
|
||||
>
|
||||
<ak-search-select
|
||||
.fetchObjects=${async (
|
||||
query?: string,
|
||||
): Promise<SAMLPropertyMapping[]> => {
|
||||
const args: PropertymappingsProviderSamlListRequest = {
|
||||
ordering: "saml_name",
|
||||
};
|
||||
if (query !== undefined) {
|
||||
args.search = query;
|
||||
}
|
||||
const items = await new PropertymappingsApi(
|
||||
DEFAULT_CONFIG,
|
||||
).propertymappingsProviderSamlList(args);
|
||||
return items.results;
|
||||
}}
|
||||
.renderElement=${(item: SAMLPropertyMapping): string => {
|
||||
return item.name;
|
||||
}}
|
||||
.value=${(
|
||||
item: SAMLPropertyMapping | undefined,
|
||||
): string | undefined => {
|
||||
return item?.pk;
|
||||
}}
|
||||
.selected=${(item: SAMLPropertyMapping): boolean => {
|
||||
return this.instance?.nameIdMapping === item.pk;
|
||||
}}
|
||||
blankable
|
||||
>
|
||||
</ak-search-select>
|
||||
<p class="pf-c-form__helper-text">
|
||||
${msg(
|
||||
"Configure how the NameID value will be created. When left empty, the NameIDPolicy of the incoming request will be respected.",
|
||||
)}
|
||||
</p>
|
||||
</ak-form-element-horizontal>
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("AuthnContextClassRef Property Mapping")}
|
||||
name="authnContextClassRefMapping"
|
||||
>
|
||||
<ak-search-select
|
||||
.fetchObjects=${async (
|
||||
query?: string,
|
||||
): Promise<SAMLPropertyMapping[]> => {
|
||||
const args: PropertymappingsProviderSamlListRequest = {
|
||||
ordering: "saml_name",
|
||||
};
|
||||
if (query !== undefined) {
|
||||
args.search = query;
|
||||
}
|
||||
const items = await new PropertymappingsApi(
|
||||
DEFAULT_CONFIG,
|
||||
).propertymappingsProviderSamlList(args);
|
||||
return items.results;
|
||||
}}
|
||||
.renderElement=${(item: SAMLPropertyMapping): string => {
|
||||
return item.name;
|
||||
}}
|
||||
.value=${(
|
||||
item: SAMLPropertyMapping | undefined,
|
||||
): string | undefined => {
|
||||
return item?.pk;
|
||||
}}
|
||||
.selected=${(item: SAMLPropertyMapping): boolean => {
|
||||
return this.instance?.authnContextClassRefMapping === item.pk;
|
||||
}}
|
||||
blankable
|
||||
>
|
||||
</ak-search-select>
|
||||
<p class="pf-c-form__helper-text">
|
||||
${msg(
|
||||
"Configure how the AuthnContextClassRef value will be created. When left empty, the AuthnContextClassRef will be set based on which authentication methods the user used to authenticate.",
|
||||
)}
|
||||
</p>
|
||||
</ak-form-element-horizontal>
|
||||
|
||||
<ak-text-input
|
||||
name="sessionValidNotOnOrAfter"
|
||||
label=${msg("Session valid not on or after")}
|
||||
value="${this.instance?.sessionValidNotOnOrAfter || "minutes=86400"}"
|
||||
required
|
||||
help=${msg("Session not valid on or after current time + this value.")}
|
||||
></ak-text-input>
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("Default NameID Policy")}
|
||||
required
|
||||
name="defaultNameIdPolicy"
|
||||
>
|
||||
<select class="pf-c-form-control">
|
||||
<option
|
||||
value=${SAMLNameIDPolicyEnum.UrnOasisNamesTcSaml20NameidFormatPersistent}
|
||||
?selected=${provider?.defaultNameIdPolicy ===
|
||||
SAMLNameIDPolicyEnum.UrnOasisNamesTcSaml20NameidFormatPersistent}
|
||||
>
|
||||
${msg("Persistent")}
|
||||
</option>
|
||||
<option
|
||||
value=${SAMLNameIDPolicyEnum.UrnOasisNamesTcSaml11NameidFormatEmailAddress}
|
||||
?selected=${provider?.defaultNameIdPolicy ===
|
||||
SAMLNameIDPolicyEnum.UrnOasisNamesTcSaml11NameidFormatEmailAddress}
|
||||
>
|
||||
${msg("Email address")}
|
||||
</option>
|
||||
<option
|
||||
value=${SAMLNameIDPolicyEnum.UrnOasisNamesTcSaml20NameidFormatWindowsDomainQualifiedName}
|
||||
?selected=${provider?.defaultNameIdPolicy ===
|
||||
SAMLNameIDPolicyEnum.UrnOasisNamesTcSaml20NameidFormatWindowsDomainQualifiedName}
|
||||
>
|
||||
${msg("Windows")}
|
||||
</option>
|
||||
<option
|
||||
value=${SAMLNameIDPolicyEnum.UrnOasisNamesTcSaml11NameidFormatX509SubjectName}
|
||||
?selected=${provider?.defaultNameIdPolicy ===
|
||||
SAMLNameIDPolicyEnum.UrnOasisNamesTcSaml11NameidFormatX509SubjectName}
|
||||
>
|
||||
${msg("X509 Subject")}
|
||||
</option>
|
||||
<option
|
||||
value=${SAMLNameIDPolicyEnum.UrnOasisNamesTcSaml20NameidFormatTransient}
|
||||
?selected=${provider?.defaultNameIdPolicy ===
|
||||
SAMLNameIDPolicyEnum.UrnOasisNamesTcSaml20NameidFormatTransient}
|
||||
>
|
||||
${msg("Transient")}
|
||||
</option>
|
||||
</select>
|
||||
<p class="pf-c-form__helper-text">
|
||||
${msg(
|
||||
"Configure the default NameID Policy used by IDP-initiated logins and when an incoming assertion doesn't specify a NameID Policy (also applies when using a custom NameID Mapping).",
|
||||
)}
|
||||
</p>
|
||||
</ak-form-element-horizontal>
|
||||
|
||||
<ak-radio-input
|
||||
name="digestAlgorithm"
|
||||
label=${msg("Digest algorithm")}
|
||||
.options=${digestAlgorithmOptions}
|
||||
.value=${this.instance?.digestAlgorithm}
|
||||
required
|
||||
>
|
||||
</ak-radio-input>
|
||||
|
||||
<ak-radio-input
|
||||
name="signatureAlgorithm"
|
||||
label=${msg("Signature algorithm")}
|
||||
.options=${signatureAlgorithmOptions}
|
||||
.value=${this.instance?.signatureAlgorithm}
|
||||
required
|
||||
>
|
||||
</ak-radio-input>
|
||||
</div>
|
||||
</ak-form-group> `;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ak-provider-wsfed-form": WSFederationProviderForm;
|
||||
}
|
||||
}
|
||||
511
web/src/admin/providers/wsfed/WSFederationProviderViewPage.ts
Normal file
511
web/src/admin/providers/wsfed/WSFederationProviderViewPage.ts
Normal file
@@ -0,0 +1,511 @@
|
||||
import "#admin/providers/RelatedApplicationButton";
|
||||
import "#admin/providers/wsfed/WSFederationProviderForm";
|
||||
import "#admin/rbac/ObjectPermissionsPage";
|
||||
import "#components/events/ObjectChangelog";
|
||||
import "#elements/CodeMirror";
|
||||
import "#elements/EmptyState";
|
||||
import "#elements/Tabs";
|
||||
import "#elements/buttons/ActionButton/index";
|
||||
import "#elements/buttons/ModalButton";
|
||||
import "#elements/buttons/SpinnerButton/index";
|
||||
|
||||
import { DEFAULT_CONFIG } from "#common/api/config";
|
||||
import { EVENT_REFRESH } from "#common/constants";
|
||||
import { MessageLevel } from "#common/messages";
|
||||
|
||||
import { AKElement } from "#elements/Base";
|
||||
import { showMessage } from "#elements/messages/MessageContainer";
|
||||
import { SlottedTemplateResult } from "#elements/types";
|
||||
|
||||
import renderDescriptionList from "#components/DescriptionList";
|
||||
|
||||
import { SAMLPreviewAttribute } from "#admin/providers/saml/SAMLProviderViewPage";
|
||||
|
||||
import {
|
||||
CertificateKeyPair,
|
||||
CoreApi,
|
||||
CoreUsersListRequest,
|
||||
CryptoApi,
|
||||
ProvidersApi,
|
||||
RbacPermissionsAssignedByRolesListModelEnum,
|
||||
SAMLMetadata,
|
||||
User,
|
||||
WSFederationProvider,
|
||||
} from "@goauthentik/api";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
import { CSSResult, html, nothing, PropertyValues, TemplateResult } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators.js";
|
||||
import { ifDefined } from "lit/directives/if-defined.js";
|
||||
|
||||
import PFBanner from "@patternfly/patternfly/components/Banner/banner.css";
|
||||
import PFButton from "@patternfly/patternfly/components/Button/button.css";
|
||||
import PFCard from "@patternfly/patternfly/components/Card/card.css";
|
||||
import PFContent from "@patternfly/patternfly/components/Content/content.css";
|
||||
import PFDescriptionList from "@patternfly/patternfly/components/DescriptionList/description-list.css";
|
||||
import PFForm from "@patternfly/patternfly/components/Form/form.css";
|
||||
import PFFormControl from "@patternfly/patternfly/components/FormControl/form-control.css";
|
||||
import PFList from "@patternfly/patternfly/components/List/list.css";
|
||||
import PFPage from "@patternfly/patternfly/components/Page/page.css";
|
||||
import PFGrid from "@patternfly/patternfly/layouts/Grid/grid.css";
|
||||
|
||||
@customElement("ak-provider-wsfed-view")
|
||||
export class WSFederationProviderViewPage extends AKElement {
|
||||
@property({ type: Number })
|
||||
public providerID: number | null = null;
|
||||
|
||||
@state()
|
||||
protected provider: WSFederationProvider | null = null;
|
||||
|
||||
@state()
|
||||
protected preview: SAMLPreviewAttribute | null = null;
|
||||
|
||||
@state()
|
||||
protected metadata: SAMLMetadata | null = null;
|
||||
|
||||
@state()
|
||||
protected signer: CertificateKeyPair | null = null;
|
||||
|
||||
@state()
|
||||
protected verifier: CertificateKeyPair | null = null;
|
||||
|
||||
@state()
|
||||
protected previewUser: User | null = null;
|
||||
|
||||
static styles: CSSResult[] = [
|
||||
PFButton,
|
||||
PFPage,
|
||||
PFGrid,
|
||||
PFContent,
|
||||
PFCard,
|
||||
PFList,
|
||||
PFDescriptionList,
|
||||
PFForm,
|
||||
PFFormControl,
|
||||
PFBanner,
|
||||
];
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.addEventListener(EVENT_REFRESH, () => {
|
||||
if (!this.provider?.pk) return;
|
||||
this.fetchProvider(this.provider.pk);
|
||||
});
|
||||
}
|
||||
|
||||
fetchPreview(): void {
|
||||
new ProvidersApi(DEFAULT_CONFIG)
|
||||
.providersWsfedPreviewUserRetrieve({
|
||||
id: this.provider?.pk || 0,
|
||||
forUser: this.previewUser?.pk,
|
||||
})
|
||||
.then((preview) => {
|
||||
this.preview = preview.preview as SAMLPreviewAttribute;
|
||||
});
|
||||
}
|
||||
|
||||
fetchCertificate(kpUuid: string) {
|
||||
return new CryptoApi(DEFAULT_CONFIG).cryptoCertificatekeypairsRetrieve({ kpUuid });
|
||||
}
|
||||
|
||||
fetchSigningCertificate(kpUuid: string) {
|
||||
this.fetchCertificate(kpUuid).then((kp) => {
|
||||
this.signer = kp;
|
||||
this.requestUpdate("signer");
|
||||
});
|
||||
}
|
||||
|
||||
fetchProvider(id: number) {
|
||||
new ProvidersApi(DEFAULT_CONFIG).providersWsfedRetrieve({ id }).then((prov) => {
|
||||
this.provider = prov;
|
||||
// Clear existing signing certificate if the provider has none
|
||||
if (!this.provider.signingKp) {
|
||||
this.signer = null;
|
||||
} else {
|
||||
this.fetchSigningCertificate(this.provider.signingKp);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected override willUpdate(changedProperties: PropertyValues<this>) {
|
||||
if (changedProperties.has("providerID") && this.providerID) {
|
||||
this.fetchProvider(this.providerID);
|
||||
}
|
||||
}
|
||||
|
||||
renderRelatedObjects(): TemplateResult {
|
||||
const relatedObjects = [];
|
||||
if (this.provider?.assignedApplicationName) {
|
||||
relatedObjects.push(
|
||||
html`<div class="pf-c-description-list__group">
|
||||
<dt class="pf-c-description-list__term">
|
||||
<span class="pf-c-description-list__text">${msg("Metadata")}</span>
|
||||
</dt>
|
||||
<dd class="pf-c-description-list__description">
|
||||
<div class="pf-c-description-list__text">
|
||||
<a
|
||||
class="pf-c-button pf-m-primary"
|
||||
target="_blank"
|
||||
href=${ifDefined(this.provider?.urlDownloadMetadata)}
|
||||
>
|
||||
${msg("Download")}
|
||||
</a>
|
||||
<ak-action-button
|
||||
class="pf-m-secondary"
|
||||
.apiRequest=${() => {
|
||||
if (!navigator.clipboard) {
|
||||
return Promise.resolve(
|
||||
showMessage({
|
||||
level: MessageLevel.info,
|
||||
message: this.provider?.urlDownloadMetadata || "",
|
||||
}),
|
||||
);
|
||||
}
|
||||
return navigator.clipboard.writeText(
|
||||
this.provider?.urlDownloadMetadata || "",
|
||||
);
|
||||
}}
|
||||
>
|
||||
${msg("Copy download URL")}
|
||||
</ak-action-button>
|
||||
</div>
|
||||
</dd>
|
||||
</div>`,
|
||||
);
|
||||
}
|
||||
if (this.signer) {
|
||||
relatedObjects.push(
|
||||
html`<div class="pf-c-description-list__group">
|
||||
<dt class="pf-c-description-list__term">
|
||||
<span class="pf-c-description-list__text"
|
||||
>${msg("Download signing certificate")}</span
|
||||
>
|
||||
</dt>
|
||||
<dd class="pf-c-description-list__description">
|
||||
<div class="pf-c-description-list__text">
|
||||
<a
|
||||
class="pf-c-button pf-m-primary"
|
||||
href=${this.signer.certificateDownloadUrl}
|
||||
>${msg("Download")}</a
|
||||
>
|
||||
</div>
|
||||
</dd>
|
||||
</div>`,
|
||||
);
|
||||
}
|
||||
return html` <div class="pf-c-card pf-l-grid__item pf-m-12-col">
|
||||
<div class="pf-c-card__title">${msg("Related objects")}</div>
|
||||
<div class="pf-c-card__body">
|
||||
<dl class="pf-c-description-list pf-m-2-col">
|
||||
${relatedObjects.length > 0 ? relatedObjects : html`-`}
|
||||
</dl>
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
render(): SlottedTemplateResult {
|
||||
if (!this.provider) {
|
||||
return nothing;
|
||||
}
|
||||
return html`<main part="main">
|
||||
<ak-tabs part="tabs">
|
||||
<div
|
||||
role="tabpanel"
|
||||
tabindex="0"
|
||||
slot="page-overview"
|
||||
id="page-overview"
|
||||
aria-label="${msg("Overview")}"
|
||||
>
|
||||
${this.renderTabOverview()}
|
||||
</div>
|
||||
${this.renderTabMetadata()}
|
||||
<div
|
||||
role="tabpanel"
|
||||
tabindex="0"
|
||||
slot="page-preview"
|
||||
id="page-preview"
|
||||
aria-label="${msg("Preview")}"
|
||||
@activate=${() => {
|
||||
this.fetchPreview();
|
||||
}}
|
||||
>
|
||||
${this.renderTabPreview()}
|
||||
</div>
|
||||
<div
|
||||
role="tabpanel"
|
||||
tabindex="0"
|
||||
slot="page-changelog"
|
||||
id="page-changelog"
|
||||
aria-label="${msg("Changelog")}"
|
||||
class="pf-c-page__main-section pf-m-no-padding-mobile"
|
||||
>
|
||||
<div class="pf-c-card">
|
||||
<div class="pf-c-card__body">
|
||||
<ak-object-changelog
|
||||
targetModelPk=${this.provider?.pk || ""}
|
||||
targetModelName=${this.provider?.metaModelName || ""}
|
||||
>
|
||||
</ak-object-changelog>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ak-rbac-object-permission-page
|
||||
role="tabpanel"
|
||||
tabindex="0"
|
||||
slot="page-permissions"
|
||||
id="page-permissions"
|
||||
aria-label="${msg("Permissions")}"
|
||||
model=${RbacPermissionsAssignedByRolesListModelEnum.AuthentikProvidersWsFederationWsfederationprovider}
|
||||
objectPk=${this.provider.pk}
|
||||
></ak-rbac-object-permission-page>
|
||||
</ak-tabs>
|
||||
</main>`;
|
||||
}
|
||||
|
||||
renderTabOverview(): SlottedTemplateResult {
|
||||
if (!this.provider) {
|
||||
return nothing;
|
||||
}
|
||||
return html`${
|
||||
this.provider?.assignedApplicationName
|
||||
? nothing
|
||||
: html`<div slot="header" class="pf-c-banner pf-m-warning">
|
||||
${msg("Warning: Provider is not used by an Application.")}
|
||||
</div>`
|
||||
}
|
||||
<div class="pf-c-page__main-section pf-m-no-padding-mobile pf-l-grid pf-m-gutter">
|
||||
<div class="pf-c-card pf-l-grid__item pf-m-12-col">
|
||||
<div class="pf-c-card__body">
|
||||
${renderDescriptionList(
|
||||
[
|
||||
[msg("Name"), this.provider.name],
|
||||
[
|
||||
msg("Assigned to application"),
|
||||
html`<ak-provider-related-application
|
||||
.provider=${this.provider}
|
||||
></ak-provider-related-application>`,
|
||||
],
|
||||
[msg("Reply URL"), this.provider.replyUrl],
|
||||
],
|
||||
{ threecolumn: true },
|
||||
)}
|
||||
</div>
|
||||
<div class="pf-c-card__footer">
|
||||
<ak-forms-modal>
|
||||
<span slot="submit">${msg("Update")}</span>
|
||||
<span slot="header">${msg("Update WS-Federation Provider")}</span>
|
||||
<ak-provider-wsfed-form slot="form" .instancePk=${this.provider.pk || 0}>
|
||||
</ak-provider-wsfed-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-primary">
|
||||
${msg("Edit")}
|
||||
</button>
|
||||
</ak-forms-modal>
|
||||
</div>
|
||||
</div>
|
||||
${this.renderRelatedObjects()}
|
||||
${
|
||||
this.provider.assignedApplicationName
|
||||
? html` <div class="pf-c-card pf-l-grid__item pf-m-12-col">
|
||||
<div class="pf-c-card__title">
|
||||
${msg("WS-Federation Configuration")}
|
||||
</div>
|
||||
<div class="pf-c-card__body">
|
||||
<form class="pf-c-form">
|
||||
<div class="pf-c-form__group">
|
||||
<label class="pf-c-form__label">
|
||||
<span class="pf-c-form__label-text"
|
||||
>${msg("WS-Federation URL")}</span
|
||||
>
|
||||
</label>
|
||||
<input
|
||||
class="pf-c-form-control"
|
||||
readonly
|
||||
type="text"
|
||||
value="${ifDefined(this.provider.urlWsfed)}"
|
||||
/>
|
||||
</div>
|
||||
<div class="pf-c-form__group">
|
||||
<label class="pf-c-form__label">
|
||||
<span class="pf-c-form__label-text"
|
||||
>${msg("Realm (wtrealm)")}</span
|
||||
>
|
||||
</label>
|
||||
<input
|
||||
class="pf-c-form-control"
|
||||
readonly
|
||||
type="text"
|
||||
value="${ifDefined(this.provider.wtrealm)}"
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>`
|
||||
: nothing
|
||||
}
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
renderTabMetadata(): SlottedTemplateResult {
|
||||
if (!this.provider) {
|
||||
return nothing;
|
||||
}
|
||||
return html`
|
||||
${this.provider.assignedApplicationName
|
||||
? html` <div
|
||||
role="tabpanel"
|
||||
tabindex="0"
|
||||
slot="page-metadata"
|
||||
id="page-metadata"
|
||||
aria-label="${msg("Metadata")}"
|
||||
@activate=${() => {
|
||||
new ProvidersApi(DEFAULT_CONFIG)
|
||||
.providersWsfedMetadataRetrieve({
|
||||
id: this.provider?.pk || 0,
|
||||
})
|
||||
.then((metadata) => (this.metadata = metadata));
|
||||
}}
|
||||
>
|
||||
<div
|
||||
class="pf-c-page__main-section pf-m-no-padding-mobile pf-l-grid pf-m-gutter"
|
||||
>
|
||||
<div class="pf-c-card pf-l-grid__item pf-m-12-col">
|
||||
<div class="pf-c-card__title">${msg("WS-Federation Metadata")}</div>
|
||||
<div class="pf-c-card__body">
|
||||
<a
|
||||
class="pf-c-button pf-m-primary"
|
||||
target="_blank"
|
||||
href=${this.provider.urlDownloadMetadata}
|
||||
>
|
||||
${msg("Download")}
|
||||
</a>
|
||||
<ak-action-button
|
||||
class="pf-m-secondary"
|
||||
.apiRequest=${() => {
|
||||
if (!navigator.clipboard) {
|
||||
return Promise.resolve(
|
||||
showMessage({
|
||||
level: MessageLevel.info,
|
||||
message:
|
||||
this.provider?.urlDownloadMetadata || "",
|
||||
}),
|
||||
);
|
||||
}
|
||||
return navigator.clipboard.writeText(
|
||||
this.provider?.urlDownloadMetadata || "",
|
||||
);
|
||||
}}
|
||||
>
|
||||
${msg("Copy download URL")}
|
||||
</ak-action-button>
|
||||
</div>
|
||||
<div class="pf-c-card__footer">
|
||||
<ak-codemirror
|
||||
mode="xml"
|
||||
readonly
|
||||
value="${ifDefined(this.metadata?.metadata)}"
|
||||
></ak-codemirror>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>`
|
||||
: nothing}
|
||||
`;
|
||||
}
|
||||
|
||||
renderTabPreview(): SlottedTemplateResult {
|
||||
if (!this.preview) {
|
||||
return html`<ak-empty-state loading></ak-empty-state>`;
|
||||
}
|
||||
return html` <div
|
||||
class="pf-c-page__main-section pf-m-no-padding-mobile pf-l-grid pf-m-gutter"
|
||||
>
|
||||
<div class="pf-c-card">
|
||||
<div class="pf-c-card__title">${msg("Example WS-Federation attributes")}</div>
|
||||
<div class="pf-c-card__body">
|
||||
${renderDescriptionList([
|
||||
[
|
||||
msg("Preview for user"),
|
||||
html`
|
||||
<ak-search-select
|
||||
.fetchObjects=${async (query?: string): Promise<User[]> => {
|
||||
const args: CoreUsersListRequest = {
|
||||
ordering: "username",
|
||||
};
|
||||
if (query !== undefined) {
|
||||
args.search = query;
|
||||
}
|
||||
const users = await new CoreApi(
|
||||
DEFAULT_CONFIG,
|
||||
).coreUsersList(args);
|
||||
return users.results;
|
||||
}}
|
||||
.renderElement=${(user: User): string => {
|
||||
return user.username;
|
||||
}}
|
||||
.renderDescription=${(user: User): TemplateResult => {
|
||||
return html`${user.name}`;
|
||||
}}
|
||||
.value=${(user: User | undefined): number | undefined => {
|
||||
return user?.pk;
|
||||
}}
|
||||
.selected=${(user: User): boolean => {
|
||||
return user.pk === this.previewUser?.pk;
|
||||
}}
|
||||
blankable
|
||||
@ak-change=${(ev: CustomEvent) => {
|
||||
this.previewUser = ev.detail.value;
|
||||
this.fetchPreview();
|
||||
}}
|
||||
>
|
||||
</ak-search-select>
|
||||
`,
|
||||
],
|
||||
])}
|
||||
</div>
|
||||
<div class="pf-c-card__body">
|
||||
<dl class="pf-c-description-list pf-m-2-col-on-lg">
|
||||
<div class="pf-c-description-list__group">
|
||||
<dt class="pf-c-description-list__term">
|
||||
<span class="pf-c-description-list__text"
|
||||
>${msg("NameID attribute")}</span
|
||||
>
|
||||
</dt>
|
||||
<dd class="pf-c-description-list__description">
|
||||
<div class="pf-c-description-list__text">
|
||||
${this.preview?.nameID}
|
||||
</div>
|
||||
</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="pf-c-card__body">
|
||||
<dl class="pf-c-description-list pf-m-2-col-on-lg">
|
||||
${this.preview?.attributes.map((attr) => {
|
||||
return html` <div class="pf-c-description-list__group">
|
||||
<dt class="pf-c-description-list__term">
|
||||
<span class="pf-c-description-list__text">${attr.Name}</span>
|
||||
</dt>
|
||||
<dd class="pf-c-description-list__description">
|
||||
<div class="pf-c-description-list__text">
|
||||
<ul class="pf-c-list">
|
||||
${attr.Value.map((value) => {
|
||||
return html` <li><pre>${value}</pre></li> `;
|
||||
})}
|
||||
</ul>
|
||||
</div>
|
||||
</dd>
|
||||
</div>`;
|
||||
})}
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ak-provider-wsfed-view": WSFederationProviderViewPage;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user