主要讲述,cas5.2添加一个自定义的action处理,写了一个处理微信逻辑的。主要过程就是请求进来之后,会按照flow的流程进行处理,自定义action处理之后,生成了AbstractCredential类,然后通过不同类型的认证处理类(AbstractAuthenticationHandler子类)处理,并创建返回结果。
import org.apereo.cas.authentication.Credential;
import org.apereo.cas.authentication.adaptive.AdaptiveAuthenticationPolicy;
import org.apereo.cas.configuration.CasConfigurationProperties;
import org.apereo.cas.web.flow.actions.AbstractNonInteractiveCredentialsAction;
import org.apereo.cas.web.flow.resolver.CasDelegatingWebflowEventResolver;
import org.apereo.cas.web.flow.resolver.CasWebflowEventResolver;
import org.apereo.cas.web.support.WebUtils;
@ConfigurationProperties(value = "wechat")
@EnableConfigurationProperties(CasConfigurationProperties.class)
public class WeChatAuthenticationAction extends AbstractNonInteractiveCredentialsAction {
public WeChatAuthenticationAction(final CasDelegatingWebflowEventResolver initialAuthenticationAttemptWebflowEventResolver,
final CasWebflowEventResolver serviceTicketRequestWebflowEventResolver,
final AdaptiveAuthenticationPolicy adaptiveAuthenticationPolicy) {
super(initialAuthenticationAttemptWebflowEventResolver, serviceTicketRequestWebflowEventResolver, adaptiveAuthenticationPolicy);
}
@Override
protected Credential constructCredentialsFromRequest(final RequestContext requestContext) {
final HttpServletRequest request = WebUtils.getHttpServletRequestFromExternalWebflowContext(requestContext);
final HttpServletResponse response = WebUtils.getHttpServletResponseFromExternalWebflowContext(requestContext);
...
}
}
import org.apereo.cas.configuration.CasConfigurationProperties;
import org.apereo.cas.web.flow.CasWebflowConstants;
import org.apereo.cas.web.flow.configurer.AbstractCasWebflowConfigurer;
import org.springframework.context.ApplicationContext;
import org.springframework.webflow.definition.registry.FlowDefinitionRegistry;
import org.springframework.webflow.engine.ActionState;
import org.springframework.webflow.engine.Flow;
import org.springframework.webflow.engine.builder.support.FlowBuilderServices;
public class WeChatAuthenticationWebflowConfigurer extends AbstractCasWebflowConfigurer {
public WeChatAuthenticationWebflowConfigurer(final FlowBuilderServices flowBuilderServices,
final FlowDefinitionRegistry loginFlowDefinitionRegistry,
final ApplicationContext applicationContext,
final CasConfigurationProperties casProperties) {
super(flowBuilderServices, loginFlowDefinitionRegistry, applicationContext, casProperties);
}
@Override
protected void doInitialize() {
final Flow flow = getLoginFlow();
if (flow != null) {
//新建的action
final ActionState actionState = createActionState(flow, "weChatAuthenticationCheck",
createEvaluateAction("weChatAuthenticationAction"));
//增加判断,根据结果不同进行不同的处理逻辑
//这里可以自己新增action进行不同的处理
actionState.getTransitionSet().add(createTransition(CasWebflowConstants.TRANSITION_ID_SUCCESS,
CasWebflowConstants.STATE_ID_SEND_TICKET_GRANTING_TICKET));
actionState.getExitActionList().add(createEvaluateAction("clearWebflowCredentialsAction"));
registerMultifactorProvidersStateTransitionsIntoWebflow(actionState);
createStateDefaultTransition(actionState, "defalueAuthenticationCheck");
setStartState(flow, "jcpInitialAuthenticationRequestValidationCheck");
}
}
}
import org.apereo.cas.authentication.adaptive.AdaptiveAuthenticationPolicy;
import org.apereo.cas.authentication.principal.DefaultPrincipalFactory;
import org.apereo.cas.authentication.principal.PrincipalFactory;
import org.apereo.cas.configuration.CasConfigurationProperties;
import org.apereo.cas.web.flow.CasWebflowConfigurer;
import org.apereo.cas.web.flow.resolver.CasDelegatingWebflowEventResolver;
import org.apereo.cas.web.flow.resolver.CasWebflowEventResolver;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.webflow.definition.registry.FlowDefinitionRegistry;
import org.springframework.webflow.engine.builder.support.FlowBuilderServices;
import org.springframework.webflow.execution.Action;
@Configuration("casWeChatAuthenticationConfiguration")
@EnableConfigurationProperties(CasConfigurationProperties.class)
public class CasWeChatAuthenticationConfiguration {
@Autowired
@Qualifier("adaptiveAuthenticationPolicy")
private AdaptiveAuthenticationPolicy adaptiveAuthenticationPolicy;
@Autowired
@Qualifier("serviceTicketRequestWebflowEventResolver")
private CasWebflowEventResolver serviceTicketRequestWebflowEventResolver;
@Autowired
@Qualifier("initialAuthenticationAttemptWebflowEventResolver")
private CasDelegatingWebflowEventResolver initialAuthenticationAttemptWebflowEventResolver;
@Autowired
private ApplicationContext applicationContext;
@Autowired
private CasConfigurationProperties casProperties;
@Autowired
@Qualifier("loginFlowRegistry")
private FlowDefinitionRegistry loginFlowDefinitionRegistry;
@Autowired
private FlowBuilderServices flowBuilderServices;
@Bean
public Action weChatAuthenticationAction() {
return new WeChatAuthenticationAction(initialAuthenticationAttemptWebflowEventResolver,
serviceTicketRequestWebflowEventResolver,
adaptiveAuthenticationPolicy);
}
@ConditionalOnMissingBean(name = "weChatAuthenticationWebflowConfigurer")
@Bean
@DependsOn("defaultWebflowConfigurer")
public CasWebflowConfigurer weChatAuthenticationWebflowConfigurer() {
final CasWebflowConfigurer w = new WeChatAuthenticationWebflowConfigurer(flowBuilderServices, loginFlowDefinitionRegistry,
applicationContext, casProperties);
w.initialize();
return w;
}
@ConditionalOnMissingBean(name = "weChatPrincipalFactory")
@Bean
public PrincipalFactory weChatPrincipalFactory() {
return new DefaultPrincipalFactory();
}
}
import com.joincheer.sso.wechat.syncuser.WeChatSyncUser;
import org.apereo.cas.authentication.AbstractAuthenticationHandler;
import org.apereo.cas.authentication.Credential;
import org.apereo.cas.authentication.DefaultHandlerResult;
import org.apereo.cas.authentication.HandlerResult;
import org.apereo.cas.authentication.principal.Principal;
import org.springframework.beans.factory.annotation.Autowired;
import java.security.GeneralSecurityException;
import java.util.Map;
public class WeChatCredentialsAuthenticationHandler extends AbstractAuthenticationHandler {
@Autowired
private WeChatSyncUser weChatSyncUser;
public WeChatCredentialsAuthenticationHandler() {
super(null, null, null, Integer.MIN_VALUE);
}
@Override
public HandlerResult authenticate(final Credential credential) throws GeneralSecurityException {
final WeChatCredential weChatCredential = (WeChatCredential) credential;
//这里根据 attributes 去选择做其他的事情,如同步本地用户
Map weChatUserProperties = weChatCredential.getProperties();
weChatSyncUser.syncWeChatUser(weChatUserProperties);
Principal principal = principalFactory.createPrincipal(weChatCredential.getId(), weChatUserProperties);
return new DefaultHandlerResult(this, weChatCredential, principal);
}
@Override
public boolean supports(final Credential credential) {
return credential instanceof WeChatCredential;
}
}
import com.joincheer.sso.wechat.syncuser.WeChatUserProperties;
import org.apereo.cas.authentication.AbstractCredential;
import java.util.Map;
/**
* 微信 web 扫码 凭据
*/
public class WeChatCredential extends AbstractCredential {
/**
* 微信API配置属性
*/
private Map properties;
public WeChatCredential(final Map properties) {
this.properties = properties;
}
public Map getProperties() {
return properties;
}
public String getId() {
if (null != properties)
return (String) properties.get(WeChatUserProperties.ID);
return null;
}
}
import org.apereo.cas.authentication.AuthenticationEventExecutionPlan;
import org.apereo.cas.authentication.AuthenticationEventExecutionPlanConfigurer;
import org.apereo.cas.configuration.CasConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration("WeChatAuthenticationEventExecutionPlanConfiguration")
@EnableConfigurationProperties(CasConfigurationProperties.class)
public class WeChatAuthenticationEventExecutionPlanConfiguration
implements AuthenticationEventExecutionPlanConfigurer {
@Override
public void configureAuthenticationExecutionPlan(final AuthenticationEventExecutionPlan plan) {
plan.registerAuthenticationHandler(weChatCredentialsAuthenticationHandler());
}
@Bean
public WeChatCredentialsAuthenticationHandler weChatCredentialsAuthenticationHandler(){
return new WeChatCredentialsAuthenticationHandler();
}
}
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.joincheer.sso.wechat.flow.CasWeChatAuthenticationConfiguration,\
com.joincheer.sso.wechat.flow.WeChatAuthenticationAction,\
com.joincheer.sso.wechat.authentication.WeChatAuthenticationEventExecutionPlanConfiguration\