我是靠谱客的博主 追寻秀发,最近开发中收集的这篇文章主要介绍CAS SSO改造步骤(3),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

上面写完了登录验证。那么接下来还有几个部分需要修改。
  1. 当用户登录成功之后从应用1跳转到应用2的时候也需要增加一个判断应用2是否授权的操作。具体是在GenerateServiceTicketAction.java类中。
  2. 当用户退出的时候(包括浏览器退出都要触发LogoutController.java类中的操作)因此退出的时候一定要更改用户的登录状态,负责下一次用户将无法登录。
  3. 其他的如果你有其他的地方需要改造,那么不管是login-webflow.xml,还是cas-servlet.xml.都可以相应的更改。

将核心代码展示如下:

GenerateServiceTicketAction.java

/*
 * Copyright 2007 The JA-SIG Collaborative. All rights reserved. See license
 * distributed with this file and available online at
 * http://www.ja-sig.org/products/cas/overview/license/
 */
package org.jasig.cas.web.flow;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.logging.LogFactory;
import org.jasig.cas.CentralAuthenticationService;
import org.jasig.cas.authentication.principal.Credentials;
import org.jasig.cas.authentication.principal.Service;
import org.jasig.cas.authentication.principal.UsernamePasswordCredentials;
import org.jasig.cas.ticket.TicketException;
import org.jasig.cas.web.support.WebUtils;
import org.jasig.services.persondir.support.jdbc.ApplicationAuthoritiedAuthenticationDAO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.webflow.action.AbstractAction;
import org.springframework.webflow.execution.Event;
import org.springframework.webflow.execution.RequestContext;

import javax.servlet.http.HttpServletRequest;
import javax.sql.DataSource;
import javax.validation.constraints.NotNull;

/**
 * Action to generate a service ticket for a given Ticket Granting Ticket and
 * Service.
 * 
 * @author Scott Battaglia
 * @version $Revision$ $Date$
 * @since 3.0.4
 */
public final class GenerateServiceTicketAction extends AbstractAction {
   
	private final Logger log = LoggerFactory.getLogger(this.getClass());
    /** Instance of CentralAuthenticationService. */
    @NotNull
    private CentralAuthenticationService centralAuthenticationService;

    /** Instance of ApplicationAuthoritiedAuthenticationDAO. */
    @NotNull
    private ApplicationAuthoritiedAuthenticationDAO applicationAuthoritiedAuthenticationDAO;
    
    /** check the url your are request is valid or not*/
    protected boolean checkUrl(final RequestContext context){
    	UsernamePasswordCredentials userinfo = (UsernamePasswordCredentials)this.centralAuthenticationService.getCredentials();
    	HttpServletRequest request = WebUtils.getHttpServletRequest(context);
    	String url = request.getParameter("service").toString();
    	Assert.notNull(userinfo,"userinfo is null");
    	Assert.notNull(url,"url is null");
    	
		boolean result = this.applicationAuthoritiedAuthenticationDAO.CheckApplicationURLIsAuthority(url, userinfo.getUsername());
    	if(result){
    		log.error("Your have no authoriation to log this application");
    		return false;
    	}
		log.info("the Url is validn");
		return true;
    }
    protected Event doExecute(final RequestContext context) {
    	
    	boolean result = checkUrl(context);
    	if(!result){
    		return error();
    	}
        final Service service = WebUtils.getService(context);
        final String ticketGrantingTicket = WebUtils.getTicketGrantingTicketId(context);

        try {
            final String serviceTicketId = this.centralAuthenticationService
                .grantServiceTicket(ticketGrantingTicket,
                    service);
            WebUtils.putServiceTicketInRequestScope(context,
                serviceTicketId);
            return success();
        } catch (final TicketException e) {
            if (isGatewayPresent(context)) {
                return result("gateway");
            }
        }

        return error();
    }

    public void setCentralAuthenticationService(
        final CentralAuthenticationService centralAuthenticationService) {
        this.centralAuthenticationService = centralAuthenticationService;
    }

    protected boolean isGatewayPresent(final RequestContext context) {
        return StringUtils.hasText(context.getExternalContext()
            .getRequestParameterMap().get("gateway"));
    }
	
