自定义Shiro领域 - 谁进行实际身份验证

时间:2016-05-01 11:02:37

标签: shiro

通过覆盖

对shiro的AuthorizingRealm(或仅AuthenticationRealm)进行子分类时
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
}

我的工作是检查AuthenticationToken中提供的凭据是否实际匹配?

或者我应该返回AuthenticationInfo principals已解决AuthenticationToken来自namespace MyVendor\MyExt\Scheduler; class MultiStepProcessTask extends \TYPO3\CMS\Scheduler\Task\AbstractTask { public function execute() { $objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager'); $businessLogic = $objectManager->get(\MyVendor\MyExt\Scheduler\MultiStepProcessTaskBusinessLogic::class); return $businessLogic->run(); } } 和给定凭据的正确密码,shiro会在流程中的某个地方对它们进行比较Subject.login(AuthenticationToken)调用?

3 个答案:

答案 0 :(得分:2)

AuthenticatingRealm.doGetAuthenticationInfo()州的Javadocs(强调我的):

  

从给定身份验证令牌的特定于实现的数据源(RDBMS,LDAP等)中检索身份验证数据。

     

对于大多数数据源而言,这意味着只需“拉动”数据源。关联主题/用户的身份验证数据,仅此而已让Shiro完成其余工作。但在某些系统中,除了检索数据外,此方法实际上还可以执行EIS特定的登录逻辑 - 这取决于领域实施。

方法AuthenticatingRealm.getAuthenticationInfo()首先调用doGetAuthenticationInfo(),然后使用配置的assertCredentialsMatch()调用credentialsMatcher

public final AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

    AuthenticationInfo info = getCachedAuthenticationInfo(token);
    if (info == null) {
        //otherwise not cached, perform the lookup:
        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) {
        assertCredentialsMatch(token, info);
    } else {
        log.debug("No AuthenticationInfo found for submitted AuthenticationToken [{}].  Returning null.", token);
    }

    return info;
}

因此,根据您的Realm实现的典型程度,您可能希望避免在AuthenticationToken方法中查看doGetAuthenticationInfo()的凭据,因为已经getAuthenticationInfo()模板方法包含确保提交的凭据匹配的步骤。

如果您有责任专门解决您的问题,并且要检查AuthenticationToken中提供的凭据是否与#34;实际匹配,那么答案是是,但不是doGetAuthenticationInfo()方法即可。通常,您将在CredentialsMatcher接口的实现中执行凭据比较,如here所述。

答案 1 :(得分:0)

在doGetAuthenticationInfo(...)中,您需要验证用户是否为您提供了身份验证证明。

以下是您可能会做的伪编码示例:

protected AuthenticationInfo doGetAutheticationInfo(AuthenticationToken token) {
  if(token instanceof UsernamePasswordToken) {
    String username = token.getUsername();
    // Look up the user by the provide username
    UserRecord userRecord = lookupUserRecord(username);
    // No record found - don't know who this is
    if (userRecord == null) {
      throw new UnknownAccountException();
    }
    // Check for other things, like a locked account, expired password, etc.

    // Verify the user
    SimpleAuthenticationInfo sai = new SimpleAuthenticationInfo(userRecord.getPrincipal(), userRecord.getHashedCredentials(), userRecord.getCredentialsSalt(), getName());
    boolean successfulAuthentication = getCredentialsMatcher().doCredentialsMatch(token, sai);

    if(successfulAuthentication) {
       // Check for anything else that might prevent login (expired password, locked account, etc
       if (other problems) {
           throw new CredentialsException(); // Or something more specific
       }
       // Success!
       return sai;
    } else {
       // Bad password
       throw new IncorrectCredentialsException();
    }
  }
  // Don't know what to do with this token
  throw new CredentialsException();
}

您必须编写lookupUserRecord(用户名)或类似的东西来查找用户信息,包括他的散列和盐渍凭证。

答案 2 :(得分:0)

doGetAuthenticationInfo是完成身份验证的主要方法。因此,如果您覆盖它,通常会覆盖身份验证过程。如果你想使用为那个reealm定义的进程并做一些额外的事情,最好先调用超类方法然后获取它的信息,然后使用它,这样你就不必改变任何东西了。同样在jdbcrealm的情况下,shiro.ini中的sqls会自动映射。并且在你覆盖之前不会改变它们 setAuthenticationQuery,setUserRolesQuery等

您可以轻松调用以下方法来模拟实际过程,然后对其进行自定义。

AuthenticationInfo  info = super.doGetAuthenticationInfo(token); 

注意,super是对父级的引用,但是super()是它的构造函数。

像:

public class CustomJdbcRealm extends JdbcRealm 
{
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException 
    {

       AuthenticationInfo  info = super.doGetAuthenticationInfo(token);
      // Your own code here 
    }
}