- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
你好
我正尝试在 Symfony2 中为我的 api 设置某种 WSSE 身份验证。但是,在测试未经授权的调用时,我没有获取自定义的 AuthenticationException,而是从框架中获取了状态代码为 500 的 AuthenticationCredentialsNotFoundException。
对于为什么会发生这种情况有什么想法吗?这是我的代码:
WsseListener.php
<?php
namespace KrugerCorp\VOIPBundle\Security\Firewall;
use Symfony\Component\Config\Definition\Exception\Exception;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\Log\LoggerInterface;
use Symfony\Component\Security\Http\Firewall\ListenerInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
use KrugerCorp\VOIPBundle\Security\Authentication\Token\WsseTenantToken;
class WsseListener implements ListenerInterface
{
protected $securityContext;
protected $authenticationManager;
protected $logger;
public function __construct(SecurityContextInterface $securityContext, AuthenticationManagerInterface $authenticationManager, LoggerInterface $logger)
{
$this->securityContext = $securityContext;
$this->authenticationManager = $authenticationManager;
$this->logger = $logger;
}
public function handle(GetResponseEvent $event)
{
$request = $event->getRequest();
$wsseRegex = '/UsernameToken Username="([^"]+)", PasswordDigest="([^"]+)", Nonce="([^"]+)", Created="([^"]+)"/';
if (!$request->headers->has('x-wsse') || 1 !== preg_match($wsseRegex, $request->headers->get('x-wsse'), $matches))
return;
$token = new WsseTenantToken();
$token->setUser($matches[1]);
$token->digest = $matches[2];
$token->nonce = $matches[3];
$token->created = $matches[4];
try {
$authToken = $this->authenticationManager->authenticate($token);
$this->securityContext->setToken($authToken);
return;
} catch (AuthenticationException $e) {
$failedMessage = 'WSSE login failed for '.$token->getUsername()-'. Why? '.$e->getMessage();
$this->logger->error($failedMessage);
$response = new Response();
$response->setStatusCode(403);
$response->setContent($failedMessage);
$event->setResponse($response);
return;
}
$response = new Response();
$response->setStatusCode(403);
$event->setResponse($response);
}
}
WsseProvider.php
<?php
namespace KrugerCorp\VOIPBundle\Security\Authentication\Provider;
use Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Exception\NonceExpiredException;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use KrugerCorp\VOIPBundle\Security\Authentication\Token\WsseTenantToken;
class WsseProvider implements AuthenticationProviderInterface {
private $tenantProvider;
private $cacheDir;
public function __construct(UserProviderInterface $userProvider, $cacheDir)
{
$this->tenantProvider = $userProvider;
$this->cacheDir = $cacheDir;
}
public function authenticate(TokenInterface $token)
{
$tenant = $this->tenantProvider->loadUserByUsername($token->getUsername());
if (!$tenant)
throw new AuthenticationException("Bad credentials.");
if ($tenant && $this->validateDigest($token->digest, $token->nonce, $token->created, $tenant->getPassword()))
{
$authenticatedToken = new WsseTenantToken($tenant->getRoles());
$authenticatedToken->setUser($tenant);
return $authenticatedToken;
}
throw new AuthenticationException('The WSSE authentication failed.');
}
protected function validateDigest($digest, $nonce, $created, $secret)
{
if (strtotime($created) > time())
throw new AuthenticationException('The provided WSSE timestamp is in the future. Nice try.');
if (time() - strtotime($created) > 300)
throw new AuthenticationException('The timestamp is outdated.');
if (file_exists($this->cacheDir.'/'.$nonce) && file_get_contents($this->cacheDir.'/'.$nonce) + 300 > time())
throw new NonceExpiredException('Previously used nonce detected');
if (!is_dir($this->cacheDir))
mkdir($this->cacheDir, 0777, true);
file_put_contents($this->cacheDir.'/'.$nonce, time());
$expected = base64_encode(sha1(base64_decode($nonce).$created.$secret, true));
if ($digest !== $expected)
throw new AuthenticationException('Bad credentials. Digest is not as expected.');
return true;
}
public function supports(TokenInterface $token)
{
return $token instanceof WsseTenantToken;
}
}
WsseFactory.php
<?php
namespace KrugerCorp\VOIPBundle\DependencyInjection\Security\Factory;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\DefinitionDecorator;
use Symfony\Component\Config\Definition\Builder\NodeDefinition;
use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\SecurityFactoryInterface;
class WsseFactory implements SecurityFactoryInterface
{
public function create(ContainerBuilder $container, $id, $config, $userProvider, $defaultEntryPoint)
{
$providerId = 'security.authentication.provider.wsse.'.$id;
$container
->setDefinition($providerId, new DefinitionDecorator('wsse.security.authentication.provider'))
->replaceArgument(0, new Reference($userProvider));
$listenerId = 'security.authentication.listener.wsse.'.$id;
$listener = $container->setDefinition($listenerId, new DefinitionDecorator('wsse.security.authentication.listener'));
return array($providerId, $listenerId, $defaultEntryPoint);
}
public function getPosition()
{
return 'pre_auth';
}
public function getKey()
{
return 'wsse';
}
public function addConfiguration(NodeDefinition $node)
{
}
}
我的防火墙
wsse_secured:
pattern: ^/api/.*
stateless: true
wsse: true
anonymous: false
我的服务
wsse.security.authentication.provider:
class: KrugerCorp\VOIPBundle\Security\Authentication\Provider\WsseProvider
arguments: ["", "%kernel.cache_dir%/security/nonces"]
wsse.security.authentication.listener:
class: KrugerCorp\VOIPBundle\Security\Firewall\WsseListener
arguments: ["@security.context", "@security.authentication.manager", "@logger"]
tags:
- { name: monolog.logger, channel: wsse }
和 mu bundle 类
<?php
namespace KrugerCorp\VOIPBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
use KrugerCorp\VOIPBundle\DependencyInjection\Security\Factory\WsseFactory;
use Symfony\Component\DependencyInjection\ContainerBuilder;
class KrugerCorpVOIPBundle extends Bundle
{
public function build(ContainerBuilder $container)
{
parent::build($container);
$extension = $container->getExtension('security');
$extension->addSecurityListenerFactory(new WsseFactory());
}
}
最佳答案
try {
$authToken = $this->authenticationManager->authenticate($token);
$this->securityContext->setToken($authToken);
return;
} catch (AuthenticationException $e) {
// ...
}
您只捕获了AuthenticationException!
但是
$this->authenticationManager->authenticate($token);
还会抛出不会被捕获的 NonceExpiredException。
还有我的代码审查...阅读评论。
// I guess loadUserByUsername throws UsernameNotFoundException.
// Wrap it in try catch and throw new AuthenticationException("Bad credentials.");
$tenant = $this->tenantProvider->loadUserByUsername($token->getUsername());
// You will not need this...
if (!$tenant)
throw new AuthenticationException("Bad credentials.");
// $tenant always true here.
if ($tenant && $this->validateDigest($token->digest, $token->nonce, $token->created, $tenant->getPassword()))
{
$authenticatedToken = new WsseTenantToken($tenant->getRoles());
$authenticatedToken->setUser($tenant);
return $authenticatedToken;
}
关于php - Symfony2 显示 "A token was not found in the SecurityContext"而不是我的 AuthenticationException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21902109/
我正在尝试连接到 SFTP 服务器。我有一个私钥和一个密码。我已经尝试阅读SO上的相关问题,但一直无法成功连接。 这是我试过的: pysftp.Connection(host=, username=,
我正在尝试为 ActiveDirectory 创建上下文(客户端和服务器都是 Windows),使用我的 Windows 凭据和 NTLM。 这是我的代码: public void func() {
是否有更简洁的方法来检查 javax.naming.AuthenticationException(或 spring)的主要失败原因? LDAP Wiki (Binding Errors) 中描述了不
INFO [client-001-job-3] o.j.s.s.impl.DataLoaderService - Using registration URL of http://localhost
我们将应用程序从 Spring & Hibernate 3.x 升级到 4.x。问题是 AuthenticationException.getAuthentication() 现在已被弃用。任何人都可
我正在尝试创建一个 AuthenticationException 的异常子类,如下所示: public class RegistrationNotCompleteException extends
这是极少数情况之一,几乎不可能重现,但我见过这种情况发生了 20 次中有 4 次。 这是我的 open_session 方法: def open_session: self.session =
我在使用 Paramiko(版本 1.7.6-2)ssh 客户端连接到设备时遇到问题: $ python Python 2.6.5 (r265:79063, Apr 16 2010, 13:09:56
我正在使用 MailKit 尝试通过 SMTP 通过交换服务器发送电子邮件,但当我尝试连接时出现以下错误: An exception of type 'System.Security.Authenti
我正在尝试过滤在我的应用程序中进行用户身份验证期间引发的 AuthenticationException。我知道这些不能用 @ControllerAdvice 和 @ExceptionHandler
我在一个项目中使用 Spring MVC 和 Spring Security,并用它实现一个登录表单。我遇到了一种奇怪的行为,这是我没有预料到的,我想知道是否有办法避免它。 当登录表单上出现身份验证错
当我尝试通过客户端连接 Hazelcast 服务器时,出现以下异常。 com.hazelcast.client.AuthenticationException: Invalid credentials
我正在尝试使用 Java 类 AuthenticationService 进行露天身份验证。这是代码: public void Authenticate() throws Authentication
我正在尝试使用 PushSharp 向我的应用程序发送推送通知。我有两个 Apple 帐户...一个是普通帐户,另一个是企业帐户。我在正常帐户上有一个开发人员证书可以使用,但我的开发和分发证书都无法在
我正在尝试使用 JAVA GSSAPI 执行 NTLM 绑定(bind)。 我收到此错误: javax.naming.AuthenticationException: GSSAPI [Root exc
我一直在使用 Kubernetes .net 客户端库版本来从容器内访问 Kubernetes api。今天我从客户端库版本 1.6.11 更新到 4.0.21 但这破坏了客户端身份验证的某些部分。
import paramiko host='x.x.x.x' port=22 username='root' password='password' cmd='dmidecode > a' ssh=p
我正在尝试定义一个默认入口点来处理AuthenticationException。 这是我的配置: @Override protected void configure(HttpSecurity ht
我在使用纯 Java 通过 ldap 连接到 Active Directory 时遇到问题。 如果 displayName 以 ,(逗号,例如“, name”)开头,我会得到一个 javax.nami
您好,我需要在 Spring 安全登录表单中添加一个新的异常,除了我想要自己的错误消息(直到现在它显示“错误的登录名/密码”)之外,一切正常。 我已经覆盖了用户名密码身份验证过滤器的默认尝试身份验证方
我是一名优秀的程序员,十分优秀!