害,Sso-server模块的认证中心已经完成,我自己逻辑很清晰,但是我感觉写的有点乱,但是别慌,我后面会提供完整的源码,Sso-server模块不懂的请参看:
单点登录-六-模块Sso-server
1.编写System-a模块,一个登录页面,同样放在templates下面,展示一下用户和唯一标识,真实需求会将ticket隐藏,并对cookie中的信息进行加密处理,后台再接密,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| <!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Title</title> <link href="//layui.hcwl520.com.cn/layui/css/layui.css?v=201811010202" rel="stylesheet"> </head> <body> <h1></h1>
<div style="padding: 20px; background-color: #F2F2F2;"> <div class="layui-row layui-col-space15"> <div class="layui-col-md12"> <div class="layui-card"> <div class="layui-card-header">系统A</div> <div class="layui-card-body"> 用户:<span th:text="${userInfo.userName}"></span>登录成功<br> ticket:<span th:text="${userInfo.ticket}"></span> </div> </div> <form class="layui-form" method="post" action="/logout"> <div class="layui-form-item"> <div class="layui-input-block"> <button class="layui-btn" lay-submit="" >退出登录</button> </div> </div> </form> </div> </div> </div>
<script src="//layui.hcwl520.com.cn/layui/layui.js?v=201811010202"></script> </body> </html>
|
2.编写控制器,由于是从session中获取,所以不需要业务层,直接获取就可以,我还写了一个退出请求,退出的时候同步清楚cookie就可以了,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
|
@Controller public class HomeController { @Autowired private RestTemplate restTemplate; @RequestMapping("/home") public String goHome(HttpSession session, Model model,HttpServletRequest request){ Object userInfo = session.getAttribute("userInfo"); System.out.println(userInfo); model.addAttribute("userInfo",session.getAttribute("userInfo")); return "home"; }
@ResponseBody @RequestMapping("/logout") @SuppressWarnings("all") public String logout(HttpServletRequest request, HttpServletResponse response) { String ticket = SsoCookieUtil.getCookie(request,"ticket"); boolean isLogout = restTemplate.getForObject(ServerConstant.SSO_URL+"logout?ticket="+ticket,Boolean.class); if(isLogout){ SsoCookieUtil.setCookie(response,"ticket","",0); return "用户已登出"; } return "登出失败"; } }
|
3.这里需要主义的是,必须写一下restTemplate的配置类,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
|
@Configuration public class RestConfig { @Bean public RestTemplate restTemplate(RestTemplateBuilder builder) { List<HttpMessageConverter<?>> converters = builder.build().getMessageConverters(); for(HttpMessageConverter<?> converter : converters){ if(converter instanceof MappingJackson2HttpMessageConverter){ try{ List<MediaType> mediaTypeList = new ArrayList<>(converter.getSupportedMediaTypes()); mediaTypeList.add(MediaType.TEXT_HTML); mediaTypeList.add(MediaType.APPLICATION_JSON); mediaTypeList.add(MediaType.valueOf(MediaType.APPLICATION_JSON_VALUE)); ((MappingJackson2HttpMessageConverter) converter).setSupportedMediaTypes(mediaTypeList); }catch(Exception e){ e.printStackTrace(); } } } return builder.build(); } }
|
4.最重要的一步,就是编写拦截器,将请求全部拦截,然后转发到拦截类里面,new LoginInterceptor()则是刚刚写的预处理,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
@Configuration public class InterceptorConfig implements WebMvcConfigurer { String[] addPathPatterns = { "/**" };
String[] excludePathPatterns = { "/user/error","/user/out" };
@Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LoginInterceptor()).addPathPatterns(addPathPatterns).excludePathPatterns(excludePathPatterns); } }
|
总结:
到这里A系统就完成,就一个从session中获取用户信息的控制器,一个登录成功返回的页面,一个拦截器和一个restTeplate配置类,测试将在后面操作,