Spring Boot集成CAS客户端

本教程是通过访问url来进入登录界面。

需求:
我们开发平台有很多学校在使用,需要接入每个学校的统一认证CAS系统。

1.服务端设置授权域名或者IP
在这里插入图片描述
2.访问地址

完整的访问路径:
https://xxx.xxx.xxx.xxx.cn/sso/login?service=https://xxx.xxxx.cn/svc/sso/login/callback/ahjzu

在这里插入图片描述
在这里插入图片描述
登录成功后,服务端将信息通过回调地址返回给客户端。

3.客户端导入jar包
在这里插入图片描述
pom引入本地jar包
在这里插入图片描述

4.过滤器配置文件

package com.wst.oss.common.filter.lib;

import org.jasig.cas.client.session.SingleSignOutHttpSessionListener;
import org.jasig.cas.client.util.HttpServletRequestWrapperFilter;
import org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter;
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 java.util.EventListener;
import java.util.HashMap;
import java.util.Map;

/**
 * 配置过滤规则
 * <p>
 * setFilter(),设置过滤器的类
 * <p>
 * setUrlPatterns(),设置拦截的路径
 * <p>
 * setInitParameters(),设置初始化的一些参数
 * <p>
 * setOrder(),设置优先过滤的级别,越小越优先。
 *
 * @author yangjingsong
 * @since 2020/7/7
 */
@Configuration("ahjzu")
public class AhjzuFilterConfig {
   
   /**
    * 添加监听器
    * @return
    */
   @Bean
   public ServletListenerRegistrationBean<EventListener> ahjuzSingleSignOutListenerRegistration() {
      ServletListenerRegistrationBean<EventListener> registrationBean = new ServletListenerRegistrationBean<EventListener>();
      registrationBean.setListener(new SingleSignOutHttpSessionListener());
      registrationBean.setOrder(2);
      return registrationBean;
   }

   //该过滤器负责对Ticket的校验工作,必须启用它
   @Bean
   public FilterRegistrationBean ahjzuCas20ProxyReceivingTicketValidationFilter() {
      FilterRegistrationBean registration = new FilterRegistrationBean();
      registration.setFilter(new Cas20ProxyReceivingTicketValidationFilter());
      registration.addUrlPatterns(
         "/login/callback/ahjzu"   //这个
      );
      registration.setName("CAS Validation Filter ahjzu");
      Map<String, String> init = new HashMap<>();
      init.put("casServerUrlPrefix", "https://sso.xxx.xxx.xxx.cn/sso/");//服务端地址
      init.put("serverName", "https://xxx.xxx.cn/svc/sso");//客户端地址
      init.put("encoding", "UTF-8"); //去身份认证的校验的时候也需要加一个编码


      registration.setInitParameters(init);
      registration.setOrder(3);
      return registration;
   }

   /**
    * 该过滤器负责实现HttpServletRequest请求的包裹,
    * 比如允许开发者通过HttpServletRequest的getRemoteUser()方法获得SSO登录用户的登录名,可选配置
    */
   @Bean
   public FilterRegistrationBean ahjzuHttpServletRequestWrapperFilter() {
      FilterRegistrationBean registration = new FilterRegistrationBean();
      registration.setFilter(new HttpServletRequestWrapperFilter());
      registration.addUrlPatterns("/login/callback/ahjzu");
      registration.setName("CAS HttpServletRequest Wrapper Filter ahjzu");
      registration.setOrder(4);
      return registration;
   }

}

5、获取信息代码

@Controller
@RequestMapping("login")
public class AhjzuLoginController {
	
   @Value("${AUTH_SERVICE_ENDPOINT}")
   private String controlHost;

   @Resource
   private RestTemplate restTemplate;

   @GetMapping("/callback/ahjzu")
   public void callback( HttpServletRequest request, HttpServletResponse response) throws IOException {

      String tenantId ="ahjzu";
      //SSO登录用户的登录名
      String remoteUser = request.getRemoteUser();
      //获取信息
      Assertion assertion = (Assertion) request.getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION);
      Principal principal = request.getUserPrincipal();
      if(StringUtils.isNotEmpty(remoteUser)) {
      
		//获取我们系统内token
         Result<Map> result = getAuthToken(remoteUser, tenantId);
         if (result != null && result.getCode().equals(BuzCode.SUCCEED.getCode())) {        	
            CookieUtils.setCookieWithoutFlush(response, "Authorization", (String) result.getData().get("access_token"), CookieUtils.COOKIE_MAX_AGE);
         }
         response.sendRedirect("https://"+tenantId+".xxx.cn/xxxx/front");
      }
   }

6.退出

登出地址格式:
https://xxx.xxx.xxx.xxx.cn/sso/logout?service=https://abc.abcd.cn/svc/sso/logout/ahjzu

回调代码

/**
 * 统一接口退出
 * @author czm
 * @date 2021/4/17 18:15
 */

@Controller
@RequestMapping("logout")
public class SsoLogoutController {

   /**
    * 退出
    * @param session
    * @return
    * tenantId 不同单位代码
    */
   @RequestMapping("/{tenantId}")
   public void logout(@PathVariable("tenantId")String tenantId,HttpSession session,HttpServletRequest request, HttpServletResponse response) throws IOException {
      session.invalidate();
    
      response.sendRedirect("https://"+tenantId+".xxx.cn/reader/front");
   }
}

7.多个服务端

当一个客户端需要对接多个服务端时,需要配置多个过滤器文件。
每个过滤器文件中方法名要区分开不能相同。
过滤路径和服务端地址需要更改。

在这里插入图片描述
在这里插入图片描述
欢迎大家留言点赞。
转发请标明出处。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