cas client 配置及其实现。

cas 客户端相对来说很简单:

只需要配置,还有一些登录的代码就可以了!需要注意的就是退出的配置。

1、web.xml配置,这个很多的cas 客户端配置里面都会有的但是需要注意一下的

    <filter>
        <filter-name>CAS Single Sign Out Filter</filter-name>
        <filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
        <init-param>
            <param-name>casServerUrlPrefix</param-name>
            <param-value>http://test.com/cas</param-value>
            <!-- cas server 端地址的配置。 这个主要是用户登出用的  -->
        </init-param>
    </filter>
    <filter>
        <!-- 判断用户时候进行登录的,没有今登陆将跳转到casServerLoginUrl页面进行登录,这里手动实现了一下,用于登出 -->
        <filter-name>CAS Authentication Filter</filter-name>
        <!--<filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>-->
        <filter-class>AuthenticationFilter</filter-class>
        <init-param>
            <param-name>casServerLoginUrl</param-name>
            <param-value>http://test.com/cas/login</param-value>
        </init-param>
        <init-param>
            <param-name>casServerLogoutUrl</param-name>
            <param-value>http://test.com/cas/logout</param-value>
        </init-param>
        <init-param>
            <param-name>serverName</param-name>
            <param-value>test.com</param-value>
        </init-param>
        <init-param>
            <param-name>ignorePattern</param-name>
            <param-value>^.*[.](js|css|gif|png|zip)$</param-value>
        </init-param>
    </filter>
    <filter>
        <!-- 用于进行ticket认证 -->
        <filter-name>CAS Validation Filter</filter-name>
        <filter-class>org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class>
        <init-param>
            <!-- ticket 认证的地址,这里配置的是内网地址-->
            <param-name>casServerUrlPrefix</param-name>
            <param-value>http://127.0.0.1:8443/cas</param-value>
        </init-param>
        <init-param>
            <param-name>serverName</param-name>
            <param-value>test.com</param-value>
        </init-param>
        <init-param>
            <param-name>redirectAfterValidation</param-name>
            <param-value>true</param-value>
        </init-param>
        <init-param>
            <param-name>acceptAnyProxy</param-name>
            <param-value>false</param-value>
        </init-param>
        <init-param>
            <param-name>useSession</param-name>
            <param-value>true</param-value>
        </init-param>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
    </filter>
    <filter>
        <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
        <filter-class>org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>CAS Single Sign Out Filter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>CAS Validation Filter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>CAS Authentication Filter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <filter>
        <filter-name>LoginFilter</filter-name>
        <filter-class>LoginFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>LoginFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

 <!-- 登录的监听,用户session 失效的时候,删除 sessionStorage 中的session -->
  <listener>
    <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
 </listener>

修改原来的 org.jasig.cas.client.authentication.AuthenticationFilter 的代码,如果是登出页面,将重定向到cas 中进行登出操作。

    AuthenticationFilter.java 添加一些代码 如下
    public final void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse,
                               final FilterChain filterChain) throws IOException, ServletException {

        final HttpServletRequest request = (HttpServletRequest) servletRequest;
        final HttpServletResponse response = (HttpServletResponse) servletResponse;

        if (isRequestUrlExcluded(request)) {
            logger.debug("Request is ignored.");
            filterChain.doFilter(request, response);
            return;
        }

        final HttpSession session = request.getSession(false);
        final Assertion assertion = session != null ? (Assertion) session.getAttribute(CONST_CAS_ASSERTION) : null;

        // 这里添加 如果登出的话,在这里处理 start

        if(assertion != null && CommonUtils.isNotBlank(casServerLogoutUrl) ) {
            String url = request.getRequestURI();
            String contextpath = request.getContextPath();
            if (url.startsWith(contextpath)) {
                url = url.substring(contextpath.length() + 1);
            }

            if (url.equals("managerloginout.jsf")) {
                request.getSession().invalidate();
                final String serviceUrl = constructServiceUrl(request, response);
                String modifiedServiceUrl = serviceUrl.replace(url,"");
                final String urlToRedirectTo = CommonUtils.constructRedirectUrl(this.casServerLogoutUrl,
                        getProtocol().getServiceParameterName(), modifiedServiceUrl, this.renew, this.gateway);

                this.authenticationRedirectStrategy.redirect(request, response, urlToRedirectTo);
                return;
            }
        }

        if (assertion != null) {
            filterChain.doFilter(request, response);
            return;
        }

        final String serviceUrl = constructServiceUrl(request, response);
        final String ticket = retrieveTicketFromRequest(request);
        final boolean wasGatewayed = this.gateway && this.gatewayStorage.hasGatewayedAlready(request, serviceUrl);

        if (CommonUtils.isNotBlank(ticket) || wasGatewayed) {
            filterChain.doFilter(request, response);
            return;
        }

        final String modifiedServiceUrl;

        logger.debug("no ticket and no assertion found");
        if (this.gateway) {
            logger.debug("setting gateway attribute in session");
            modifiedServiceUrl = this.gatewayStorage.storeGatewayInformation(request, serviceUrl);
        } else {
            modifiedServiceUrl = serviceUrl;
        }

        logger.debug("Constructed service url: {}", modifiedServiceUrl);

        final String urlToRedirectTo = CommonUtils.constructRedirectUrl(this.casServerLoginUrl,
                getProtocol().getServiceParameterName(), modifiedServiceUrl, this.renew, this.gateway);

        logger.debug("redirecting to \"{}\"", urlToRedirectTo);
        this.authenticationRedirectStrategy.redirect(request, response, urlToRedirectTo);

    }

