验证身份的对象元素
在shiro中,用户需要提供principals (身份)和credentials(证明)给shiro,从而应用能验证用户身份:
principals:身份,即主体的标识属性,可以是任何东西,如用户名、邮箱等,唯一即可。一个主体可以有多个principals,但只有一个Primary principals,一般是用户名/密码/手机号。
credentials:证明/凭证,即只有主体知道的安全值,如密码/数字证书等。
认证流程
securiyManager是验证开始的地方,但从数据源取数据并作比较的工作是由Realm来进行的
ModularRealmAuthenticator:
protected AuthenticationInfo doMultiRealmAuthentication(Collection<Realm> realms, AuthenticationToken token) { //获取认证策略 AuthenticationStrategy strategy = getAuthenticationStrategy(); AuthenticationInfo aggregate = strategy.beforeAllAttempts(realms, token); if (log.isTraceEnabled()) { log.trace("Iterating through {} realms for PAM authentication", realms.size()); } //循环realm for (Realm realm : realms) { aggregate = strategy.beforeAttempt(realm, token, aggregate); if (realm.supports(token)) { log.trace("Attempting to authenticate token [{}] using realm [{}]", token, realm); AuthenticationInfo info = null; Throwable t = null; try { //关键:调用realm的getAuthenticationInfo进行认证,token为用户的token info = realm.getAuthenticationInfo(token); } catch (Throwable throwable) { t = throwable; if (log.isDebugEnabled()) { String msg = "Realm [" + realm + "] threw an exception during a multi-realm authentication attempt:"; log.debug(msg, t); } } aggregate = strategy.afterAttempt(realm, token, info, aggregate, t); } else { log.debug("Realm [{}] does not support token {}. Skipping realm.", realm, token); } } aggregate = strategy.afterAllAttempts(token, aggregate); return aggregate; }
在Realm开始处理验证的逻辑之前,Authenticator将调用Realm的 supports 方法去验证当前Realm是否支持获得的AuthenticationToken。
boolean supports (AuthenticationToken token);
通常,Realm检查的是token的类型,比如在 AuthenticatingRealm 中检查类型是否相同。
public boolean supports(AuthenticationToken token) { return token != null && getAuthenticationTokenClass().isAssignableFrom(token.getClass()); }
另外,AuthenticatingRealm的constructor中类型默认为
authenticationTokenClass = UsernamePasswordToken .class;
如果当前Realm支持提交过来的token,authenticator则调用 getAuthenticationInfo (token) 方法。
以 AuthenticatingRealm 为例(注意是final):
public final AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { //先从缓存中取 //token为需验证的用户信息(前台传来的需要验证的用户) //info为根据需验证的用户信息(前台传来的需要验证的用户)获得校验的用户验证信息(数据源中获得的正确的用户信息) AuthenticationInfo info = getCachedAuthenticationInfo(token); if (info == null) { //otherwise not cached, perform the lookup: //自定义Realm的扩展点 //根据需要验证的用户信息获得正确的用户信息(获得方式:数据库,配置文件等) info = doGetAuthenticationInfo(token); log.debug("Looked up AuthenticationInfo [{}] from doGetAuthenticationInfo", info); if (token != null && info != null) { cacheAuthenticationInfoIfPossible(token, info); } } else { log.debug("Using cached authentication info [{}] to perform credentials matching.", info); } if (info != null) { //真正的验证,token,info //此验证内,如果验证不对,则抛出异常 assertCredentialsMatch(token, info); } else { log.debug("No AuthenticationInfo found for submitted AuthenticationToken [{}]. Returning null.", token); } return info; }
有些人直接在doGetAuthenticationInfo该方法中完成也验证,验证通过时返回SimpleAuthenticationInfo实例,失败则抛出相应的验证异常。
但下面有个 assertCredentialsMatch ,说明doGetAuthenticationInfo本没有打算这样用,这种使用方式会让 CredentialMatcher 失去意义。
protected void assertCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) throws AuthenticationException { //获得CredentialsMatcher,有多种实现 CredentialsMatcher cm = getCredentialsMatcher(); if (cm != null) { //扩展点 //认证失败抛出异常 if (!cm.doCredentialsMatch(token, info)) { //not successful - throw an exception to indicate this: String msg = "Submitted credentials for token [" + token + "] did not match the expected credentials."; throw new IncorrectCredentialsException(msg); } } else { throw new AuthenticationException("A CredentialsMatcher must be configured in order to verify " + "credentials during authentication. If you do not wish for credentials to be examined, you " + "can configure an " + AllowAllCredentialsMatcher.class.getName() + " instance."); } }
AuthenticatingRealm的默认CredentialMatcher是SimpleCredentialsMatcher
public AuthenticatingRealm() { this(null, new SimpleCredentialsMatcher()); }
protected boolean equals(Object tokenCredentials, Object accountCredentials) { if (log.isDebugEnabled()) { log.debug("Performing credentials equality check for tokenCredentials of type [" + tokenCredentials.getClass().getName() + " and accountCredentials of type [" + accountCredentials.getClass().getName() + "]"); } if (isByteSource(tokenCredentials) && isByteSource(accountCredentials)) { if (log.isDebugEnabled()) { log.debug("Both credentials arguments can be easily converted to byte arrays. Performing " + "array equals comparison"); } byte[] tokenBytes = toBytes(tokenCredentials); byte[] accountBytes = toBytes(accountCredentials); return Arrays.equals(tokenBytes, accountBytes); } else { return accountCredentials.equals(tokenCredentials); } }
当然,实现类还有HashedCredentialsMatcher,使用密码加密的方式提高安全性
<!--EndFragment-->
相关推荐
谷歌身份验证器是一款用于增强在线安全的工具,尤其在谷歌浏览器环境下使用广泛。这款插件主要功能是提供两步验证(2-Step Verification)服务,为用户的账户添加额外的安全层。两步验证是一种安全措施,它要求用户...
API的设计旨在提供一个灵活的框架,允许开发者根据特定的应用场景定制身份验证流程。例如,可以通过插件或自定义组件的方式添加新的认证方法。 #### 四、Sakai身份验证的应用场景 Sakai的身份验证机制适用于各种...
在身份认证方面,SSL利用数字证书来验证服务器和客户端的身份。数字证书是由权威的第三方认证机构(CA,Certificate Authority)发行的,它包含了公钥、证书主体信息、CA的数字签名等重要信息。数字证书通过公钥和...
本篇文章将详细探讨 vSphere 身份验证的各个方面,包括证书管理和身份验证服务的管理,以及使用 vCenter Single Sign-On 进行身份验证的详细流程。 **一、证书管理与身份验证** vSphere 的安全架构依赖于有效的...
SSH 工作原理及流程 SSH(Secure Shell)是一种安全的网络协议,用于提供安全的远程访问和文件传输。SSH 协议具有广泛的应用场景,如远程登录、文件传输、网络管理等。下面是 SSH 工作原理及流程的详细说明: 一、...
现有的身份认证技术存在多种问题,例如易受攻击、认证过程复杂、安全性较低等。针对这些问题,研究者们提出了基于PKI的动态身份认证方案。该方案通过结合PKI的强大功能和挑战/应答机制的灵活性,旨在提高身份认证的...
对接受 PKI 基本模型的认证技术而言,其算法平安性目前可以说是平安的,但是某些 PKI 身份认证系统在认证流程中接受了简洁的签名技术;其认证模型为:对于接受动态口令技术的身份认证系统,算法平安性依靠于算法的...
ASP.NET Forms身份认证是Web应用程序中用户验证的一种机制,它主要用于确认用户的身份并授权其访问受保护的资源。本文将深入探讨Forms身份认证的基础、过程、登录与注销的实现,以及在多服务器环境和客户端程序中的...
#### 一、U KEY的身份认证原理 U KEY采用了先进的冲击响应认证方法来进行身份验证。这一过程主要包括以下步骤: 1. **客户端验证**:在客户端,首先需要验证用户输入的PIN码(USER PIN),这是为了确保持有U KEY的...
S/Key身份认证协议是一种基于一次性口令(One-Time Password, OTP)的强身份验证方法,主要用于增强网络安全性。在C#中实现S/Key协议,可以为应用程序提供更高级别的用户验证保护,防止恶意攻击者通过重放攻击或者密码...
- 登录配置文件(如`demo.conf`)的正确设置至关重要,它决定了应用程序如何选择和配置LoginModule,从而影响整个身份验证流程。 - CallbackHandler的实现应考虑用户体验,确保在收集用户信息时遵循最佳实践,如使用...
在ASP.NET 2.0及更高版本中,虽然基本工作原理保持不变,但引入了一些改进和新特性,比如更强大的角色管理、自定义身份验证提供程序等,使得身份验证和授权过程更加灵活和易于管理。 在代码层面,可以通过`...
本篇文章将深入探讨Forms身份验证的工作原理、实现方式以及与票证(Ticket)和Cookie的关系。 **1. Forms身份验证基础** Forms身份验证是一种基于Web表单的身份验证方式,用户通过输入用户名和密码登录,服务器...
Google 身份验证器的原理是客户端和服务器事先协商好一个密钥 K,用于一次性密码的生成过程。此密钥不被任何第三方所知道。此外,客户端和服务器各有一个计数器 C,并且事先将计数值同步。 进行验证时,客户端对...
### 基于ASP.NET MVC3的身份验证及权限控制方案设计 #### 摘要 在当前信息技术迅速发展的背景下,确保Web应用系统的安全性至关重要。本文介绍了一种基于ASP.NET MVC3框架的身份验证及角色权限控制方案的设计思路。...
1. **身份认证**:这是验证用户身份的过程,通常涉及用户提供某种形式的身份证明。常见的认证方法包括用户名和密码、智能卡、生物特征(如指纹或面部识别)以及多因素认证(MFA),其中需要提供两种或更多类型的凭证...
本文将深入探讨身份验证的原理、类型以及其在现代IT环境中的应用。 身份验证(Authentication)是确认一个实体声称的身份的过程。它通常涉及三个要素:实体(主体)、声称的身份和凭证。在进行身份验证时,系统会...
根据提供的文件信息“下载增强型身份验证插件.txt”及其描述“虚拟化WEB登录下载增强型身份验证插件”,我们可以深入探讨相关知识点,包括增强型身份验证插件的重要性、工作原理以及如何在虚拟化环境中实施。...
通过这些技术的结合,不仅可以提升身份认证的安全性,还可以简化验证过程,提升用户体验。此系统对我国铁路旅客身份认证工作提出了新的技术方案,具有重大的实际应用价值和广泛的发展前景。此外,该系统的研究和应用...