身份验证
编辑该页面警告:你浏览的文档欧宝官网下载appob娱乐下载Symfony 4.1,不再维护。
读这个页面的更新版本Symfob娱乐下载ony 6.3(当前的稳定版本)。
身份验证
当请求指向一个安全区域,其中一个听众从防火墙映射能够从当前提取用户的凭据请求对象,应该创建一个令牌,包含这些凭证。接下来听者应该做的是要求身份验证管理器验证给定的牌,并返回一个通过身份验证令牌,如果提供的证书是有效的。听众应该存储身份验证令牌使用令牌存储:
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
使用ob娱乐下载\组件\安全\Http\防火墙\ListenerInterface;使用ob娱乐下载\组件\安全\核心\身份验证\令牌\存储\TokenStorageInterface;使用ob娱乐下载\组件\安全\核心\身份验证\AuthenticationManagerInterface;使用ob娱乐下载\组件\HttpKernel\事件\GetResponseEvent;使用ob娱乐下载\组件\安全\核心\身份验证\令牌\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
使用ob娱乐下载\组件\安全\核心\身份验证\AuthenticationProviderManager;使用ob娱乐下载\组件\安全\核心\异常\AuthenticationException;/ / Symfony核心\ \ob娱乐下载安全\ \组件的实例验证\ \ 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
使用ob娱乐下载\组件\安全\核心\身份验证\提供者\DaoAuthenticationProvider;使用ob娱乐下载\组件\安全\核心\用户\UserChecker;使用ob娱乐下载\组件\安全\核心\用户\InMemoryUserProvider;使用ob娱乐下载\组件\安全\核心\编码器\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;使用ob娱乐下载\组件\安全\核心\编码器\EncoderFactory;使用ob娱乐下载\组件\安全\核心\编码器\MessageDigestPasswordEncoder;使用ob娱乐下载\组件\安全\核心\用户\用户;美元defaultEncoder=新MessageDigestPasswordEncoder (“sha512”,真正的,5000年);美元weakEncoder=新MessageDigestPasswordEncoder (md5的,真正的,1);美元编码器=[用户::类= >美元defaultEncoder,LegacyUser::类= >美元weakEncoder,/ /……];美元encoderFactory=新EncoderFactory (美元编码器);
每个编码器应该实现PasswordEncoderInterface或者用一个数组类
和一个参数
关键,允许编码器工厂构造编码器只有当它是必要的。
创建一个自定义密码编码器
有很多内置的密码编码器。但是如果你需要创建自己的,它需要遵循以下规则:
- 这个类必须实现PasswordEncoderInterface;
的实现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日
使用ob娱乐下载\组件\安全\核心\编码器\BasePasswordEncoder;使用ob娱乐下载\组件\安全\核心\异常\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
事件,例如,为了记录失败的登录尝试。