单点登陆流程图html
系统登录拦截器前端
// // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // package com.jdcloud.policycloudapi.sso; import com.alibaba.fastjson.JSON; import com.jdcloud.policycloudapi.domain.response.RetResponse; import com.jdcloud.policycloudapi.domain.vo.LoginUser; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; public class SsoClientInterceptor implements HandlerInterceptor { private Logger log = LoggerFactory.getLogger(this.getClass()); private SsoProperties ssoProperties; private RemoteService remoteService; public SsoClientInterceptor(SsoProperties ssoProperties, RemoteService remoteService) { this.ssoProperties = ssoProperties; this.remoteService = remoteService; } public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException { String tokenParam = null; Cookie[] cookies = request.getCookies(); if (cookies != null) { for(int i = 0; i < cookies.length; ++i) { if (cookies[i].getName().equals("gunsToken")) { tokenParam = cookies[i].getValue(); break; } } } if(!StringUtils.isNotBlank(tokenParam)){ tokenParam=request.getParameter("gunsToken"); } if (StringUtils.isNotBlank(tokenParam)) { //验证tokenParam是否正确 Integer userId = this.remoteService.validateToken(tokenParam, HttpUtil.getRequestContextPath(request)); if (userId != null) { request.setAttribute("SESSION_LOGIN_FLAG", tokenParam); // 调用接口获取user,以及user权限列表 LoginUser loginUser=remoteService.getLoginUser(userId,tokenParam); // log.info("loginUser:"+ JSON.toJSONString(loginUser)); // RestTemplateUtils restTemplateUtils=new RestTemplateUtils(); // LoginUser loginUser = restTemplateUtils.getLoginUser(tokenParam); request.setAttribute(SsoConstants.LOGIN_USER_SESSION, loginUser); return true; } else { // this.redirectSsoServer(request, response); return responseFalse(response); } } else { // this.redirectSsoServer(request, response); return responseFalse(response); } // return true; } private boolean responseFalse(HttpServletResponse response) throws IOException { response.setCharacterEncoding("UTF-8"); response.setContentType("application/json; charset=utf-8"); PrintWriter out = null; out = response.getWriter(); out.write(JSON.toJSONString(RetResponse.retFail())); out.flush(); out.close(); return false; } private void redirectSsoServer(HttpServletRequest request, HttpServletResponse response) { String redirectUrl = this.ssoProperties.getServerUrl() + "?" + "redirectUrl" + "=" + HttpUtil.encodeUrl(HttpUtil.getRequestFullPathNoParam(request)); try { response.sendRedirect(redirectUrl); } catch (IOException var5) { this.log.error("跳转到服务器出错!", var5); } } public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { } }
SSO服务器登陆验证代码java
package com.stylefeng.sso.server.modular.controller; import com.stylefeng.guns.core.base.controller.BaseController; import com.stylefeng.guns.core.util.ToolUtil; import com.stylefeng.sso.plugin.constants.SsoConstants; import com.stylefeng.sso.plugin.service.AuthService; import com.stylefeng.sso.server.common.Rests; import com.stylefeng.sso.server.modular.entity.SysUser; import com.stylefeng.sso.server.modular.service.SysUserService; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import static com.stylefeng.sso.plugin.constants.SsoConstants.LOGOUT_URL; /** * 登陆验证控制器 * * @author stylefeng * @Date 2018/2/3 22:23 */ @Controller @Slf4j public class AuthController extends BaseController { private static final String LOGIN_TIPS = "tips"; @Autowired AuthService authService; @Autowired private SysUserService sysUserService; private boolean isMobile(HttpServletRequest request) { String userAgent = request.getHeader("User-Agent"); userAgent = userAgent.toLowerCase(); if (userAgent.contains("iphone") || userAgent.contains("android") || userAgent.contains("ipad") || userAgent.contains("ipod")) { return true; } return false; } @RequestMapping (value = "/login", method = RequestMethod.GET) public String toLogin(HttpServletRequest request) { return isMobile(request)? "/login_m.html" : "/login.html"; } @Value ("${spring.profiles.active}") private String profile; @RequestMapping (value = "/login", method = RequestMethod.POST) public String doLogin(HttpServletRequest request, HttpServletResponse response, Model model) { String returnUrl = isMobile(request)? "/login_m.html" : "/login.html"; String tokenParam = null; Cookie[] cookies = request.getCookies(); if (cookies != null) { for (int i = 0; i < cookies.length; i++) { if (cookies[i].getName().equals("gunsToken")) { tokenParam = cookies[i].getValue(); break; } } } String redirectUrl = request.getParameter(SsoConstants.REDIRECT_PARAM_NAME); // 若是cookie中能取到token,则认为从其余页面登陆,不继续登陆流程,跳回原地址 // if (StringUtils.isNotBlank(tokenParam) && StringUtils.isNotBlank(redirectUrl)){ // log.info("用户已经处于登陆状态,不继续登陆流程,跳回原地址: {}", redirectUrl); // try { // response.sendRedirect(redirectUrl); // return null; // } catch (IOException e) { // log.warn("已经登陆,跳回原地址失败", e); // model.addAttribute(LOGIN_TIPS, "网络异常!"); // return "/login.html"; // } // } String userName = request.getParameter("userName"); String password = request.getParameter("password"); // 登陆失败是记录redirectUrl model.addAttribute(SsoConstants.REDIRECT_PARAM_NAME, redirectUrl); if (ToolUtil.isEmpty(userName) || ToolUtil.isEmpty(password) || ToolUtil.isEmpty(redirectUrl)) { model.addAttribute(LOGIN_TIPS, "请求信息不完整!"); return returnUrl; } else { /** * 判断用户帐号密码是否正确 */ Integer userId = authService.checkUserLogin(userName, password); if (userId != null) { //若是帐号密码正确,跳转回业务系统的url String token = ""; try { /*SysUser sysUser = sysUserService.getSysUser(userId); sysUserService.insertLoginUserIntoRedisDto(sysUser, token);*/ token = authService.createToken(userId); } catch (Exception e) { log.warn("createToken失败",e); model.addAttribute(LOGIN_TIPS, "登陆失败,请稍后再试!"); return returnUrl; } if (profile.equals("dev")) { Cookie localhost = new Cookie(SsoConstants.TOKEN_PARAM_NAME, token); localhost.setDomain("jdcloud.com"); localhost.setPath("/"); localhost.setMaxAge(36000); response.addCookie(localhost); } else { Cookie cookie = new Cookie(SsoConstants.TOKEN_PARAM_NAME, token); cookie.setPath("/"); response.addCookie(cookie); } try { // String redirect=redirectUrl+"?"+SsoConstants.TOKEN_PARAM_NAME + "=" + token; // response.sendRedirect(redirectUrl /*+ "?" + SsoConstants.TOKEN_PARAM_NAME + "=" + token*/); response.sendRedirect(redirectUrl); return null; } catch (IOException e) { model.addAttribute(LOGIN_TIPS, "网络异常!"); return returnUrl; } } else { //若是帐号密码错误 model.addAttribute(LOGIN_TIPS, "帐号或密码错误!"); return returnUrl; } } } @ResponseBody @RequestMapping ("/hello") public String token() { return "暂未登陆"; } @RequestMapping (LOGOUT_URL) public String logout(HttpServletRequest request, HttpServletResponse response, Model model) { String tokenParam = null; Cookie[] cookies = request.getCookies(); if (cookies != null) { for (int i = 0; i < cookies.length; i++) { if (cookies[i].getName().equals("gunsToken")) { tokenParam = cookies[i].getValue(); break; } } } String redirectUrl = request.getParameter(SsoConstants.REDIRECT_PARAM_NAME); if (StringUtils.isNotBlank(tokenParam)){ // 删除redis中保存的token,若是失败,不容许退出登陆,跳回源地址 if (!authService.removeCachedToken(tokenParam)) { try { redirectUrl = redirectUrl + "?status="+SsoConstants.LOGIN_FAILED_FLAG+"?gunsToken"+tokenParam; response.sendRedirect(redirectUrl); return null; } catch (Exception e) { log.error("重定向失败", e); return "/404.html"; } } } // 删除cookie // 开发环境为了方便前端本地测试配置域名hosts,cookie选择种到二级域下;线上环境域名一致,cookie种到默认的domain下 if (profile.equals("dev")) { Cookie localhost = new Cookie(SsoConstants.TOKEN_PARAM_NAME, null); localhost.setPath("/"); localhost.setMaxAge(0); response.addCookie(localhost); } else { Cookie newCookie = new Cookie(SsoConstants.TOKEN_PARAM_NAME, null); //假如要删除名称为username的Cookie newCookie.setMaxAge(0); //当即删除型 newCookie.setPath("/"); //项目全部目录均有效,这句很关键,不然不敢保证删除 response.addCookie(newCookie); //从新写入,将覆盖以前的 } //跳转到登陆页面 model.addAttribute(SsoConstants.REDIRECT_PARAM_NAME, redirectUrl); return isMobile(request)? "/login_m.html" : "/login.html"; } }