/** * @param SamlToken|TokenInterface $token * @return TokenInterface|void */ public function authenticate(TokenInterface $token) { $translatedAssertion = $this->attributeDictionary->translate($token->assertion); $nameId = $translatedAssertion->getNameID(); $institution = $translatedAssertion->getAttribute('schacHomeOrganization'); $identity = $this->identityService->findByNameIdAndInstitution($nameId, $institution); // if no identity can be found, we're done. if ($identity === null) { throw new BadCredentialsException('Unable to find Identity matching the criteria. Has the identity been registered before?'); } $raCredentials = $this->identityService->getRaCredentials($identity); // if no credentials can be found, we're done. if (!$raCredentials) { throw new BadCredentialsException('The Identity is not registered as (S)RA(A) and therefor does not have access to this application'); } // determine the role based on the credentials given $roles = []; if ($raCredentials->isSraa) { $roles[] = 'ROLE_SRAA'; } if ($raCredentials->isRaa) { $roles[] = 'ROLE_RAA'; } else { $roles[] = 'ROLE_RA'; } // set the token $authenticatedToken = new SamlToken($token->getLoa(), $roles); $authenticatedToken->setUser($identity); return $authenticatedToken; }
/** * @param SamlToken $token * @return TokenInterface|void */ public function authenticate(TokenInterface $token) { $translatedAssertion = $this->attributeDictionary->translate($token->assertion); $nameId = $translatedAssertion->getNameID(); $institution = $translatedAssertion->getAttribute('schacHomeOrganization'); $email = $translatedAssertion->getAttribute('mail'); $commonName = $translatedAssertion->getAttribute('commonName'); $identity = $this->identityService->findByNameIdAndInstitution($nameId, $institution); if ($identity === null) { $identity = new Identity(); $identity->id = Uuid::generate(); $identity->nameId = $nameId; $identity->institution = $institution; $identity->email = $email; $identity->commonName = $commonName; $identity->preferredLocale = $this->preferredLocaleProvider->providePreferredLocale(); $this->identityService->createIdentity($identity); } elseif ($identity->email !== $email || $identity->commonName !== $commonName) { $identity->email = $email; $identity->commonName = $commonName; $this->identityService->updateIdentity($identity); } $authenticatedToken = new SamlToken(['ROLE_USER']); $authenticatedToken->setUser($identity); return $authenticatedToken; }
public static function createFrom(SAML2_Assertion $assertion, AttributeDictionary $attributeDictionary) { $attributeSet = new AttributeSet(); foreach ($assertion->getAttributes() as $urn => $attributeValue) { $attribute = new Attribute($attributeDictionary->getAttributeDefinitionByUrn($urn), $attributeValue); $attributeSet->initializeWith($attribute); } return $attributeSet; }
/** * @test * @group AttributeDictionary */ public function finds_definition_when_urn_matches_urn_oid() { $oidAttributeUrn = 'urn:oid:0.0.0.0.0.0.0.0.0'; $existingOidAttributeDefinition = new AttributeDefinition('existingOidAttribute', 'urn:mace:some:attribute', $oidAttributeUrn); $attributeDictionary = new AttributeDictionary(); $attributeDictionary->addAttributeDefinition($existingOidAttributeDefinition); $foundDefinition = $attributeDictionary->findAttributeDefinitionByUrn($oidAttributeUrn); $this->assertSame($existingOidAttributeDefinition, $foundDefinition, 'Expected to find an attribute definition, but found none'); }
/** * @param string $attributeName the name of the attribute to attempt to get the value of * @param mixed $defaultValue the value to return should the assertion not contain the attribute * @return string[]|mixed string[] if the attribute is found, the given default value otherwise */ public function getAttributeValue($attributeName, $defaultValue = null) { $attributeDefinition = $this->attributeDictionary->getAttributeDefinition($attributeName); if (!$this->attributeSet->containsAttributeDefinedBy($attributeDefinition)) { return $defaultValue; } $attribute = $this->attributeSet->getAttributeByDefinition($attributeDefinition); return $attribute->getValue(); }
public function authenticate(TokenInterface $token) { ConfigurableAttributeSetFactory::configureWhichAttributeSetToCreate(AttributeSetWithFallbacks::class); $translatedAssertion = $this->attributeDictionary->translate($token->assertion); $authenticatingAuthorities = array_map(function ($authenticatingAuthority) { return new EntityId($authenticatingAuthority); }, $token->assertion->getAuthenticatingAuthority()); $user = AuthenticatedUser::createFrom($translatedAssertion, $authenticatingAuthorities); $authenticatedToken = new SamlToken(['ROLE_USER']); $authenticatedToken->setUser($user); return $authenticatedToken; }
/** * @test * @group AttributeSet * @group AttributeDictionary */ public function attribute_set_with_fallbacks_contains_an_attribute_with_an_existing_definition() { $attributeMaceUrn = 'urn:mace:some-attribute'; $attributeValue = ['someValue']; $attributeDefinition = new AttributeDefinition('some-attribute', $attributeMaceUrn); $assertion = Mockery::mock(SAML2_Assertion::class); $assertion->shouldReceive('getAttributes')->andReturn([$attributeMaceUrn => $attributeValue]); $dictionary = new AttributeDictionary(); $dictionary->addAttributeDefinition($attributeDefinition); $attributeSet = AttributeSetWithFallbacks::createFrom($assertion, $dictionary); $attributeIsInSet = $attributeSet->contains(new Attribute($attributeDefinition, $attributeValue)); $this->assertTrue($attributeIsInSet); }
public static function createFrom(SAML2_Assertion $assertion, AttributeDictionary $attributeDictionary) { $attributeSet = new AttributeSetWithFallbacks(); foreach ($assertion->getAttributes() as $urn => $attributeValue) { try { $attributeDefinition = $attributeDictionary->getAttributeDefinitionByUrn($urn); } catch (UnknownUrnException $exception) { $attributeDefinition = new AttributeDefinition($urn, $urn, $urn); } $attributeSet->initializeWith(new Attribute($attributeDefinition, $attributeValue)); } return $attributeSet; }
/** * @test * @group AttributeReleasePolicy */ public function consent_list_and_attributes_are_correctly_converted_to_a_request_and_the_response_is_mapped_correctly_to_a_result() { $someAttributeDefinition = new AttributeDefinition('someAttribute', 'urn:mace:some-attribute', 'urn:oid:0.0.0.0.0.1'); $anotherAttributeDefinition = new AttributeDefinition('anotherAttribute', null, 'urn:oid:0.0.0.0.0.2'); $attributeDictionary = new AttributeDictionary(); $attributeDictionary->addAttributeDefinition($someAttributeDefinition); $attributeDictionary->addAttributeDefinition($anotherAttributeDefinition); $client = Mockery::mock(JsonApiClient::class); $arpService = new AttributeReleasePolicyService($client, $attributeDictionary); $client->shouldReceive('post')->withArgs([['entityIds' => ['some-entity-id', 'another-entity-id'], 'attributes' => ['urn:mace:some-attribute' => ['some-value'], 'urn:oid:0.0.0.0.0.1' => ['some-value'], 'urn:oid:0.0.0.0.0.2' => ['another-value']]], '/arp'])->andReturn(['some-entity-id' => ['urn:mace:some-attribute' => ['some-value'], 'urn:oid:0.0.0.0.0.1' => ['some-value'], 'urn:oid:0.0.0.0.0.2' => ['another-value']], 'another-entity-id' => ['urn:oid:0.0.0.0.0.2' => ['another-value']]]); $someConsent = new Consent(new ServiceProvider(new Entity(new EntityId('some-entity-id'), EntityType::SP()), new DisplayName(['en' => 'Some display name']), new Url('http://some-eula-url.example'), new ContactEmailAddress('*****@*****.**')), new DateTimeImmutable(), new DateTimeImmutable(), ConsentType::explicit()); $anotherConsent = new Consent(new ServiceProvider(new Entity(new EntityId('another-entity-id'), EntityType::SP()), new DisplayName(['en' => 'Another display name']), new Url('http://another-eula-url.example'), new ContactEmailAddress('*****@*****.**')), new DateTimeImmutable(), new DateTimeImmutable(), ConsentType::explicit()); $consentList = new ConsentList([$someConsent, $anotherConsent]); $someAttribute = new Attribute($someAttributeDefinition, ['some-value']); $anotherAttribute = new Attribute($anotherAttributeDefinition, ['another-value']); $attributeSet = AttributeSet::create([$someAttribute, $anotherAttribute]); $expectedResult = SpecifiedConsentList::createWith([SpecifiedConsent::specifies($someConsent, AttributeSetWithFallbacks::create([$someAttribute, $anotherAttribute])), SpecifiedConsent::specifies($anotherConsent, AttributeSetWithFallbacks::create([$anotherAttribute]))]); $result = $arpService->applyAttributeReleasePolicies($consentList, $attributeSet); $this->assertEquals($expectedResult, $result); }
/** * @param ConsentList $consentList * @param AttributeSetInterface $attributeSet * @return SpecifiedConsentList * @SuppressWarnings(PHPMD.NPathComplexity) Build and mapping logic causes complexity */ public function applyAttributeReleasePolicies(ConsentList $consentList, AttributeSetInterface $attributeSet) { $entityIds = $consentList->map(function (Consent $consent) { return $consent->getServiceProvider()->getEntity()->getEntityId()->getEntityId(); }); $mappedAttributes = []; foreach ($attributeSet as $attribute) { $mace = $attribute->getAttributeDefinition()->getUrnMace(); $oid = $attribute->getAttributeDefinition()->getUrnOid(); if ($mace !== null) { $mappedAttributes[$mace] = $attribute->getValue(); } if ($oid !== null) { $mappedAttributes[$oid] = $attribute->getValue(); } } $data = ['entityIds' => $entityIds, 'attributes' => !empty($mappedAttributes) ? $mappedAttributes : new stdClass()]; $response = $this->jsonApiClient->post($data, '/arp'); $specifiedConsents = $consentList->map(function (Consent $consent) use($response) { $entityId = $consent->getServiceProvider()->getEntity()->getEntityId()->getEntityId(); if (!isset($response[$entityId])) { throw new InvalidResponseException(sprintf('EntityID "%s" was not found in the ARP response (entityIDs: %s)', $entityId, join(', ', array_keys($response)))); } $attributes = []; foreach ($response[$entityId] as $attributeName => $attributeValue) { try { $attributeDefinition = $this->attributeDictionary->getAttributeDefinitionByUrn($attributeName); } catch (UnknownUrnException $exception) { $attributeDefinition = new AttributeDefinition($attributeName, $attributeName, $attributeName); } $attribute = new Attribute($attributeDefinition, $attributeValue); if (!in_array($attribute, $attributes)) { $attributes[] = $attribute; } } return SpecifiedConsent::specifies($consent, AttributeSetWithFallbacks::create($attributes)); }); return SpecifiedConsentList::createWith($specifiedConsents); }
/** * Attempt to get an attribute from the assertion. * * @param string $name * @param null $default * @return mixed|null */ public function getAttribute($name, $default = null) { $attributeDefinition = $this->attributeDictionary->getAttributeDefinition($name); // try first by urn:mace, then by urn:oid if ($this->assertionAttributes->has($attributeDefinition->getUrnMace())) { $attribute = $this->assertionAttributes->get($attributeDefinition->getUrnMace()); } elseif ($this->assertionAttributes->has($attributeDefinition->getUrnOid())) { $attribute = $this->assertionAttributes->get($attributeDefinition->getUrnOid()); } else { return $default; } // if it is singular, it should return the single value if it has a value if ($attributeDefinition->getMultiplicity() === AttributeDefinition::MULTIPLICITY_SINGLE) { $count = count($attribute); if ($count > 1) { throw new UnexpectedValueException(sprintf('AttributeDefinition "%s" has a single-value multiplicity, yet returned' . ' "%d" values', $attributeDefinition->getName(), count($attribute))); } elseif ($count === 0) { $attribute = null; } else { $attribute = reset($attribute); } } return $attribute; }
/** * @test * @group AssertionAdapter */ public function attribute_set_has_no_duplicate_attribute_definitions_when_same_attributes_found() { $oidAttributeUrn = 'urn:oid:0.0.0.0.0.0.0.0.0'; $maceAttributeUrn = 'urn:mace:some:attribute'; $attributeValue = ['oid-attribute-value']; $existingAttributeDefinition = new AttributeDefinition('existingOidAttribute', $maceAttributeUrn, $oidAttributeUrn); $assertion = m::mock('\\SAML2_Assertion'); $assertion->shouldReceive('getAttributes')->andReturn([$oidAttributeUrn => $attributeValue, $maceAttributeUrn => $attributeValue]); $dictionary = new AttributeDictionary(); $dictionary->addAttributeDefinition($existingAttributeDefinition); $adapter = new AssertionAdapter($assertion, $dictionary); $attributeSet = $adapter->getAttributeSet(); $this->assertCount(1, $attributeSet, 'Expected attribute AttributeSet to have exactly one attribute'); }
private function getAttributeDictionary() { $attributeDictionary = new AttributeDictionary(); $attributeDictionary->addAttributeDefinition(new AttributeDefinition('displayName', 'urn:mace:dir:attribute-def:displayName')); $attributeDictionary->addAttributeDefinition(new AttributeDefinition('eduPersonTargetedID', 'urn:mace:dir:attribute-def:eduPersonTargetedID')); return $attributeDictionary; }