LoginFilter 系统使用cas 中的信息,进行认证登录操作 ,属于业务代码,不能直接使用。

public class LoginFilter implements Filter{
    private static Logger log = LoggerFactory.getLogger(LoginFilter.class);

    private final String  SEPARATOR_CHAR = "#@#";

    @Override
    public void destroy() {
        // TODO Auto-generated method stub

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest)request ;
        if(httpServletRequest.getSession().getAttribute("login_user") == null && httpServletRequest.getRemoteUser() != null){
            String[] separator_chars = httpServletRequest.getRemoteUser().split(SEPARATOR_CHAR);
            WebContext.setThreadRequest(httpServletRequest);
            IUserService userService = (IUserService)BaseUtil.getBean("userService") ;
            Map resultMap = userService.ssoLogin(separator_chars[0], separator_chars[1]);
            if(!"SUCESS".equals((String)resultMap.get("error_code"))){
                throw new ServletException((String)resultMap.get("error_msg"));
            }
            User user = (User)resultMap.get("user");
            httpServletRequest.getSession().setMaxInactiveInterval(3*60*60);
            httpServletRequest.getSession().setAttribute("org_code", user.getParent_code());
            httpServletRequest.getSession().setAttribute("login_user", user);
        }

        filterChain.doFilter(request, response);
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // TODO Auto-generated method stub

    }
}

需要注意的是 serverName 的配置, 可能跟晚上很多的教程不一样
直,这里只是配置了host (proto://host:port/path)。目的是,proto port都由cas去处理。

如果是配置http://test.com ,你访问https://test.com/xxx 的时候,会把你当前访问的地址识别为http://test.com/xxx。就会导致你请求混乱,当前这个的前提是你需要使用https 并且https的证书没有配置到tomcat中。具体,会在https的配置中提到。

“`java
看下 org.jasig.cas.client.util.CommonUtils 的源码
public static String constructServiceUrl(final HttpServletRequest request, final HttpServletResponse response,
final String service, final String serverNames, final String serviceParameterName,
final String artifactParameterName, final boolean encode) {
if (CommonUtils.isNotBlank(service)) {
return encode ? response.encodeURL(service) : service;
}

    final String serverName = findMatchingServerName(request, serverNames);
    final URIBuilder originalRequestUrl = new URIBuilder(request.getRequestURL().toString(), encode);
    originalRequestUrl.setParameters(request.getQueryString());

    URIBuilder builder = null;

    boolean containsScheme = true;
    // 如果servername配置proto,那么就会默认是用你配置http 或者https。不管请求过来的地址是http 还是https 。这样的情况下,如果你是https 与http 共用一个tomcat 那么就会解析混乱。
    if (!serverName.startsWith("https://") && !serverName.startsWith("http://")) {
        builder = new URIBuilder(encode);
        builder.setScheme(request.isSecure() ? "https" : "http");
        builder.setHost(serverName);
        containsScheme = false;
    }  else {
        builder = new URIBuilder(serverName, encode);
    }


    if (!serverNameContainsPort(containsScheme, serverName) && !requestIsOnStandardPort(request)) {
        builder.setPort(request.getServerPort());
    }

    builder.setEncodedPath(request.getRequestURI());

    final List<String> serviceParameterNames = Arrays.asList(serviceParameterName.split(","));
    if (!serviceParameterNames.isEmpty() && !originalRequestUrl.getQueryParams().isEmpty()) {
        for (final URIBuilder.BasicNameValuePair pair : originalRequestUrl.getQueryParams()) {
            if (!pair.getName().equals(artifactParameterName) && !serviceParameterNames.contains(pair.getName())) {
                builder.addParameter(pair.getName(), pair.getValue());
            }
        }
    }

    final String result = builder.toString();
    final String returnValue = encode ? response.encodeURL(result) : result;
    LOGGER.debug("serviceUrl generated: {}", returnValue);
    return returnValue;
}

“`

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值