CAS无法找到支持UsernamePasswordCredential的身份验证处理程序

时间:2019-04-28 00:29:09

标签: cas

我有一个这样的自定义处理程序:

ERROR [org.apereo.cas.authentication.PolicyBasedAuthenticationManager] 
- <Authentication has failed. Credentials may be incorrect or CAS cannot find authentication handler that supports
[UsernamePasswordCredential(username=sadf, source=MyJDBCAuthenticationManager)] of type [UsernamePasswordCredential].
 Examine the configuration to ensure a method of authentication is defined and analyze CAS logs at DEBUG level to trace the authentication event.

对我来说,无论如何,这都应该始终记录用户。但是我在日志中看到了这个:

{{1}}

这对我来说毫无意义,因为我在日志中看到cas调用了authenticatUsernamePasswordInternal方法。显然,此处理程序支持所有操作。

为什么我不能登录?

2 个答案:

答案 0 :(得分:1)

我认为您最好使用principalFactory.createPrincipal创建主体,而不要返回new SimplePrincipal()

在您的AuthenticationEventExecutionPlanConfigurerDatabaseAuthenticationHandler中,添加以下内容:

AuthenticationEventExecutionPlanConfigurer.java

    @Autowired
    @Qualifier("principalFactory")
    private PrincipalFactory principalFactory;

    @Bean
    public DatabaseAuthenticationHandler databaseAuthenticationHandler() {
         return new DatabaseAuthenticationHandler(principalFactory);
    }


DatabaseAuthenticationHandler

Public class DatabaseAuthenticationHandler extends AbstractJdbcUsernamePasswordAuthenticationHandler {
  private final PrincipalFactory principalFactory;
  public DatabaseAuthenticationHandler (PrincipalFactory principalFactory){
     this.principalFactory = principalFactory;
  }

  @Override
  protected AuthenticationHandlerExecutionResult authenticateUsernamePasswordInternal(
        UsernamePasswordCredential credential, String originalPassword) throws GeneralSecurityException,    PreventedException {

    final String username = credential.getUsername();
    logger.debug("***Username:"+username);
    logger.debug("***Password:"+credential.getPassword());
    /////// below here's the change /////////
    return createHandlerResult(credential, this.principalFactory.createPrincipal(username), null);
  }

  @Override
  public boolean supports(final Credential credential)  {
    return true;
  }
}

看看上面的方法是否有效,谢谢。

答案 1 :(得分:0)

此问题的根本原因是您将空参数传递给createHandlerResult方法,您可以将其更改为new ArrayList<>。我也遇到了这个问题。我也尝试了Ng Sek Long提供的解决方案,但是没有用。然后我试图自己解决它。跟踪PolicyBasedAuthenticationManager类的源代码,我找到了记录错误的代码消息。

            try {
                  PrincipalResolver resolver = this.getPrincipalResolverLinkedToHandlerIfAny(handler, transaction);
                  LOGGER.debug("Attempting authentication of [{}] using [{}]", credential.getId(), handler.getName());
                  this.authenticateAndResolvePrincipal(builder, credential, resolver, handler);
                  AuthenticationCredentialsThreadLocalBinder.bindInProgress(builder.build());
                  Pair<Boolean, Set<Throwable>> failures = this.evaluateAuthenticationPolicies(builder.build(), transaction);
                  proceedWithNextHandler = !(Boolean)failures.getKey();
                } catch (Exception var15) {
                  LOGGER.error("Authentication has failed. Credentials may be incorrect or CAS cannot find authentication handler that supports [{}] of type [{}]. Examine the configuration to ensure a method of authentication is defined and analyze CAS logs at DEBUG level to trace the authentication event.", credential, credential.getClass().getSimpleName());
                  this.handleAuthenticationException(var15, handler.getName(), builder);
                  proceedWithNextHandler = true;
                }

authenticateAndResolvePrincipal方法声明了两种异常。检查此方法后,我发现有一行代码可能抛出这两种异常。

 AuthenticationHandlerExecutionResult result = handler.authenticate(credential);

跟踪的authenticate方法,我终于在DefaultAuthenticationHandlerExecutionResult类中找到了导致此问题的键代码。

  public DefaultAuthenticationHandlerExecutionResult(final AuthenticationHandler source, final CredentialMetaData metaData, final Principal p, @NonNull final List<MessageDescriptor> warnings) {
    this(StringUtils.isBlank(source.getName()) ? source.getClass().getSimpleName() : source.getName(), metaData, p, warnings);
    if (warnings == null) {
      throw new NullPointerException("warnings is marked @NonNull but is null");
    }
  }