若依改造CAS登录流程
后端处理
-
引入依赖到common模块
<dependency> <groupId>net.unicon.cas</groupId> <artifactId>cas-client-autoconfig-support</artifactId> <version>2.3.0-GA</version> </dependency>
-
配置yml
# CAS 配置 cas: server-url-prefix: http://xx/cas #cas服务端提供 server-login-url: http://xxcas/login #cas服务端提供 client-host-url: http://xxxx/api #后端请求接口地址 validation-type: cas3 redirect-after-validation: true adminPath: http://xxxx/achievement-v1 #后端管理页面地址
-
创建config类
package com.cgy.common.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.Cas30ProxyReceivingTicketValidationFilter; 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 java.util.EventListener; import java.util.HashMap; import java.util.Map; @Configuration public class config { @Value("${cas.server-url-prefix}") private String CAS_SERVER_URL_PREFIX; @Value("${cas.server-login-url}") private String CAS_SERVER_URL_LOGIN; @Value("${cas.client-host-url}") private String SERVER_NAME; /** * description: 登录过滤器 * @param: [] * @return: org.springframework.boot.web.servlet.FilterRegistrationBean */ @Bean public FilterRegistrationBean filterSingleRegistration() { FilterRegistrationBean registration = new FilterRegistrationBean(); registration.setFilter(new SingleSignOutFilter()); // 设定匹配的路径 registration.addUrlPatterns("/*"); Map<String,String> initParameters = new HashMap<String, String>(); initParameters.put("casServerUrlPrefix", CAS_SERVER_URL_PREFIX); registration.setInitParameters(initParameters); // 设定加载的顺序 registration.setOrder(1); return registration; } /** * description:过滤验证器 * * @param: [] * @return: org.springframework.boot.web.servlet.FilterRegistrationBean */ @Bean public FilterRegistrationBean filterValidationRegistration() { FilterRegistrationBean registration = new FilterRegistrationBean(); registration.setFilter(new Cas30ProxyReceivingTicketValidationFilter()); // 设定匹配的路径 registration.addUrlPatterns("/*"); Map<String,String> initParameters = new HashMap<String, String>(); initParameters.put("casServerUrlPrefix", CAS_SERVER_URL_PREFIX); initParameters.put("serverName", SERVER_NAME); initParameters.put("useSession", "true"); registration.setInitParameters(initParameters); // 设定加载的顺序 registration.setOrder(1); return registration; } /** * description:授权过滤器 * @param: [] * @return: org.springframework.boot.web.servlet.FilterRegistrationBean */ @Bean public FilterRegistrationBean filterAuthenticationRegistration() { FilterRegistrationBean registration = new FilterRegistrationBean(); registration.setFilter(new AuthenticationFilter()); // 设定匹配的路径 registration.addUrlPatterns("/cas/redirect"); //自己写的接口 registration.addUrlPatterns("/cas/login"); //自己写的接口 Map<String,String> initParameters = new HashMap<String, String>(); initParameters.put("casServerLoginUrl", CAS_SERVER_URL_LOGIN); initParameters.put("serverName", SERVER_NAME); //设置忽略 退出登录不用登录 // initParameters.put("ignorePattern", "/system/*"); registration.setInitParameters(initParameters); // 设定加载的顺序 registration.setOrder(1); return registration; } /** * wraper过滤器 * @return */ @Bean public FilterRegistrationBean filterWrapperRegistration() { FilterRegistrationBean registration = new FilterRegistrationBean(); registration.setFilter(new HttpServletRequestWrapperFilter()); // 设定匹配的路径 registration.addUrlPatterns("/*"); // 设定加载的顺序 registration.setOrder(1); return registration; } /** * 添加监听器 * @return */ @Bean public ServletListenerRegistrationBean<EventListener> singleSignOutListenerRegistration(){ ServletListenerRegistrationBean<EventListener> registrationBean = new ServletListenerRegistrationBean<EventListener>(); registrationBean.setListener(new SingleSignOutHttpSessionListener()); registrationBean.setOrder(1); return registrationBean; } }
-
编写cas登录接口
package com.cgy.web.controller.system; import com.cgy.common.constant.Constants; import com.cgy.common.core.domain.AjaxResult; import com.cgy.common.utils.StringUtils; import com.cgy.framework.web.service.SysLoginService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; import org.jasig.cas.client.authentication.AttributePrincipal; import org.jasig.cas.client.validation.Assertion; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; import java.util.HashMap; import java.util.Map; import static org.jasig.cas.client.util.AbstractCasFilter.CONST_CAS_ASSERTION; /** * 首页 * * @author Lion Li */ @Api(value = "CAS控制器", tags = {"CAS管理"}) @RequiredArgsConstructor @RestController @RequestMapping("/cas") public class SysCasController { @Value("${cas.server-url-prefix}") private String CAS_SERVER_URL_PREFIX; @Value("${cas.server-login-url}") private String CAS_SERVER_URL_LOGIN; @Value("${cas.client-host-url}") private String SERVER_NAME; @Value("${adminPath}") private String ADMIN_PATH; @Autowired private SysLoginService loginService; /** * 访问首页,提示语 */ @ApiOperation("cas登录") @GetMapping("/login") @CrossOrigin public AjaxResult login(HttpSession session) { Assertion assertion = (Assertion)session.getAttribute(CONST_CAS_ASSERTION); AttributePrincipal principal = assertion.getPrincipal(); String loginName = principal.getName(); Map<String, Object> ajax = new HashMap<>(); // 生成令牌 String token = loginService.casLogin(loginName); ajax.put(Constants.TOKEN, token); return AjaxResult.success(ajax); } /** * 访问首页,提示语 */ @RequestMapping("/redirect") public String redirect(HttpSession session, HttpServletResponse response) { try { Assertion assertion = (Assertion)session.getAttribute(CONST_CAS_ASSERTION); AttributePrincipal principal = assertion.getPrincipal(); String loginName = principal.getName(); System.out.println("loginName = " + loginName); if (StringUtils.isEmpty(loginName)) { return "票据无效!"; } response.sendRedirect("http://server/cas/login?service="+ ADMIN_PATH +"/casLogin"); // 这里为cas服务端登录地址 } catch (IOException e) { e.printStackTrace(); } return "登录成功"; } }
-
在framework/web/service/SysLoginService.java中新增
/** * CAS登录验证 * * @param username 用户名 * @return 结果 */ public String casLogin(String username) { SysUser sysUser = userService.selectUserByUserName(username); if (ObjectUtils.isEmpty(sysUser)) { System.out.println("cas用户名不存在"); return ""; } recordLoginInfo(sysUser.getUserId()); LoginUser loginUser = buildLoginUser(sysUser); // 生成token return tokenService.createToken(loginUser); } /** * 构建登录用户 */ private LoginUser buildLoginUser(SysUser user) { LoginUser loginUser = new LoginUser(); loginUser.setUserId(user.getUserId()); loginUser.setDeptId(user.getDeptId()); loginUser.setUser(user); return loginUser; }
-
启动类中开启cas
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) @EnableCasClient // 重点在这里 public class AchievementApplication { public static void main(String[] args) { SpringApplication.run(AchievementApplication.class, args); System.out.println("(♥◠‿◠)ノ゙ 启动成功 ლ(´ڡ`ლ)゙ "); } }
-
com/ruoyi/framework/config/SecurityConfig.java放行cas接口
.antMatchers("/cas/**").permitAll()
前端处理
- 增加casLogin.vue页面
<template>
<div>正在进行统一认证登录...</div>
</template>
<script>
import Cookies from "js-cookie";
export default {
name: "casLogin",
mounted() {
// cas单点登录
this.$store.dispatch("CasLogin").then(() => {
this.$router.push({path: "/index"}).catch(() => {
});
}).catch((e) => {
// console.log("xx", e)
// if (e === "Error: Network Error") {
location.href = "http://server/cas/login?service=http://xxxx/achievement-v1/casLogin"
// }
});
},
}
</script>
<style scoped>
</style>
-
Router/index.js中增加路由信息
{ path: '/casLogin', component: () => import('@/views/casLogin'), hidden: true },
-
ruoyi-ui/src/store/modules/user.js中增加
// CAS登录 CasLogin({ commit }) { return new Promise((resolve, reject) => { casLogin().then(res => { setToken(res.data.token) commit('SET_TOKEN', res.data.token) resolve() }).catch(error => { reject(error) }) }) },
-
src/api/login.js增加api
// CAS登录方法 export function casLogin() { return request({ url: '/cas/login', headers: { isToken: false }, method: 'get' }) }
-
ruoyi-ui/src/permission.js中增加/casLogin
const whiteList = ['/login', '/auth-redirect', '/bind', '/register', '/casLogin']