CAS5.2自定action处理逻辑

主要讲述,cas5.2添加一个自定义的action处理,写了一个处理微信逻辑的。主要过程就是请求进来之后,会按照flow的流程进行处理,自定义action处理之后,生成了AbstractCredential类,然后通过不同类型的认证处理类(AbstractAuthenticationHandler子类)处理,并创建返回结果。

在flow里面添加一个新的action

  1. 新建一个action类,继承AbstractNonInteractiveCredentialsAction类,重写constructCredentialsFromRequest方法,处理微信授权逻辑。
  2. 继承AbstractCasWebflowConfigurer类,重写doInitialize()方法,将新写的action添加到flow流中。
  3. 将新的类写到同一个configue类中,然后添加到resources\META-INF\spring.factories中。
  4. 继承AbstractAuthenticationHandler类,处理微信认证返回结果。
WeChatAuthenticationAction类
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);
		...
	}
}	
WeChatAuthenticationWebflowConfigurer 类
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");
        }
    }
}
创建一个configue类
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();
    }

}
WeChatCredentialsAuthenticationHandler 类
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;
    }
}
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;
    }
}
WeChatAuthenticationEventExecutionPlanConfiguration类
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();
    }
}
spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  com.joincheer.sso.wechat.flow.CasWeChatAuthenticationConfiguration,\
  com.joincheer.sso.wechat.flow.WeChatAuthenticationAction,\
  com.joincheer.sso.wechat.authentication.WeChatAuthenticationEventExecutionPlanConfiguration\

你可能感兴趣的:(cas)