spring boot项目访问jsp页面已经介绍了如何在springboot项目中访问jsp页面,有了上面的基础在下面实现cas集成vue项目,由于vue项目是前后台分离的,在此记录下具体集成的步骤,方便以后查看
项目背景:cas集成的项目是使用renren-fast提供的开源框架,后台是用spring boot写的,前台使用vue。这里用cas集成的项目是在不改变项目原有登录机制的情况下,为项目单独开了个单点认证的登录入口
该项目的前后台交互是使用ajax,做cas集成要了解该项目登录模块是怎么实现的,需要在单点认证成功后将系统原有登录机制登录时所作的工作做完即可。其登录模块是使用为用户生成的记录在数据库中的token字段来判断用户是否登录的,用户登录成功后会将为用户生成的token值由后台传递vue前台放在cookie中,然后用户访问受限的资源时会判断是否有有效的token,如果有则认为是合法用户,若没有则引导用户到登录页面。所以在集成时,CAS单点登录认证成功后只要将token值传到前台并存入cookie,即被认为是登录成功的,则可以进入系统主页面。
单点登录的客户端代码是用jsp写的,访问该系统输入单点登录的入口地址会执行下面的代码
下面是单点登认证要执行的客户端核心代码,在认证成功后,生成token并将token值存在session中
<%@ page language="java" import="java.util.*" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@page import="java.io.*"%>
<%@ page import="io.admin.modules.sys.entity.SysUserEntity" %>
<%@ page import="io.admin.modules.sys.service.SysUserService" %>
<%@page import="io.admin.util.SpringContextUtil"%>
<%@ page import="io.admin.common.utils.R" %>
<%@ page import="io.admin.modules.sys.service.SysUserTokenService" %>
<%@ include file="supwisdom/CASUtils.jsp"%>
<%!
public boolean doLogin(LoginUser loginUser, HttpServletRequest request) throws UnsupportedEncodingException {
HttpSession session = request.getSession();
ServletContext application = session.getServletContext();
if(loginUser != null){
String account = loginUser.getAccount();
String localAccount = loginUser.getLocalAccount();
SysUserService sysUserService = (SysUserService) SpringContextUtil.getBean("SysUserService");
SysUserEntity user = sysUserService.queryByUserName(account);
if(user != null){
//认证成功后会执行这段代码,根据用户名在用户表中查询,生成token,并把token存入session中
SysUserTokenService sysUserTokenService = (SysUserTokenService) SpringContextUtil.getBean("sysUserTokenService");
R r = sysUserTokenService.createToken(user.getUserId());
session.setAttribute("token",r.get("token"));
}
}
return true;
}%>
<%
String targetUrl = CasUtils.getTargetUrl(request);
if (CasUtils.isLogin(session)) {
response.sendRedirect(targetUrl);
} else {
if (CasUtils.hasTicket(request)) {
LoginUser loginUser = CasUtils.getLoginUser(request);
if (loginUser.isLogin() && doLogin(loginUser, request)) {
CasUtils.login(loginUser, session);
session.setAttribute("loginOutUrl",CasUtils.getLoginUrl(request));
response.sendRedirect(targetUrl);
} else {
response.sendRedirect(CasUtils.getLogoutUrl(request));
}
} else {
String loginUrl = CasUtils.getLoginUrl(request);
response.sendRedirect(loginUrl);
}
}
%>
因为单点登录客户端与cas server认证交互的代码是写在后台的,单点登录认证成功后由于没有在被集成系统中输入用户名密码的验证过程,所以直接返回被集成系统的前台首页是没有传递token的,当然token值是可以传递的,比如可以将token值拼接在认证成功后进入系统首页的URL中,像这样(http://localhost:8001/#/caslogin/?token=c99f76b35b8efc3e9e30017957707a62),然后在前端将token值解析出来放入cookie中,但这样做感觉不安全,便舍弃了这种做法。具体做法是让认证成功后先进入前台vue的一个默认页面,这里是定义了一个caslogin.vue的页面,从这里向后台发送ajax请求获取登录所需要的token,然后再进入系统的首页。
配置单点登录认证成功后默认要跳转的URL为:http://localhost:8001/#/caslogin,即为我们定义的认证成功的默认页面。当然需要在前台src->router->index.js配置路由,使得对caslogin.vue的访问不需要token的验证,因为访问caslogin.vue时是没有token的,不配置路由会因为没有token值被拦截跳转到登录页面。
新增 { path: '/caslogin', component: _import('common/caslogin'), name: 'caslogin', meta: { title: 'CAS登录' } }
路由配置部分代码
/**
* 全站路由配置
*
* 建议:
* 1. 代码中路由统一使用name属性跳转(不使用path属性)
*/
import Vue from 'vue'
import Router from 'vue-router'
import http from '@/utils/httpRequest'
import { isURL } from '@/utils/validate'
Vue.use(Router)
// 开发环境不使用懒加载, 因为懒加载页面太多的话会造成webpack热更新太慢, 所以只有生产环境使用懒加载
const _import = require('./import-' + process.env.NODE_ENV)
// 全局路由(无需嵌套上左右整体布局)
const globalRoutes = [
{ path: '/404', component: _import('common/404'), name: '404', meta: { title: '404未找到' } },
{ path: '/login', component: _import('common/login'), name: 'login', meta: { title: '登录' } },
{ path: '/caslogin', component: _import('common/caslogin'), name: 'caslogin', meta: { title: 'CAS登录' } }
]
在caslogin.vue干了什么事呢,就是通过ajax请求,从后台获取token值,然后存放在cookie中,跳转到系统首页面
后台代码,在执行这段代码时要放开后台的拦截,在src->main->java->io.admin->config-->ShiroConfig中配置拦截 filterMap.put("/sys/caslogin", "anon");
/**
* cas登录
* 前端重定向到此传递登录所需token
*/
@RequestMapping("/sys/caslogin")
@ResponseBody
public Map caslogin(HttpSession session)throws IOException {
String token = (String)session.getAttribute("token");
R r = R.ok().put("token", token);
return r;
}
到这里就完成了,浏览器中输入访问该系统的单点登录入口地址,然后跳转到cas server认证中心出现登录页面,输入用户名密码认证成功后会跳转到我们定义的默认跳转的前台caslogin.vue页面,通过向后台发送获取token值的请求,成功后即进入系统首页。