按照官网文档中关于 REST Protocol 说明,加入了依赖。
<dependency>
<groupId>org.apereo.cas</groupId>
<artifactId>cas-server-support-rest</artifactId>
<version>${cas.version}</version>
</dependency>
但是使用PostMan模拟请求时,会遇到401 Unauthorized
错误,无解中...
另外,控制台报错信息为:
Authentication has failed. Credentials may be incorrect or CAS cannot find authentication handler that supports [zhangsan] of type [UsernamePasswordCredential]
因为登陆逻辑中添加了验证码,也就是自定义Credential和处理Handler了,表单登陆正常,但就是Rest API不行,第一步TGT都无法获取,求助各位大神!
2019-12-18 答复下方评论
配置文件:customAuthenticationEventExecutionPlanConfiguration.java
@Configuration("customAuthenticationEventExecutionPlanConfiguration")
@EnableConfigurationProperties(CasConfigurationProperties.class)
public class CustomAuthenticationEventExecutionPlanConfiguration implements AuthenticationEventExecutionPlanConfigurer {
@Autowired
private CasConfigurationProperties casProperties;
@Autowired
@Qualifier("servicesManager")
private ServicesManager servicesManager;
//注册验证器
@Bean
public AuthenticationHandler customAuthenticationHandler() {
//优先验证
return new CustomAuthentionHandler("customAuthenticationHandler",servicesManager,new DefaultPrincipalFactory(), 1);
}
//注册自定义认证器
@Override
public void configureAuthenticationExecutionPlan(final AuthenticationEventExecutionPlan plan) {
plan.registerAuthenticationHandler(customAuthenticationHandler());
}
}
对应的自定义HandlerCustomAuthentionHandler.java
public class CustomAuthentionHandler extends AbstractPreAndPostProcessingAuthenticationHandler {
@Autowired
private UserServiceImpl userService;
public CustomAuthentionHandler(String name, ServicesManager servicesManager, PrincipalFactory principalFactory, Integer order){
super(name,servicesManager,principalFactory,order);
}
@Override
protected HandlerResult doAuthentication(Credential credential) throws GeneralSecurityException, PreventedException {
System.out.println("\n现在校验的Credential类为===》"+credential.getClass().getName()+"\n");
UsernamePasswordCredential usernamePasswordCredential = (UsernamePasswordCredential) credential;
String username = usernamePasswordCredential.getUsername();
String password = usernamePasswordCredential.getPassword();
//判断当前用户是否存在
UserVo userVo = userService.getUserWithMultiAttrs(username, password);
System.out.println("userVo: "+userVo.toString());
if(userVo==null){
throw new AccountNotFoundException("该用户不存在");
}
//返回多属性
Map<String, Object> map = new HashMap<>();
map.put("external\_userinfo", JSON.toJSONString(userVo));
return createHandlerResult(usernamePasswordCredential, principalFactory.createPrincipal(username, map), null);
}
@Override
public boolean supports(Credential credential) {
return credential instanceof UsernamePasswordCredential;
}
}
已经解决了,原因是:CAS Server自带的REST API,仅支持默认
UsernamePasswordCredential
,我的项目中自定义扩展了UsernamePasswordCredential
,所以需要在自定义验证Handler中做个判断,如果请求的Credential类型为org.apereo.cas.authentication.UsernamePasswordCredential
, 就是REST请求来的,直接返回对应的UsernamePasswordCredential
对象即可。