`
chyou1988
  • 浏览: 7183 次
社区版块
存档分类
最新评论

身份认证流程及原理

 
阅读更多

验证身份的对象元素

在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)服务,为用户的账户添加额外的安全层。两步验证是一种安全措施,它要求用户...

    sakai-authentication身份验证技术分析文档

    API的设计旨在提供一个灵活的框架,允许开发者根据特定的应用场景定制身份验证流程。例如,可以通过插件或自定义组件的方式添加新的认证方法。 #### 四、Sakai身份验证的应用场景 Sakai的身份验证机制适用于各种...

    基于SSL的身份认证和访问控制实现原理.pdf

    在身份认证方面,SSL利用数字证书来验证服务器和客户端的身份。数字证书是由权威的第三方认证机构(CA,Certificate Authority)发行的,它包含了公钥、证书主体信息、CA的数字签名等重要信息。数字证书通过公钥和...

    SSH工作原理及流程

    SSH 工作原理及流程 SSH(Secure Shell)是一种安全的网络协议,用于提供安全的远程访问和文件传输。SSH 协议具有广泛的应用场景,如远程登录、文件传输、网络管理等。下面是 SSH 工作原理及流程的详细说明: 一、...

    基于PKI 的动态身份认证

    现有的身份认证技术存在多种问题,例如易受攻击、认证过程复杂、安全性较低等。针对这些问题,研究者们提出了基于PKI的动态身份认证方案。该方案通过结合PKI的强大功能和挑战/应答机制的灵活性,旨在提高身份认证的...

    PKI身份认证和动态口令身份认证技术比较.docx

    对接受 PKI 基本模型的认证技术而言,其算法平安性目前可以说是平安的,但是某些 PKI 身份认证系统在认证流程中接受了简洁的签名技术;其认证模型为:对于接受动态口令技术的身份认证系统,算法平安性依靠于算法的...

    vSphere 身份验证(VMware vSphere 7.0,VMware ESXi 7.0,vCenter Server 7

    本篇文章将详细探讨 vSphere 身份验证的各个方面,包括证书管理和身份验证服务的管理,以及使用 vCenter Single Sign-On 进行身份验证的详细流程。 **一、证书管理与身份验证** vSphere 的安全架构依赖于有效的...

    U KEY原理说明

    #### 一、U KEY的身份认证原理 U KEY采用了先进的冲击响应认证方法来进行身份验证。这一过程主要包括以下步骤: 1. **客户端验证**:在客户端,首先需要验证用户输入的PIN码(USER PIN),这是为了确保持有U KEY的...

    C# 实现S/Key身份认证协议

    S/Key身份认证协议是一种基于一次性口令(One-Time Password, OTP)的强身份验证方法,主要用于增强网络安全性。在C#中实现S/Key协议,可以为应用程序提供更高级别的用户验证保护,防止恶意攻击者通过重放攻击或者密码...

    JAAS 身份验证技术入门

    - 登录配置文件(如`demo.conf`)的正确设置至关重要,它决定了应用程序如何选择和配置LoginModule,从而影响整个身份验证流程。 - CallbackHandler的实现应考虑用户体验,确保在收集用户信息时遵循最佳实践,如使用...

    asp.net 身份认证

    在ASP.NET 2.0及更高版本中,虽然基本工作原理保持不变,但引入了一些改进和新特性,比如更强大的角色管理、自定义身份验证提供程序等,使得身份验证和授权过程更加灵活和易于管理。 在代码层面,可以通过`...

    Forms加票证身份验证

    本篇文章将深入探讨Forms身份验证的工作原理、实现方式以及与票证(Ticket)和Cookie的关系。 **1. Forms身份验证基础** Forms身份验证是一种基于Web表单的身份验证方式,用户通过输入用户名和密码登录,服务器...

    java使用google身份验证器实现动态口令验证的示例

    Google 身份验证器的原理是客户端和服务器事先协商好一个密钥 K,用于一次性密码的生成过程。此密钥不被任何第三方所知道。此外,客户端和服务器各有一个计数器 C,并且事先将计数值同步。 进行验证时,客户端对...

    基于ASP.NET MVC3的身份验证及权限控制方案设计

    ### 基于ASP.NET MVC3的身份验证及权限控制方案设计 #### 摘要 在当前信息技术迅速发展的背景下,确保Web应用系统的安全性至关重要。本文介绍了一种基于ASP.NET MVC3框架的身份验证及角色权限控制方案的设计思路。...

    TIM/身份认证

    1. **身份认证**:这是验证用户身份的过程,通常涉及用户提供某种形式的身份证明。常见的认证方法包括用户名和密码、智能卡、生物特征(如指纹或面部识别)以及多因素认证(MFA),其中需要提供两种或更多类型的凭证...

    身份验证身份验证身份验证

    本文将深入探讨身份验证的原理、类型以及其在现代IT环境中的应用。 身份验证(Authentication)是确认一个实体声称的身份的过程。它通常涉及三个要素:实体(主体)、声称的身份和凭证。在进行身份验证时,系统会...

    下载增强型身份验证插件.txt

    根据提供的文件信息“下载增强型身份验证插件.txt”及其描述“虚拟化WEB登录下载增强型身份验证插件”,我们可以深入探讨相关知识点,包括增强型身份验证插件的重要性、工作原理以及如何在虚拟化环境中实施。...

    基于区块链应用模式的铁路旅客身份认证系统.pdf

    通过这些技术的结合,不仅可以提升身份认证的安全性,还可以简化验证过程,提升用户体验。此系统对我国铁路旅客身份认证工作提出了新的技术方案,具有重大的实际应用价值和广泛的发展前景。此外,该系统的研究和应用...

Global site tag (gtag.js) - Google Analytics