/** * @param \Symfony\Component\HttpFoundation\Request $request * @throws \InvalidArgumentException if cannot manage the Request * @return \Symfony\Component\HttpFoundation\Response|SamlSpInfo */ public function manage(Request $request) { if (false == $this->supports($request)) { throw new \InvalidArgumentException('Unsupported request'); } $serviceInfo = $this->serviceInfoCollection->findByAS($request->query->get('as')); if (!$serviceInfo) { return new RedirectResponse($this->httpUtils->generateUri($request, $request->attributes->get('discovery_path'))); } $serviceInfo->getSpProvider()->setRequest($request); $spED = $serviceInfo->getSpProvider()->getEntityDescriptor(); $idpED = $serviceInfo->getIdpProvider()->getEntityDescriptor(); $spMeta = $serviceInfo->getSpMetaProvider()->getSpMeta(); $builder = new AuthnRequestBuilder($spED, $idpED, $spMeta); $message = $builder->build(); if ($serviceInfo->getSpSigningProvider()->isEnabled()) { $message->sign($serviceInfo->getSpSigningProvider()->getCertificate(), $serviceInfo->getSpSigningProvider()->getPrivateKey()); } $binding = $this->bindingManager->instantiate($spMeta->getAuthnRequestBinding()); $bindingResponse = $binding->send($message); if ($bindingResponse instanceof \AerialShip\LightSaml\Binding\RedirectResponse) { $result = new RedirectResponse($bindingResponse->getDestination()); } else { if ($bindingResponse instanceof \AerialShip\LightSaml\Binding\PostResponse) { $result = new Response($bindingResponse->render()); } else { throw new \RuntimeException('Unrecognized binding response ' . get_class($bindingResponse)); } } $state = new RequestState(); $state->setId($message->getID()); $state->setDestination($serviceInfo->getIdpProvider()->getEntityDescriptor()->getEntityID()); $this->requestStore->set($state); return $result; }
/** * @param \Symfony\Component\HttpFoundation\Request $request * @throws \RuntimeException * @throws \Symfony\Component\Security\Core\Exception\AuthenticationException * @throws \InvalidArgumentException if cannot manage the Request * @return \Symfony\Component\HttpFoundation\RedirectResponse|SamlSpInfo */ public function manage(Request $request) { if (!$this->supports($request)) { throw new \InvalidArgumentException(); } $response = $this->getSamlResponse($request); $serviceInfo = $this->serviceInfoCollection->findByIDPEntityID($response->getIssuer()); $serviceInfo->getSpProvider()->setRequest($request); $this->validateResponse($serviceInfo, $response); $assertion = $this->getSingleAssertion($response); $this->createSSOState($serviceInfo, $assertion); return new SamlSpInfo($serviceInfo->getAuthenticationService(), $assertion->getSubject()->getNameID(), $assertion->getAllAttributes(), $assertion->getAuthnStatement()); }
/** * @param \Symfony\Component\HttpFoundation\Request $request * @throws \Symfony\Component\Process\Exception\RuntimeException * @return \Symfony\Component\HttpFoundation\Response|SamlSpInfo */ function manage(Request $request) { $serviceInfo = $this->serviceInfoCollection->findByAS($request->query->get('as')); if (!$serviceInfo) { return $this->httpUtils->createRedirectResponse($request, $request->attributes->get('discovery_path') . '?type=metadata'); } $serviceInfo->getSpProvider()->setRequest($request); $ed = $serviceInfo->getSpProvider()->getEntityDescriptor(); $context = new SerializationContext(); $ed->getXml($context->getDocument(), $context); $result = new Response($context->getDocument()->saveXML()); $result->headers->set('Content-Type', 'application/samlmetadata+xml'); return $result; }
/** * @param LogoutRequest $logoutRequest * @return ServiceInfo|null * @throws \RuntimeException */ protected function getServiceInfo(LogoutRequest $logoutRequest) { $serviceInfo = $this->serviceInfoCollection->findByIDPEntityID($logoutRequest->getIssuer()); if (!$serviceInfo) { throw new \RuntimeException('Got logout request from unknown IDP: ' . $logoutRequest->getIssuer()); } return $serviceInfo; }
/** * @param SamlSpInfo $samlInfo * @param Request $request * @return ServiceInfo * @throws \RuntimeException */ protected function getServiceInfo(SamlSpInfo $samlInfo, Request $request) { $serviceInfo = $this->serviceInfoCollection->get($samlInfo->getAuthenticationServiceID()); if (!$serviceInfo) { throw new \RuntimeException("redirect to discovery"); } if (!$serviceInfo->getSpSigningProvider()->isEnabled()) { throw new \RuntimeException('Signing is required for Logout'); } $serviceInfo->getSpProvider()->setRequest($request); return $serviceInfo; }
/** * @param \Symfony\Component\HttpFoundation\Request $request * @throws \RuntimeException * @throws \InvalidArgumentException if cannot manage the Request * @return \Symfony\Component\HttpFoundation\Response|SamlSpInfo */ public function manage(Request $request) { if (!$this->supports($request)) { throw new \InvalidArgumentException('Unsupported request'); } $path = $this->getPath($request); $allProviders = $this->metaProviders->all(); if (count($allProviders) == 1) { // there's only one idp... go straight to it $names = array_keys($allProviders); return new RedirectResponse($path . '?as=' . array_pop($names)); } else { if (count($allProviders) == 0) { // configuration validation should ensure this... but anyway just to be sure throw new \RuntimeException('At least one authentication service required in configuration'); } else { //$this->metaProviders->get('')->getIdpProvider()->getEntityDescriptor()->getEntityID() // present user to choose which idp he wants to authenticate with return new Response($this->twig->render('@AerialShipSamlSP/discovery.html.twig', array('providers' => $this->metaProviders->all(), 'path' => $path))); } } }
protected function deleteSSOSession(LogoutResponse $logoutResponse) { $serviceInfo = $this->serviceInfoCollection->findByIDPEntityID($logoutResponse->getIssuer()); /** @var $token SamlSpToken */ $token = $this->securityContext->getToken(); if ($token && $token instanceof SamlSpToken) { $samlInfo = $token->getSamlSpInfo(); if ($samlInfo) { $arrStates = $this->getSSOState($serviceInfo, $samlInfo->getNameID()->getValue(), $samlInfo->getAuthnStatement()->getSessionIndex()); $this->deleteSSOState($arrStates); } } }
/** * @test */ public function shouldReturnNullWhenFindByIDPEntityIDIsCalledWithUnknownEntityID() { $col = new ServiceInfoCollection(); $this->assertNull($col->findByIDPEntityID('foo')); }