All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.gframework.boot.mvc.config.CasConfig Maven / Gradle / Ivy

The newest version!
package com.gframework.boot.mvc.config;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

import javax.servlet.Filter;
import javax.servlet.http.HttpServletRequest;

import org.jasig.cas.client.Protocol;
import org.jasig.cas.client.authentication.AuthenticationFilter;
import org.jasig.cas.client.configuration.ConfigurationKeys;
import org.jasig.cas.client.util.AbstractCasFilter;
import org.jasig.cas.client.util.AssertionHolder;
import org.jasig.cas.client.validation.AbstractTicketValidationFilter;
import org.jasig.cas.client.validation.Assertion;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.cglib.proxy.Callback;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import org.springframework.cglib.proxy.NoOp;
import org.springframework.context.annotation.Bean;
import org.springframework.util.StringUtils;

import com.gframework.annotation.EnableCasClientSecurity;
import com.gframework.autoconfigure.mvc.cas.CasExtendConfigurationProperties;
import com.gframework.boot.mvc.controller.session.cas.CasSessionUserCreateFilter;

import net.unicon.cas.client.configuration.CasClientConfiguration;
import net.unicon.cas.client.configuration.CasClientConfigurerAdapter;

/**
 * 单点登录相关配置.
* 本类由 {@link EnableCasClientSecurity} 注解进行启动 * *

CAS核心的逻辑处理过滤器是: *

  • 重定向控制:{@link AuthenticationFilter}
  • *
  • ticket验证:{@link AbstractTicketValidationFilter}抽象类的相关子类(根据cas协议号的不同,子类不同)
  • * * @since 1.0.0 * @author Ghwolf */ @SuppressWarnings("rawtypes") @EnableConfigurationProperties(CasExtendConfigurationProperties.class) @ConditionalOnClass({Assertion.class,AbstractCasFilter.class,AssertionHolder.class}) public class CasConfig extends CasClientConfigurerAdapter { private static final Logger logger = LoggerFactory.getLogger(CasConfig.class); /** * cas 非标准额外配置信息 */ @Autowired private CasExtendConfigurationProperties casConfiguration; /** * 允许post提交ticket的代理类 * @author Ghwolf */ class RetrieveTicketFromRequestCallback implements MethodInterceptor { static final String INTERCEPTOR_METHOD_NAME = "retrieveTicketFromRequest"; private String paramName ; RetrieveTicketFromRequestCallback(AbstractCasFilter f){ Field protocol; try { protocol = AbstractCasFilter.class.getDeclaredField("protocol"); protocol.setAccessible(true); Protocol p = (Protocol) protocol.get(f); this.paramName = p.getArtifactParameterName(); } catch (Exception e) { logger.error("获取 AbstractCasFilter 类的protocol属性失败,请检查CAS版本以及是否存在安全管理器。"); throw new UnsupportedOperationException(e); } } @Override public Object intercept(Object proxyObj, Method method, Object[] args, MethodProxy proxyMethod) throws Throwable { HttpServletRequest request = (HttpServletRequest) args[0] ; return request.getParameter(paramName); } } /** * 传一个基本的AbstractCasFilter类对象,然后将其转换为支持POST传ticket的过滤器 */ private AbstractCasFilter createAllowPostTicketFilter(AbstractCasFilter filter) { // cas 的三个协议操作类都是public且可继承的,因此这里可以直接用getClass() Enhancer en = new Enhancer(); en.setSuperclass(filter.getClass()); en.setCallbacks(new Callback[]{ NoOp.INSTANCE, new RetrieveTicketFromRequestCallback(filter) }); en.setCallbackFilter(m -> RetrieveTicketFromRequestCallback.INTERCEPTOR_METHOD_NAME.equals(m.getName()) ? 1 : 0); return (AbstractCasFilter) en.create(); } /** * 这个bean的创建代码在{@link CasClientConfiguration}类的100行左右,基本都是无参构造 */ @SuppressWarnings("unchecked") @Override public void configureValidationFilter(FilterRegistrationBean validationFilter) { validationFilter.setOrder(1); if (casConfiguration.isAllowPostTicket()) { Filter filter = validationFilter.getFilter(); if (filter instanceof AbstractCasFilter) { filter = createAllowPostTicketFilter((AbstractCasFilter)filter); validationFilter.setFilter(filter); if (logger.isInfoEnabled()) { logger.info("cas被修改为支持获取post方式提交的ticket参数!"); } } else { if (logger.isWarnEnabled()) { logger.warn( "cas被修改为支持获取post方式提交的ticket参数,但是目前使用的cas版本的ValidationFilter不是AbstractCasFilter的子类,目前是:{}", filter == null ? "null" : filter.getClass()); } } } super.configureValidationFilter(validationFilter); } @Override public void configureAuthenticationFilter(FilterRegistrationBean authenticationFilter) { authenticationFilter.setOrder(2); // url过滤 if (!StringUtils.isEmpty(this.casConfiguration.getIgnorePattern())) { authenticationFilter.addInitParameter(ConfigurationKeys.IGNORE_PATTERN.getName(), this.casConfiguration.getIgnorePattern()); } super.configureAuthenticationFilter(authenticationFilter); } /** * 此过滤器在AuthenticationFilter之后,目的是将cas自己的用户认证信息进行替换,但是原始功能保留。 */ @Bean public FilterRegistrationBean configureSessionUserFilter(CasSessionUserCreateFilter casSessionUserCreateFilter) { FilterRegistrationBean filterBean = new FilterRegistrationBean<>(casSessionUserCreateFilter); filterBean.setOrder(3); return filterBean; } /** * 更改顺序+1 */ @Override public void configureHttpServletRequestWrapperFilter(FilterRegistrationBean httpServletRequestWrapperFilter) { httpServletRequestWrapperFilter.setOrder(4); super.configureHttpServletRequestWrapperFilter(httpServletRequestWrapperFilter); } /** * 更改顺序+1 */ @Override public void configureAssertionThreadLocalFilter(FilterRegistrationBean assertionThreadLocalFilter) { // XXX 这里只是存储一个threadlocal,看是否用到,没有就去掉 assertionThreadLocalFilter.setOrder(5); super.configureAssertionThreadLocalFilter(assertionThreadLocalFilter); } }




    © 2015 - 2024 Weber Informatics LLC | Privacy Policy