	public void setApplicationAuthoritiedAuthenticationDAO(
			ApplicationAuthoritiedAuthenticationDAO applicationAuthoritiedAuthenticationDAO) {
		this.applicationAuthoritiedAuthenticationDAO = applicationAuthoritiedAuthenticationDAO;
	}
	public ApplicationAuthoritiedAuthenticationDAO getApplicationAuthoritiedAuthenticationDAO() {
		return applicationAuthoritiedAuthenticationDAO;
	}
}


LogoutController.java

/*
 * Copyright 2007 The JA-SIG Collaborative. All rights reserved. See license
 * distributed with this file and available online at
 * http://www.ja-sig.org/products/cas/overview/license/
 */
package org.jasig.cas.web;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
import javax.validation.constraints.NotNull;

import org.jasig.cas.CentralAuthenticationService;
import org.jasig.cas.authentication.principal.UsernamePasswordCredentials;
import org.jasig.cas.web.support.CookieRetrievingCookieGenerator;
import org.jasig.services.persondir.support.jdbc.ModifyLoginedStatusAttributeDAO;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import org.springframework.util.Assert;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;
import org.springframework.web.servlet.view.RedirectView;

/**
 * Controller to delete ticket granting ticket cookie in order to log out of
 * single sign on. This controller implements the idea of the ESUP Portail's
 * Logout patch to allow for redirecting to a url on logout. It also exposes a
 * log out link to the view via the WebConstants.LOGOUT constant.
 * 
 * @author Scott Battaglia
 * @version $Revision$ $Date$
 * @since 3.0
 */
public final class LogoutController extends AbstractController {

	/** The CORE to which we delegate for all CAS functionality. */
	@NotNull
	private CentralAuthenticationService centralAuthenticationService;

	/** CookieGenerator for TGT Cookie */
	@NotNull
	private CookieRetrievingCookieGenerator ticketGrantingTicketCookieGenerator;

	/** CookieGenerator for Warn Cookie */
	@NotNull
	private CookieRetrievingCookieGenerator warnCookieGenerator;

	/** Logout view name. */
	@NotNull
	private String logoutView;

	@NotNull
	private ModifyLoginedStatusAttributeDAO modifyLoginedStatusAttributeDAO;

	/**
	 * Boolean to determine if we will redirect to any url provided in the
	 * service request parameter.
	 */
	private boolean followServiceRedirects;

	public LogoutController() {
		setCacheSeconds(0);
	}

	protected ModelAndView handleRequestInternal(
			final HttpServletRequest request, final HttpServletResponse response)
			throws Exception {
		final String ticketGrantingTicketId = this.ticketGrantingTicketCookieGenerator
				.retrieveCookieValue(request);
		final String service = request.getParameter("service");
		// change token status
		try {
			UsernamePasswordCredentials userinfo = (UsernamePasswordCredentials) this.centralAuthenticationService.getCredentials();
			Assert.notNull(userinfo,"userinfo is null");
			this.modifyLoginedStatusAttributeDAO.updateToken(userinfo.getUsername(), "0");
		} catch (Exception e) {
			e.printStackTrace();
		}
		if (ticketGrantingTicketId != null) {
			this.centralAuthenticationService
					.destroyTicketGrantingTicket(ticketGrantingTicketId);

			this.ticketGrantingTicketCookieGenerator.removeCookie(response);
			this.warnCookieGenerator.removeCookie(response);
		}

		if (this.followServiceRedirects && service != null) {
			return new ModelAndView(new RedirectView(service));
		}

		return new ModelAndView(this.logoutView);
	}

	public void setTicketGrantingTicketCookieGenerator(
			final CookieRetrievingCookieGenerator ticketGrantingTicketCookieGenerator) {
		this.ticketGrantingTicketCookieGenerator = ticketGrantingTicketCookieGenerator;
	}

	public void setWarnCookieGenerator(
			final CookieRetrievingCookieGenerator warnCookieGenerator) {
		this.warnCookieGenerator = warnCookieGenerator;
	}

	/**
	 * @param centralAuthenticationService
	 *            The centralAuthenticationService to set.
	 */
	public void setCentralAuthenticationService(
			final CentralAuthenticationService centralAuthenticationService) {
		this.centralAuthenticationService = centralAuthenticationService;
	}

