我有一个这样的自定义处理程序:
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方法。显然,此处理程序支持所有操作。
为什么我不能登录?
答案 0 :(得分:1)
我认为您最好使用principalFactory.createPrincipal
创建主体,而不要返回new SimplePrincipal()
。
在您的AuthenticationEventExecutionPlanConfigurer
和DatabaseAuthenticationHandler
中,添加以下内容:
@Autowired
@Qualifier("principalFactory")
private PrincipalFactory principalFactory;
@Bean
public DatabaseAuthenticationHandler databaseAuthenticationHandler() {
return new DatabaseAuthenticationHandler(principalFactory);
}
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");
}
}