【问题标题】:CAS cannot find authentication handler that supports UsernamePasswordCredentialCAS 找不到支持 UsernamePasswordCredential 的身份验证处理程序
【发布时间】:2020-08-16 19:16:17
【问题描述】:

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

Public class DatabaseAuthenticationHandler extends AbstractJdbcUsernamePasswordAuthenticationHandler {

  @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());
    return createHandlerResult(credential, new SimplePrincipal(), null);
  }

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

对我来说,无论如何,这应该始终让用户登录。但我在日志中看到:

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.

这对我来说毫无意义,因为我在日志中看到 cas 正在调用authenticatUsernamePasswordInternal 方法。显然,这个处理程序支持一切。

为什么我无法登录?

【问题讨论】:

    标签: cas


    【解决方案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;
      }
    }
    

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

    【讨论】:

      【解决方案2】:

      这个问题的根本原因是你给createHandlerResult方法传递了一个空参数,你可以把它改成new ArrayList&lt;&gt;。我也遇到了这个问题(My CAS version is 5.3.9)。我也试过吴锡龙给出的解决方案,但是没有用。然后我尝试自己解决。我在CAS代码中搜索了错误信息,在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;
                      }
      

      在上面的代码sn-p中,authenticateAndResolvePrincipal方法声明了两种异常。看了这个方法,发现有一行代码可能会抛出这两种异常。

       AuthenticationHandlerExecutionResult result = handler.authenticate(credential);
      

      导致这个问题的关键代码在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");
          }
        }
      
      

      因此,如果您使用 createHandlerResult(credential, new SimplePrincipal(), null),NullPointerException 将在运行时抛出。它将被catch (Exception var15) 代码块捕获并记录您看到的错误消息。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-01-07
        • 2012-02-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-22
        相关资源
        最近更新 更多