springsecurity整合cas客户端
这几天都在弄一个springSecurity整合Cas的单点登陆的例子,cas服务端已经弄好的,所以这里我只是说一下客户端的配置我是怎么弄的,以及出现的问题
- web.xml文件
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="zhongjiaoyun" version="2.5">
<display-name>sso test</display-name>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 解决post乱码 -->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- spring mvc start -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:spring/spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath*:spring/spring-mvc.xml
</param-value>
</context-param>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/pages/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/hyperlink/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
<filter>
<filter-name>HiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HiddenHttpMethodFilter</filter-name>
<servlet-name>dispatcher</servlet-name>
</filter-mapping>
<!-- cas security start -->
<listener>
<listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
</listener>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- cas security end -->
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<session-config>
<session-timeout>30</session-timeout>
</session-config>
</web-app>
2.接下来是springMVC.xml,里面引入了spring-security-cas.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 引入配置文件 -->
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list>
<value>classpath:env.properties</value>
</list>
</property>
</bean>
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="properties" ref="propertyConfigurer"/>
<property name="order" value="-1"/>
</bean>
<!-- 使用Annotation自动注册Bean,只扫描@Controller -->
<context:component-scan base-package="com.cccc" use-default-filters="false"><!-- base-package 如果多个,用“,”分隔 -->
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!-- 支持返回json(避免IE在ajax请求时,返回json出现下载 ) -->
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="mappingJacksonHttpMessageConverter"/>
</list>
</property>
</bean>
<bean id="mappingJacksonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/plain;charset=UTF-8</value>
<value>application/json;charset=UTF-8</value>
</list>
</property>
<property name="objectMapper">
<bean class="com.fasterxml.jackson.databind.ObjectMapper">
<property name="dateFormat">
<bean class="java.text.SimpleDateFormat">
<constructor-arg value="yyyy-MM-dd HH:mm:ss"/>
</bean>
</property>
</bean>
</property>
</bean>
<bean id="mappingJackson2HttpMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/json;charset=UTF-8</value>
</list>
</property>
</bean>
<bean id="stringHttpMessageConverter" class="org.springframework.http.converter.StringHttpMessageConverter"/>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="mappingJackson2HttpMessageConverter"/>
<ref bean="stringHttpMessageConverter"/>
</list>
</property>
</bean>
<!-- 支持返回json -->
<import resource="classpath*:/spring/spring-security-cas.xml"/>
</beans>
- spring-security-cas.xml配置如下:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<!-- 指定登录入口为casEntryPoint -->
<security:http entry-point-ref="casEntryPoint" use-expressions="true" >
<security:intercept-url pattern="/html/**" access="isFullyAuthenticated()"/>
<security:custom-filter ref="switchUserFilter" before="FILTER_SECURITY_INTERCEPTOR" />
<!-- 请求登出Cas Server的过滤器,放在Spring Security的登出过滤器之前 -->
<security:custom-filter ref="requestCasLogoutFilter" before="LOGOUT_FILTER" />
<!-- SingleSignOutFilter放在CAS_FILTER之前 -->
<security:custom-filter ref="casLogoutFilter" before="CAS_FILTER" />
<security:custom-filter ref="casFilter" position="CAS_FILTER" />
</security:http>
<!-- 认证的入口 -->
<bean id="casEntryPoint"
class="org.springframework.security.cas.web.CasAuthenticationEntryPoint">
<!-- Cas Server的登录地址 -->
<property name="loginUrl" value="${spring.security.cas.prefix}/login" />
<!-- service相关的属性 -->
<property name="serviceProperties" ref="serviceProperties" />
</bean>
<bean id="casFilter" class="org.springframework.security.cas.web.CasAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager" />
</bean>
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider ref="casAuthenticationProvider" />
</security:authentication-manager>
<bean id="casAuthenticationProvider" class="org.springframework.security.cas.authentication.CasAuthenticationProvider">
<!-- 通过username来加载UserDetails -->
<property name="authenticationUserDetailsService">
<bean class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
<!-- 真正加载UserDetails的UserDetailsService实现 -->
<constructor-arg ref="userInfoService" />
</bean>
</property>
<property name="serviceProperties" ref="serviceProperties" />
<!-- 配置TicketValidator在登录认证成功后验证ticket -->
<property name="ticketValidator">
<bean class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator">
<!-- Cas Server访问地址的前缀,即根路径 -->
<constructor-arg index="0" value="${spring.security.cas.prefix_intranet}" />
</bean>
</property>
<property name="key" value="key4CasAuthenticationProvider" />
</bean>
<!-- 指定service相关信息 -->
<bean id="serviceProperties" class="org.springframework.security.cas.ServiceProperties">
<!-- Cas Server认证成功后的跳转地址,这里要跳转到我们的Spring Security应用,之后会由CasAuthenticationFilter处理,默认处理地址为/j_spring_cas_security_check -->
<property name="service" value="${spring.security.sysmgr.service.prefix}/j_spring_cas_security_check" />
</bean>
<bean id="switchUserFilter" class="org.springframework.security.web.authentication.switchuser.SwitchUserFilter">
<property name="userDetailsService" ref="userInfoService"/>
<!-- usernameParameter属性表示传递的用户名称的参数名称 -->
<property name="usernameParameter" value="userId"/>
<!--targetUrl属性表示切换用户成功后应该转向哪个地址 -->
<property name="targetUrl" value="/switch/success"/>
<!--switchUserUrl属性表示SwitchUserFilter拦截的请求地址-->
<!--<property name="switchUserUrl" value="/switch"/>-->
<!-- exitUserUrl表示切换用记成功后如果想要退出应该设置的url请求地址 -->
<!-- <property name="exitUserUrl" value="/exit"/> -->
</bean>
<bean id="userInfoService" class="com.cccc.security.UserInfoService" lazy-init="true" ></bean>
<bean id="casLogoutFilter" class="org.jasig.cas.client.session.SingleSignOutFilter" />
<bean id="requestCasLogoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
<!-- 指定登出成功后需要跳转的地址,这里指向Cas Server的登出URL,以实现单点登出 -->
<constructor-arg value="${spring.security.cas.prefix}/logout?service=${spring.security.sysmgr.service.login.url}" />
<constructor-arg>
<bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler" />
</constructor-arg>
<!-- 该Filter需要处理的地址,默认是Spring Security的默认登出地址“/j_spring_security_logout” -->
<property name="filterProcessesUrl" value="/j_spring_cas_security_logout" />
</bean>
</beans>
还有对应的环境配置文件 env.properties
#注意一下,这个地址需要在cas服务端加入到白名单
spring.security.sysmgr.service.prefix=http://localhost:8080/sso_test
spring.security.cas.prefix=https://xxx.xx.com //cas服务认证地址
spring.security.cas.prefix_intranet=https://xxx.xx.com //cas服务认证地址和上面一样
spring.security.sysmgr.service.login.url=https://xxx.cxc.cn//这个是退出之后的地址
4,java的实现类
这个实现类里面不用做任何的逻辑处理
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import java.util.HashMap;
import java.util.Map;
public class UserInfoService implements UserDetailsService {
private final Log logger = LogFactory.getLog(getClass());
/**
* 此处的参数[loginId]为CAS登录画面输入的用户名
*/
@Override
public UserDetails loadUserByUsername(String loginId) throws UsernameNotFoundException {
String[] loginIds = loginId.split(",");
Long loginId1 = Long.valueOf(loginIds[0]);
logger.info(loginId1);
System.out.println("ID--->" + loginId1);
UserInfo userInfo = new UserInfo();
userInfo.setUid(loginId1);
userInfo.setUsername("wwd");
userInfo.setPassword("123456");
userInfo.setName("wwdname");
userInfo.setOrgLeafId(111L);
userInfo.setCompId(11111L);
userInfo.setDeptId(111112L);
userInfo.setOrgFullName("test");
userInfo.setOrgFullName("test");
userInfo.setDeptName("test");
userInfo.setIsprofess("test");
userInfo.setCompName("test");
return userInfo;
}
}
到这里基本上就已经配置完毕了,我自己的例子中还是用到了apache的反向代理,就是cas认证服务器白名单中的一个地址代理成我本地的地址,这个网上都是有详细的说明的。就是说到这里吧,弄这个springsecurity整合cas的单点登陆花了我好几天,哎、、、
版权声明:本文为funkMusic原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。