身份验证

编辑该页面

警告:你浏览的文档欧宝体育电话欧宝娱乐app下载地址Symfony 2.7,不再维护。

这个页面的更新版本Symf欧宝娱乐app下载地址ony 6.2(当前的稳定版本)。

身份验证

2.6

TokenStorageInterface是在Symfony 2.6中引入的。欧宝娱乐app下载地址之前,你必须使用getToken ()的方法SecurityContextInterface

当请求指向一个安全区域,其中一个听众从防火墙映射能够从当前提取用户的凭据请求对象,应该创建一个令牌,包含这些凭证。接下来听者应该做的是要求身份验证管理器验证给定的牌,并返回一个通过身份验证令牌,如果提供的证书是有效的。听众应该存储身份验证令牌使用令牌存储:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17日18 19 20 21日22日23日24日25日26日27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
使用欧宝娱乐app下载地址\组件\安全\Http\防火墙\ListenerInterface;使用欧宝娱乐app下载地址\组件\安全\核心\身份验证\令牌\存储\TokenStorageInterface;使用欧宝娱乐app下载地址\组件\安全\核心\身份验证\AuthenticationManagerInterface;使用欧宝娱乐app下载地址\组件\HttpKernel\事件\GetResponseEvent;使用欧宝娱乐app下载地址\组件\安全\核心\身份验证\令牌\UsernamePasswordToken;SomeAuthenticationListener实现了ListenerInterface{/ * * *@varTokenStorageInterface * /私人美元tokenStorage;/ * * *@varAuthenticationManagerInterface * /私人美元authenticationManager;/ * * *@var字符串惟一地标识* /安全区域私人美元providerKey;/ /……公共函数处理(GetResponseEvent美元事件){美元请求=美元事件- >getRequest ();美元用户名=……;美元密码=……;美元unauthenticatedToken=UsernamePasswordToken (美元用户名,美元密码,美元- >providerKey);美元authenticatedToken=美元- >authenticationManager- >验证(美元unauthenticatedToken);美元- >tokenStorage- >setToken (美元authenticatedToken);}}

请注意

一个令牌可以是任何类,只要它实现TokenInterface

身份验证管理器

默认的身份验证管理器的一个实例AuthenticationProviderManager:

1 2 3 4 5 6 7 8 9 10 11 12 13 14
使用欧宝娱乐app下载地址\组件\安全\核心\身份验证\AuthenticationProviderManager;使用欧宝娱乐app下载地址\组件\安全\核心\异常\AuthenticationException;/ / Symfony核心\ \欧宝娱乐app下载地址安全\ \组件的实例验证\ \ AuthenticationProviderInterface提供者美元供应商=数组(…);美元authenticationManager=AuthenticationProviderManager (美元供应商);试一试{美元authenticatedToken=美元authenticationManager- >验证(美元unauthenticatedToken);}(AuthenticationException美元异常){/ /身份验证失败}

AuthenticationProviderManager实例化时,接收多个身份验证提供者,每个支持不同类型的令牌。

请注意

当然你可以编写自己的身份验证管理器,它只有实现AuthenticationManagerInterface

身份验证提供者

每个提供者(因为它实现了AuthenticationProviderInterface)有一个方法支持()AuthenticationProviderManager可以确定它是否支持给定的令牌。如果是这样的话,经理然后调用提供者的方法authenticate ()。此方法应该返回一个身份验证令牌或抛出AuthenticationException(或任何其他异常扩展)。

用户身份验证的用户名和密码

身份验证提供者将尝试验证用户根据他们提供的凭证。通常这些都是用户名和密码。大多数web应用程序中存储用户的用户名和用户密码的哈希加上一个随机生成的盐。这意味着获取的平均验证将由盐和散列密码的用户数据存储、散列密码用户刚刚提供的(例如,使用一个登录表单)与盐和比较来确定给定的密码是有效的。

这个功能是提供的DaoAuthenticationProvider。获取用户的数据UserProviderInterface,使用一个PasswordEncoderInterface创建一个哈希密码并返回一个验证令牌如果密码是有效的:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17日18 19 20 21日22日23日24日25日26日27 28 29
使用欧宝娱乐app下载地址\组件\安全\核心\身份验证\提供者\DaoAuthenticationProvider;使用欧宝娱乐app下载地址\组件\安全\核心\用户\UserChecker;使用欧宝娱乐app下载地址\组件\安全\核心\用户\InMemoryUserProvider;使用欧宝娱乐app下载地址\组件\安全\核心\编码器\EncoderFactory;美元userProvider=InMemoryUserProvider (数组(“管理”= >数组(/ /密码是“foo”“密码”= >“5 fz2z8qika7utz4bykoc + GsReLf569mSKDsfods6LYQ8t + a8EW9oaircfMpmaLbPBh4FOBiiFyLfuZmTSUwzZg = =”,“角色”= >数组(“ROLE_ADMIN”))));对一些额外的检查:/ /帐户启用,锁定,过期等。美元userChecker=UserChecker ();/ /数组的密码编码器(见下文)美元encoderFactory=EncoderFactory (…);美元daoProvider=DaoAuthenticationProvider (美元userProvider,美元userChecker,“secured_area”,美元encoderFactory);美元daoProvider- >验证(美元unauthenticatedToken);