	public void setFollowServiceRedirects(final boolean followServiceRedirects) {
		this.followServiceRedirects = followServiceRedirects;
	}

	public void setLogoutView(final String logoutView) {
		this.logoutView = logoutView;
	}

	public void setModifyLoginedStatusAttributeDAO(
			ModifyLoginedStatusAttributeDAO modifyLoginedStatusAttributeDAO) {
		this.modifyLoginedStatusAttributeDAO = modifyLoginedStatusAttributeDAO;
	}

	public ModifyLoginedStatusAttributeDAO getModifyLoginedStatusAttributeDAO() {
		return modifyLoginedStatusAttributeDAO;
	}
}

cas-servlet.xml的改动部分主要是将datasource和对应的数据库注入相关的bean里面。


 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:webflow="http://www.springframework.org/schema/webflow-config"
       xmlns:p="http://www.springframework.org/schema/p"       
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://www.springframework.org/schema/webflow-config http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.0.xsd">

    <import resource="spring-configuration/propertyFileConfigurer.xml" />

	<!-- Theme Resolver -->
	<bean id="themeResolver" class="org.jasig.cas.services.web.ServiceThemeResolver"
		p:defaultThemeName="${cas.themeResolver.defaultThemeName}"
        p:argumentExtractors-ref="argumentExtractors"
        p:servicesManager-ref="servicesManager">
        <property name="mobileBrowsers">
            <map>
                <entry key=".*iPhone.*" value="iphone" />
                <entry key=".*Android.*" value="iphone" />
                <entry key=".*Safari.*Pre.*" value="iphone" />
                <entry key=".*Nokia.*AppleWebKit.*" value="iphone" />
            </map>
        </property>
    </bean>

	<!-- View Resolver -->
	<bean id="viewResolver" class="org.springframework.web.servlet.view.ResourceBundleViewResolver"
		p:order="0">
		<property name="basenames">
			<list>
				<value>${cas.viewResolver.basename}</value>
				<value>protocol_views</value>
			</list>
		</property>
	</bean>
	
	<!-- Locale Resolver -->
	<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver" />
		
	<bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" />
	
	<bean id="urlBasedViewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver"
		p:viewClass="org.springframework.web.servlet.view.InternalResourceView"
        p:prefix="/WEB-INF/view/jsp/"
        p:suffix=".jsp"
        p:order="1"/>
	
	<bean id="errorHandlerResolver" class="org.jasig.cas.web.NoSuchFlowExecutionExceptionResolver" />

    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />
	
	<bean
		id="handlerMappingC"
		class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
		<property
			name="mappings">
			<props>
				<prop
					key="/logout">
					logoutController
				</prop>
				<prop
					key="/serviceValidate">
					serviceValidateController
				</prop>
				<prop
					key="/validate">
					legacyValidateController
				</prop>
				<prop
					key="/proxy">
					proxyController
				</prop>
				<prop
					key="/proxyValidate">
					proxyValidateController
				</prop>
				<prop
					key="/samlValidate">
					samlValidateController
				</prop>
				
				<prop
					key="/services/add.html">
					addRegisteredServiceSimpleFormController
				</prop>
				
				<prop
					key="/services/edit.html">
					editRegisteredServiceSimpleFormController
				</prop>
				
				<prop
					key="/services/loggedOut.html">
					serviceLogoutViewController
				</prop>

                <prop key="/services/viewStatistics.html">
                    viewStatisticsController
                </prop>
			
				<prop key="/services/*">manageRegisteredServicesMultiActionController</prop>
				<prop key="/openid/*">openIdProviderController</prop>
                <prop key="/authorizationFailure.html">passThroughController</prop>
                <prop key="/403.html">passThroughController</prop>
			</props>
		</property>
		<property
			name="alwaysUseFullPath" value="true" />
		<!--
		uncomment this to enable sending PageRequest events. 
		<property
			name="interceptors">
			<list>
				<ref bean="pageRequestHandlerInterceptorAdapter" />
			</list>
		</property>
		 -->
	</bean>

    <bean id="passThroughController" class="org.springframework.web.servlet.mvc.UrlFilenameViewController" /> 
	
	<bean
		id="openIdProviderController"
		class="org.jasig.cas.web.OpenIdProviderController"
		p:loginUrl="${cas.securityContext.casProcessingFilterEntryPoint.loginUrl}" />
	
	<bean
		id="serviceLogoutViewController"
		class="org.springframework.web.servlet.mvc.ParameterizableViewController"
		p:viewName="serviceLogoutView" />

    <bean class="org.springframework.webflow.mvc.servlet.FlowHandlerMapping" p:flowRegistry-ref="flowRegistry" p:order="2">
        <property name="interceptors">
            <ref local="localeChangeInterceptor" />
        </property>
    </bean>


     <bean class="org.springframework.webflow.mvc.servlet.FlowHandlerAdapter"
        p:flowExecutor-ref="flowExecutor"
        p:flowUrlHandler-ref="flowUrlHandler" />
 
    <bean id="flowUrlHandler" class="org.jasig.cas.web.flow.CasDefaultFlowUrlHandler" />

    <webflow:flow-executor id="flowExecutor" flow-registry="flowRegistry">
        <webflow:flow-execution-attributes>
            <webflow:always-redirect-on-pause value="false" />
        </webflow:flow-execution-attributes>
    </webflow:flow-executor>

    <webflow:flow-registry id="flowRegistry" flow-builder-services="builder">
        <webflow:flow-location path="/WEB-INF/login-webflow.xml" id="login" />
    </webflow:flow-registry>

    <webflow:flow-builder-services id="builder" view-factory-creator="viewFactoryCreator" expression-parser="expressionParser" />

    <bean id="expressionParser" class="org.springframework.webflow.expression.WebFlowOgnlExpressionParser" />

    <bean id="viewFactoryCreator" class="org.springframework.webflow.mvc.builder.MvcViewFactoryCreator">
        <property name="viewResolvers">
            <list>
                <ref local="viewResolver" />
            </list>
        </property>
    </bean>
	<bean id="proxyValidateController" class="org.jasig.cas.web.ServiceValidateController"
		p:centralAuthenticationService-ref="centralAuthenticationService"
		p:proxyHandler-ref="proxy20Handler"
		p:argumentExtractor-ref="casArgumentExtractor" />

	<bean id="serviceValidateController" class="org.jasig.cas.web.ServiceValidateController"
		p:validationSpecificationClass="org.jasig.cas.validation.Cas20WithoutProxyingValidationSpecification"
		p:centralAuthenticationService-ref="centralAuthenticationService"
		p:proxyHandler-ref="proxy20Handler"
		p:argumentExtractor-ref="casArgumentExtractor" />
	
	<bean id="samlValidateController" class="org.jasig.cas.web.ServiceValidateController"
		p:validationSpecificationClass="org.jasig.cas.validation.Cas20WithoutProxyingValidationSpecification"
		p:centralAuthenticationService-ref="centralAuthenticationService"
		p:proxyHandler-ref="proxy20Handler"
		p:argumentExtractor-ref="samlArgumentExtractor"
		p:successView="casSamlServiceSuccessView"
		p:failureView="casSamlServiceFailureView" />

	<bean id="legacyValidateController" class="org.jasig.cas.web.ServiceValidateController"
		p:proxyHandler-ref="proxy10Handler"
		p:successView="cas1ServiceSuccessView"
		p:failureView="cas1ServiceFailureView"
		p:validationSpecificationClass="org.jasig.cas.validation.Cas10ProtocolValidationSpecification"
		p:centralAuthenticationService-ref="centralAuthenticationService"
		p:argumentExtractor-ref="casArgumentExtractor" />

	<bean id="proxyController" class="org.jasig.cas.web.ProxyController"
		p:centralAuthenticationService-ref="centralAuthenticationService" />

    <bean id="viewStatisticsController" class="org.jasig.cas.web.StatisticsController"
        p:casTicketSuffix="${host.name}">
        <constructor-arg index="0" ref="ticketRegistry" />
    </bean>

	<bean id="logoutController" class="org.jasig.cas.web.LogoutController"
		p:centralAuthenticationService-ref="centralAuthenticationService"
		p:logoutView="casLogoutView"
		p:followServiceRedirects="true"  
		p:warnCookieGenerator-ref="warnCookieGenerator"
		p:ticketGrantingTicketCookieGenerator-ref="ticketGrantingTicketCookieGenerator"
		p:modifyLoginedStatusAttributeDAO-ref="modifyLoginedStatusAttributeDAO"
		/>
	
	<bean id="initialFlowSetupAction" class="org.jasig.cas.web.flow.InitialFlowSetupAction"
		p:argumentExtractors-ref="argumentExtractors"
		p:warnCookieGenerator-ref="warnCookieGenerator"
		p:ticketGrantingTicketCookieGenerator-ref="ticketGrantingTicketCookieGenerator" />
	
	<bean id="authenticationViaFormAction" class="org.jasig.cas.web.flow.AuthenticationViaFormAction"
		p:centralAuthenticationService-ref="centralAuthenticationService"
		p:warnCookieGenerator-ref="warnCookieGenerator" />
	
	<bean id="generateServiceTicketAction" class="org.jasig.cas.web.flow.GenerateServiceTicketAction"
		p:centralAuthenticationService-ref="centralAuthenticationService"
		p:applicationAuthoritiedAuthenticationDAO-ref="applicationAuthoritiedAuthenticationDAO"
		 />
		
	<bean id="sendTicketGrantingTicketAction" class="org.jasig.cas.web.flow.SendTicketGrantingTicketAction"
		p:centralAuthenticationService-ref="centralAuthenticationService"
		p:ticketGrantingTicketCookieGenerator-ref="ticketGrantingTicketCookieGenerator" />

    <bean id="gatewayServicesManagementCheck" class="org.jasig.cas.web.flow.GatewayServicesManagementCheck">
        <constructor-arg index="0" ref="servicesManager" />
    </bean>
		
	<bean id="generateLoginTicketAction" class="org.jasig.cas.web.flow.GenerateLoginTicketAction"
		p:ticketIdGenerator-ref="loginTicketUniqueIdGenerator" />
	
	<bean id="addRegisteredServiceSimpleFormController" class="org.jasig.cas.services.web.RegisteredServiceSimpleFormController"
		p:formView="addServiceView"
		p:successView="addServiceView"
		p:commandName="registeredService"
		p:validator-ref="registeredServiceValidator"
		p:sessionForm="true">
		<constructor-arg index="0" ref="servicesManager" />
		<constructor-arg index="1" ref="attributeRepository" />
	</bean>
	
	<bean id="editRegisteredServiceSimpleFormController" class="org.jasig.cas.services.web.RegisteredServiceSimpleFormController"
		p:formView="editServiceView"
		p:successView="editServiceView"
		p:commandName="registeredService"
		p:validator-ref="registeredServiceValidator"
		p:sessionForm="false">
		<constructor-arg index="0" ref="servicesManager" />
		<constructor-arg index="1" ref="attributeRepository" />
	</bean>
	
	<bean id="registeredServiceValidator" class="org.jasig.cas.services.web.support.RegisteredServiceValidator"
		p:servicesManager-ref="servicesManager" />
	
	<bean id="manageRegisteredServicesMultiActionController" class="org.jasig.cas.services.web.ManageRegisteredServicesMultiActionController">
		<constructor-arg index="0" ref="servicesManager" />
        <constructor-arg index="1" value="${cas.securityContext.serviceProperties.service}" />
	</bean>

    <bean id="messageInterpolator" class="org.jasig.cas.util.SpringAwareMessageMessageInterpolator" />

    <bean id="credentialsValidator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"
            p:messageInterpolator-ref="messageInterpolator" />
</beans>

总结,只要明白了整个CAS的工作原理,就可以相应的改造部分内容来为我所用,CAS操作数据库部分本身提供的模板已经相当强大,但是为了方便自己用,在这里写了两个类来封装操作数据库的操作。

最后

以上就是追寻秀发为你收集整理的CAS SSO改造步骤(3)的全部内容,希望文章能够帮你解决CAS SSO改造步骤(3)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(39)

评论列表共有 0 条评论

立即
投稿
返回
顶部