1.環境信息
Springboot 2.2.0
thymeleaf
2.CAS Server關鍵代碼
2.1攔截器
public class LoginHandlerInterceptor implements HandlerInterceptor {
private final Logger logger = LoggerFactory.getLogger(LoginHandlerInterceptor.class);
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession session = request.getSession();
Object userName = session.getAttribute("userInfo");
//如果session中有數據,說明已登錄,則頒發token重定向到來源服務
if(userName!=null){
logger.info("LoginHandlerInterceptor.preHandle get userInfo from session success!");
String bizServiceUrl = request.getParameter("bizServiceUrl");
if(bizServiceUrl != null){
String casTicket = simpleEnAndDeCode((String)userName);
String redirectUrl = bizServiceUrl+(bizServiceUrl.contains("?")?"&":"?")+"casTicket="+casTicket;
response.sendRedirect(redirectUrl);
return true;
}
return true;
}{
//如果session中沒有用戶數據,則轉移到登錄界面 request.getRequestDispatcher("/loginpage").forward(request,response);
return true;
}
}
}
2.2攔截路徑配置
@Configuration
public class MyWebMvcConfigurer implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
//登錄界面loginpage、用戶密碼校驗login、校驗token的路徑放行validate
registry.addInterceptor(new LoginHandlerInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/loginpage","/login","/validate")
.excludePathPatterns("/css/**","/fonts/**","/js/**");;
}
}
2.3登錄controller
@Controller
public class LoginController {
private final Logger logger = LoggerFactory.getLogger(LoginController.class);
// 映射"/"請求
@RequestMapping({"/","/loginpage"})
public String loginPage(Model model,@RequestParam("bizServiceUrl") String bizServiceUrl) {
System.out.println("HomepageController loginpage方法被調用......");
model.addAttribute("bizServiceUrl", bizServiceUrl);
// 根據Thymeleaf默認模板,將返回resources/templates/loginpage.html
return "loginpage";
}
//校驗用戶名、密碼
@PostMapping("/login")
public String login(Model model, HttpServletRequest request,HttpServletResponse response,@RequestParam("bizServiceUrl") String bizServiceUrl, @RequestParam("loginName") String userName, @RequestParam("password") String password) throws IOException, NoSuchAlgorithmException {
//TO DO:校驗userName和password
boolean validate = true;
if(validate){
HttpSession session = request.getSession(true);
session.setAttribute("userInfo",userName);
logger.info("login success");
String casTicket = simpleEnAndDeCode(userName);
String redirectUrl = bizServiceUrl+(bizServiceUrl.contains("?")?"&":"?")+"casTicket="+casTicket;
response.sendRedirect(redirectUrl);
model.addAttribute("userName", userName);
return "homepage";
}else{
return "loginpage";
}
}
//校驗用戶名、密碼
@GetMapping("/validate")
@ResponseBody
public String validate(HttpServletRequest request,HttpServletResponse response,@RequestParam("casTicket") String casTicket) throws IOException, NoSuchAlgorithmException {
//TO DO:校驗casTicket
String userName = simpleEnAndDeCode(casTicket);
boolean validate = true;
if(validate){
return userName;
}else{
return "";
}
}
}
3.ServerA關鍵代碼
3.1攔截器
@Component
public class LoginHandlerInterceptor implements HandlerInterceptor {
private final Logger logger = LoggerFactory.getLogger(LoginHandlerInterceptor.class);
@Autowired
private RestTemplate restTemplate;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession session = request.getSession();
boolean needLogin = false;
boolean needValidate = false;
String ticket = request.getParameter("casTicket");
Object userInfo = session.getAttribute("userInfo");
String casServer = "http://local.cas.com:8088";
String currentServer = "http://local.servera.com:8091";
String casValidateUrl = casServer+"/validate";
//session中已經有值,則放行
if(userInfo!=null){
return true;
}else{
//session中沒值
if(ticket==null){
//沒有ticket,則需重新登錄
response.sendRedirect(casServer+"?bizServiceUrl="+currentServer);
return true;
}else{
//有ticket,則需找CAS Server驗證
String userName = restTemplate.getForObject(casValidateUrl+"?casTicket="+ticket,String.class);
if(userName==null || userName.equals("")){
//認證失敗,需要重新登錄
response.sendRedirect(casServer+"?bizServiceUrl="+currentServer);
return false;
}
session.setAttribute("userInfo",userName);
return true;
}
}
}
}
4.補充說明
- 用戶、密碼校驗存在DB或redis,校驗可自行實現
- token生成和校驗可採用JWT實現
- CAS也可直接使用官網提供的WAR包實現,本文僅爲學習之用