Shiro集成kisso,搭建单点登录系统


声明:本文转载自https://my.oschina.net/qwzhang01/blog/1620564,转载目的在于传递更多信息,仅供学习交流之用。如有侵权行为,请联系我,我会及时删除。

kisso 是一个中间件,提供 cookie 搭建 java web sso 的组件式解决方案。

shiro是目前比较常用的轻量权限控制框架。

SpringBoot集成Shiro的文章比较多,我不多赘述。下面介绍SpringBoot集成kisso。

思路

  • Spring集成Shiro
  • Shiro托管项目session,使用Redis保存Shiro缓存信息
  • SpringBoot集成kisso
  • kisso单点登录同步shiro授权信息

步骤

1.SpringBoot集成Shiro

略。

2.Shiro托管项目session,使用Redis保存Shiro缓存信息

这个的详细操作过程在这个博文里介绍过了 https://my.oschina.net/qwzhang01/blog/1620339

3.SpringBoot集成kisso

    1)添加配置文件sso.properties

sso.encoding=UTF-8 sso.secretkey=Kisso4SpringBootK80mAS sso.cookie.name=uid sso.cookie.domain=canyou.xyz sso.cookie.maxage=7200 sso.login.url=http://canyou.xyz:8088/login

    2)注入kisso组件

 @Configuration public class WebAppConfig extends WebMvcConfigurerAdapter {           /**      * 注入kisso拦截器      *      * @param registry      */     @Override     public void addInterceptors(InterceptorRegistry registry) {         registry.addInterceptor(new SSOSpringInterceptor()).addPathPatterns("/**").excludePathPatterns("/login/**");         super.addInterceptors(registry);     }       /**      * 注入Kisso      *      * @return      */     @Bean(initMethod = "initKisso")     public WebKissoConfigurer webKissoConfigurer() {         WebKissoConfigurer webKissoConfigurer = new WebKissoConfigurer("sso.properties");         return webKissoConfigurer;     } } 

    3)修改登录方法,登录成功,调用kisso,将登陆信息保存在cookie中

 @RequestMapping(value = "/login/check", method = RequestMethod.POST)     public String login(@RequestParam(value = "ReturnURL", defaultValue = "") String retuenUrl, LoginUserVo user, RedirectAttributes redirectAttributes, HttpServletRequest request, HttpServletResponse response) {         if (StrUtil.hasBlank(user.getUsername(), user.getPassword(), user.getSafecode_iput())) {             redirectAttributes.addFlashAttribute("msg", "用户名或密码验证码都均能为空");             return "redirect:/login";         }         if (!CaptchaKit.validate(user.getSafecode_iput(), request)) {             redirectAttributes.addFlashAttribute("msg", "验证码错误");             return "redirect:/login";         }         User checkUser = userService.getByUserName(user.getUsername());         if (checkUser == null) {             redirectAttributes.addFlashAttribute("msg", "用户不存在,请核对后重新登录");             return "redirect:/login";         }         String encrypt = ShiroCrypt.encrypt(user.getPassword());         if (!checkUser.getPassword().equals(encrypt)) {             redirectAttributes.addFlashAttribute("msg", "密码错误,请核对后重新登录");             return "redirect:/login";         }          if (userService.login(checkUser.getUsername(), checkUser.getPassword())) {             HttpSession session = request.getSession();             session.setAttribute("username", checkUser.getUsername());             session.setAttribute("fullName", checkUser.getRealname());             // 单点登录核心代码             SSOToken ssoToken = new SSOToken();             ssoToken.setUid(user.getUsername());             ssoToken.setApp("oms");             ssoToken.setIp(IpHelper.getIpAddr(request));             // 将sessionid保存在kisso的cookie里面             ssoToken.setData(request.getSession().getId());             SSOHelper.setSSOCookie(request, response, ssoToken, false);             return "redirect:/";         }         redirectAttributes.addFlashAttribute("msg", "登陆失败");         return "redirect:/login";     }

至此,kisso集成完成。符合配置在sso.properties中的domain的域名cookie中,都会同步登陆信息。

但是目前只是把登陆信息同步在kisso里面了,对于shiro来说,不同应用之间的认证、授权信息并没有同步,因此需要在所有系统里面根据kisso,添加shiro的认证授权信息。

4.kisso单点登录同步shiro授权信息

上面已经实现了应用session由shiro托管,shiro缓存实现共享。给shiro添加filter,通过filter,对于符合kisso的单点登录条件的应用,通过kisso获取原来已经登录项目的sessionid,将其写入新应用的cookie里面,即实现将原已经授权认证的项目的shiro信息同步至新项目中。

 import cn.hutool.core.util.StrUtil; import com.baomidou.kisso.SSOHelper; import com.baomidou.kisso.SSOToken; import org.apache.shiro.web.filter.AccessControlFilter; import org.springframework.stereotype.Component;  import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;  @Component public class KissoFilter extends AccessControlFilter {      @Override     protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {         HttpServletRequest httpServletRequest = (HttpServletRequest) request;         String username = (String) httpServletRequest.getSession().getAttribute("username");         return StrUtil.isNotBlank(username);     }      @Override     protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {         SSOToken ssoToken = SSOHelper.getToken((HttpServletRequest) request);         if (ssoToken != null && ssoToken.getApp().equals("oms")) {             Cookie cookie = new Cookie("csid", ssoToken.getData());             cookie.setPath("/");             ((HttpServletResponse) response).addCookie(cookie);         }         return true;     } }

把filter注册为shiro的过滤器,过滤所有请求

@Bean     public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {         ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();         shiroFilterFactoryBean.setSecurityManager(securityManager);         Map<String, Filter> filterMap = new HashMap<>();         filterMap.put("authc_kisso", new KissoFilter());         filterMap.put("shiro_kisso", new KiSsoShiroAuthFilter());         filterMap.put("logout_kisso", new KiSsoShiroLogoutFilter());         shiroFilterFactoryBean.setFilters(filterMap);         Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();                 filterChainDefinitionMap.put("/js/**", "anon");         filterChainDefinitionMap.put("/css/**", "anon");         filterChainDefinitionMap.put("/fonts/**", "anon");         filterChainDefinitionMap.put("/login/logout", "logout_kisso");         filterChainDefinitionMap.put("/login/**", "anon");                filterChainDefinitionMap.put("/**", "authc_kisso, shiro_kisso");                shiroFilterFactoryBean.setLoginUrl("/login");         shiroFilterFactoryBean.setSuccessUrl("/index");                shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);         return shiroFilterFactoryBean;     }

传送门

本文发表于2018年02月09日 12:31
(c)注:本文转载自https://my.oschina.net/qwzhang01/blog/1620564,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除.

阅读 2739 讨论 0 喜欢 1

抢先体验

扫码体验
趣味小程序
文字表情生成器

闪念胶囊

你要过得好哇,这样我才能恨你啊,你要是过得不好,我都不知道该恨你还是拥抱你啊。

直抵黄龙府,与诸君痛饮尔。

那时陪伴我的人啊,你们如今在何方。

不出意外的话,我们再也不会见了,祝你前程似锦。

这世界真好,吃野东西也要留出这条命来看看

快捷链接
网站地图
提交友链
Copyright © 2016 - 2021 Cion.
All Rights Reserved.
京ICP备2021004668号-1