spring boot项目使用cas单点登陆,就是cas客户端是直接在spring boot项目pom.xml和yml等文件中配置就是行了吧?
客户端不需要再管web.xml那些文件?
还有局域网内网设置域名,客户端是不是需要在hosts文件中配置IP域名映射?
<dependency>
<groupId>org.jasig.cas.client</groupId>
<artifactId>cas-client-core</artifactId>
<version>3.5.0</version>
</dependency>
2.配置地址信息,在application.properties文件中配置如下
#CAS服务地址
cas.server-url=http://localhost:8080/cas
#本地客户端ip端口,不是首页地址
cas.client-host=http://localhost:8081
3.cas过滤器配置
import org.jasig.cas.client.authentication.AuthenticationFilter;
import org.jasig.cas.client.session.SingleSignOutFilter;
import org.jasig.cas.client.session.SingleSignOutHttpSessionListener;
import org.jasig.cas.client.util.HttpServletRequestWrapperFilter;
import org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.Ordered;
/**
* 创 建 人 : wangsheng 创建日期:2019年11月
*/
@Configuration
@PropertySource("classpath:application.properties")
public class casFilterConfig {
@Value("${cas.server-url}")
private String CAS_URL;
@Value("${cas.client-host}")
private String APP_URL;
@Bean
public ServletListenerRegistrationBean servletListenerRegistrationBean(){
ServletListenerRegistrationBean listenerRegistrationBean = new ServletListenerRegistrationBean();
listenerRegistrationBean.setListener(new SingleSignOutHttpSessionListener());
listenerRegistrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE);
return listenerRegistrationBean;
}
/**
* 单点登录退出
* @return
*/
@Bean
public FilterRegistrationBean singleSignOutFilter(){
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
registrationBean.setFilter(new SingleSignOutFilter());
registrationBean.addUrlPatterns("/*");
registrationBean.addInitParameter("casServerUrlPrefix", CAS_URL );
registrationBean.setName("CAS Single Sign Out Filter");
registrationBean.setOrder(2);
return registrationBean;
}
/**
* 单点登录认证
* @return
*/
@Bean
public FilterRegistrationBean AuthenticationFilter(){
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
registrationBean.setFilter(new AuthenticationFilter());
registrationBean.addUrlPatterns("/*");
registrationBean.setName("CAS Filter");
registrationBean.addInitParameter("casServerLoginUrl",CAS_URL);
registrationBean.addInitParameter("serverName", APP_URL );
registrationBean.setOrder(3);
return registrationBean;
}
/**
* 单点登录校验
* @return
*/
@Bean
public FilterRegistrationBean cas20ProxyReceivingTicketValidationFilter(){
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
registrationBean.setFilter(new Cas20ProxyReceivingTicketValidationFilter());
registrationBean.addUrlPatterns("/*");
registrationBean.setName("CAS Validation Filter");
registrationBean.addInitParameter("casServerUrlPrefix", CAS_URL );
registrationBean.addInitParameter("serverName", APP_URL );
registrationBean.setOrder(4);
return registrationBean;
}
/**
* 单点登录请求包装
* @return
*/
@Bean
public FilterRegistrationBean httpServletRequestWrapperFilter(){
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
registrationBean.setFilter(new HttpServletRequestWrapperFilter());
registrationBean.addUrlPatterns("/*");
registrationBean.setName("CAS HttpServletRequest Wrapper Filter");
registrationBean.setOrder(5);
return registrationBean;
}
/**
* 单点登录本地用户信息
* @return
*/
@Bean
public FilterRegistrationBean localUserInfoFilter(){
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
registrationBean.setFilter(new LocalUserInfoFilter());
registrationBean.addUrlPatterns("/*");
registrationBean.setName("localUserInfoFilter");
registrationBean.setOrder(6);
return registrationBean;
}
}
4.获取登录用户账号名称工具类
import org.jasig.cas.client.authentication.AttributePrincipal;
import org.jasig.cas.client.util.AbstractCasFilter;
import org.jasig.cas.client.validation.Assertion;
import javax.servlet.http.HttpServletRequest;
/**
* 创 建 人 : wangsheng 创建日期:2019年11月
*/
public class CASUtil { /**
* 从cas中获取用户名
*
* @param request
* @return
*/
public static String getAccountNameFromCas(HttpServletRequest request) {
Assertion assertion = (Assertion) request.getSession().getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION);
if(assertion!= null){
AttributePrincipal principal = assertion.getPrincipal();
return principal.getName();
}else return null;
}
}
5.定义本地过滤器,作用是通过从单点登录服务器获取用户账号,将登录的用户账号存到session中。(CAS服务端在认证通过后,会把当前认证通过的登陆用户名传递到子系统,当然,认证通过的用户名有可能与子系统的用户名不一样,那子系统就需要一个认证通过的用户名与子系统用户的映射,在子系统拿到通过认证的用户名,再找到对应的子系统用户)
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* 创 建 人 : wangsheng 创建日期:2019年11月
*/
public class LocalUserInfoFilter implements Filter {
Logger logger = LoggerFactory.getLogger(LocalUserInfoFilter.class);
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request_ = (HttpServletRequest)request;
String loginName = CASUtil.getAccountNameFromCas(request_);
if(StringUtils.isNotEmpty(loginName)){
logger.info("访问者 :" +loginName);
request_.getSession().setAttribute("loginName", loginName);
}
chain.doFilter(request, response);
}
@Override
public void destroy() {
}
}
6.controller
/**
* 创 建 人 : wangsheng 创建日期:2019年11月
*/
@Controller
public class DemoController {
//进入系统首页方法,如果没有登录,会跳转到CAS统一登录页面,登录成功后会回调该方法。
@RequestMapping("/")
public String index(){
return "index";
}
//登出
@RequestMapping("/logout")
public String logout(HttpSession session){
session.invalidate();
return "redirect:http://localhost:8080/cas/logout?service=http://localhost:8080/cas";
}
}
是的,使用CAS单点登录,客户端可以直接在spring boot项目的pom.xml和yml文件中进行配置。客户端不需要再管web.xml等文件。
对于局域网内网设置域名,客户端确实需要在hosts文件中配置IP域名映射。例如:
127.0.0.1 localhost
192.168.1.100 cas.example.com
在application.yml文件中,需要配置CAS服务器的地址和客户端的服务地址:
cas:
server:
url: https://cas.example.com:8443/cas
client:
# 客户端的服务地址,需要与CAS服务器中配置的一致
serviceUrl: https://example.com:8443/myapp/login/cas
# 忽略CAS服务器证书校验
skipSslVerification: true
在pom.xml文件中,需要添加CAS客户端的依赖:
<dependency>
<groupId>org.jasig.cas.client</groupId>
<artifactId>cas-client-core</artifactId>
<version>${cas-client.version}</version>
</dependency>
在启动类中,需要添加CAS的配置:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private CasProperties casProperties;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/login").permitAll()
.anyRequest().authenticated()
.and()
.logout().logoutSuccessUrl("/")
.and()
.apply(new CasAuthenticationConfigurer(casProperties));
}
@Bean
public ServiceProperties serviceProperties() {
ServiceProperties serviceProperties = new ServiceProperties();
serviceProperties.setService(casProperties.getClient().getServiceUrl());
serviceProperties.setSendRenew(false);
return serviceProperties;
}
@Bean
public CasAuthenticationProvider casAuthenticationProvider() {
CasAuthenticationProvider provider = new CasAuthenticationProvider();
provider.setAuthenticationUserDetailsService(new UserDetailsServiceImpl());
provider.setServiceProperties(serviceProperties());
provider.setTicketValidator(new Cas20ServiceTicketValidator(casProperties.getServer().getUrl()));
provider.setKey("casAuthProviderKey");
return provider;
}
@Bean
public AuthenticationEntryPoint authenticationEntryPoint() {
CasAuthenticationEntryPoint entryPoint = new CasAuthenticationEntryPoint();
entryPoint.setLoginUrl(casProperties.getServer().getUrl() + "/login");
entryPoint.setServiceProperties(serviceProperties());
return entryPoint;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(casAuthenticationProvider());
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/css/**", "/js/**", "/images/**", "/favicon.ico");
}
}
以上就是使用CAS单点登录的客户端配置和代码示例。