请注意

上面的示例演示了使用“内存”用户提供者,但你可以使用任何用户提供者,只要它实现UserProviderInterface。也可以让多个用户提供者尝试找到用户的数据,使用ChainUserProvider

密码编码器工厂

DaoAuthenticationProvider使用一个编码器工厂来创建一个密码编码器为给定类型的用户。这允许您为不同类型的用户使用不同的编码策略。默认的EncoderFactory编码器接收一个数组:

1 2 3 4 5 6 7 8 9 10 11 12 13 14
使用Acme\实体\LegacyUser;使用欧宝娱乐app下载地址\组件\安全\核心\编码器\EncoderFactory;使用欧宝娱乐app下载地址\组件\安全\核心\编码器\MessageDigestPasswordEncoder;使用欧宝娱乐app下载地址\组件\安全\核心\用户\用户;美元defaultEncoder=MessageDigestPasswordEncoder (“sha512”,真正的,5000年);美元weakEncoder=MessageDigestPasswordEncoder (md5的,真正的,1);美元编码器=数组(用户::类= >美元defaultEncoder,LegacyUser::类= >美元weakEncoder,/ /……);美元encoderFactory=EncoderFactory (美元编码器);

每个编码器应该实现PasswordEncoderInterface或者用一个数组和一个参数关键,允许编码器工厂构造编码器只有当它是必要的。

创建一个自定义密码编码器

有很多内置的密码编码器。但是如果你需要创建自己的,只需要遵循以下规则:

  1. 这个类必须实现PasswordEncoderInterface;
  2. 的实现encodePassword ()isPasswordValid ()必须首先确保密码不是很长,即密码长度不超过4096个字符。这是出于安全考虑(见cve - 2013 - 5750),您可以使用isPasswordTooLong ()这张支票的方法:

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21日22日23日
    使用欧宝娱乐app下载地址\组件\安全\核心\编码器\BasePasswordEncoder;使用欧宝娱乐app下载地址\组件\安全\核心\异常\BadCredentialsException;FoobarEncoder扩展BasePasswordEncoder{公共函数encodePassword(美元,美元){如果(美元- >isPasswordTooLong (美元)){BadCredentialsException (无效的密码。);}/ /……}公共函数isPasswordValid(美元编码,美元,美元){如果(美元- >isPasswordTooLong (美元)){返回;}/ /……}}

使用密码编码器

getEncoder ()方法与用户密码编码器工厂叫做对象作为它的第一个参数,它将返回类型的编码器PasswordEncoderInterface应该使用哪一个编码这个用户的密码:

1 2 3 4 5 6 7 8 9 10 11 12 13 14
/ / Acme \实体\ LegacyUser实例美元用户=……;/ /提交的密码,例如当注册美元plainPassword=……;美元编码器=美元encoderFactory- >getEncoder (美元用户);/ /返回weakEncoder美元(见上图)美元encodedPassword=美元编码器- >encodePassword (美元plainPassword,美元用户- >getSalt ());美元用户- >向setPassword (美元encodedPassword);/ /……保存这个用户

现在,当你想要检查是否提交的密码(例如,当试图登录)是正确的,您可以使用:

1 2 3 4 5 6 7 8 9 10 11
/ /获取Acme \ \ LegacyUser实体美元用户=……;/ /提交的密码,如登录表单美元plainPassword=……;美元validPassword=美元编码器- >isPasswordValid (美元用户- >getPassword (),/ /编码的密码美元plainPassword,/ /提交的密码美元用户- >getSalt ());

验证事件

安全组件提供4相关认证事件:

的名字 事件不断 参数传递给侦听器
security.authentication.success AuthenticationEvents: AUTHENTICATION_SUCCESS AuthenticationEvent
security.authentication.failure AuthenticationEvents: AUTHENTICATION_FAILURE AuthenticationFailureEvent
security.interactive_login SecurityEvents: INTERACTIVE_LOGIN InteractiveLoginEvent
security.switch_user SecurityEvents: SWITCH_USER SwitchUserEvent

身份验证成功和失败事件

当供应商对用户进行身份验证security.authentication.success事件分派。但要注意——这一事件将火,例如,每一个如果你有基于会话的身份验证请求。看到security.interactive_login下面如果你需要做一些当用户实际上登录。

当一个提供者尝试验证但失败(即抛出AuthenticationException),一个security.authentication.failure事件分派。你可以听的security.authentication.failure事件,例如,为了记录失败的登录尝试。

安全事件

security.interactive_login事件触发后用户积极登录到你的网站。重要的是要区分这一行动和非交互式验证方法,如:

  • 基于您的会话的身份验证。
  • 使用HTTP基本身份验证或HTTP消化头。

你可以听的security.interactive_login事件,例如,为了给用户一个受欢迎的flash消息每次登录。

security.switch_user每次你激活触发事件switch_user防火墙侦听器。

另请参阅

切换用户的更多信息,请参阅如何模拟一个用户吗

这项工作,包括代码示例,许可下Creative Commons冲锋队3.0许可证。