单点登录(Single Sign-On,简称SSO)是指在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。
Java实现单点登录的方法有很多种,下面给出一种基于Cookie的实现方案的完整代码:
- 首先定义一个工具类用于设置、获取、删除Cookie:
public class CookieUtil {
private static final int COOKIE_MAX_AGE = 7 * 24 * 60 * 60; // Cookie的最长有效期为7天
/**
* 设置Cookie
*
* @param response HttpServletResponse
* @param key Cookie的key
* @param value Cookie的value
*/
public static void setCookie(HttpServletResponse response, String key, String value) {
Cookie cookie = new Cookie(key, value);
cookie.setMaxAge(COOKIE_MAX_AGE);
cookie.setPath("/");
response.addCookie(cookie);
}
/**
* 获取Cookie
*
* @param request HttpServletRequest
* @param key Cookie的key
* @return Cookie的value
*/
public static String getCookie(HttpServletRequest request, String key) {
Cookie[] cookies = request.getCookies();
if (cookies == null || cookies.length == 0) {
return null;
}
for (Cookie cookie : cookies) {
if (cookie.getName().equals(key)) {
return cookie.getValue();
}
}
return null;
}
/**
* 删除Cookie
*
* @param response HttpServletResponse
* @param key Cookie的key
*/
public static void deleteCookie(HttpServletResponse response, String key) {
Cookie cookie = new Cookie(key, null);
cookie.setMaxAge(0);
cookie.setPath("/");
response.addCookie(cookie);
}
}
- 然后定义一个拦截器,用于拦截所有需要登录的请求,并判断用户是否已经登录(即判断是否存在特定的Cookie),如果已经登录则放行,否则跳转到登录页面:
public class LoginInterceptor implements HandlerInterceptor {
private static final String LOGIN_COOKIE_KEY = "login_token"; // 登录时设置的Cookie的key
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 判断用户是否已经登录
String loginToken = CookieUtil.getCookie(request, LOGIN_COOKIE_KEY);
if (loginToken != null) {
// 用户已经登录,放行
return true;
} else {
// 用户未登录,跳转到登录页面
response.sendRedirect(request.getContextPath() + "/login");
return false;
}
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
- 接着在登录页面的表单提交处理方法中设置一个特定的Cookie,用于表示用户已经登录:
public class LoginController {
private static final String LOGIN_COOKIE_KEY = "login_token"; // 登录时设置的Cookie的key
@RequestMapping("/login")
public String login(@RequestParam("username") String username,
@RequestParam("password") String password,
HttpServletResponse response) {
// TODO: 验证用户名密码是否正确
// ...
// 设置登录Cookie
String loginToken = UUID.randomUUID().toString();
CookieUtil.setCookie(response, LOGIN_COOKIE_KEY, loginToken);
// 登录成功,跳转到首页
return "redirect:/index";
}
}
- 最后在Spring Boot的配置类中注册拦截器:
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Autowired
private LoginInterceptor loginInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginInterceptor).addPathPatterns("/user/*"); // 拦截/user/目录下的所有请求
}
}
以上就是基于Cookie实现单点登录的完整代码。需要注意的是,这只是一种比较简单的实现方案,实际上还有很多细节需要考虑,例如登录Cookie的安全性、注销功能的实现、SSO的跨域支持等等。