当前位置:网站首页>XXL-SSO 实现SSO单点登录

XXL-SSO 实现SSO单点登录

2022-06-23 05:37:00 zetor_major

一、 概述:

本文旨在使用XXL-SSO开源架构 实现单点登录系统。

XXL-SSO 是一个分布式单点登录框架、只需要登录一次就可以访问所有相互信任的应用系统。

拥有”轻量级、分布式、跨域、Cookie+Token均支持、Web+APP均支持”等特性。现已开放源代码,开箱即用。

官网地址:https://www.xuxueli.com/xxl-sso/#/

二、 准备:

  • 下载XXL-SSO

https://github.com/xuxueli/xxl-sso
https://gitee.com/xuxueli0323/xxl-sso

安装 xxl-sso-core-1.1.0.jar 到maven仓库:

mvn install:install-file -Dfile=D:/yourpath/xxl-sso-core-1.1.0.jar -DgroupId=com.xuxueli -DartifactId=xxl-sso-core -Dversion=1.1.0 -Dpackaging=jar

  • 安装redis、并启动...
  • 执行sql脚本:mysql创建用户表等相关操作,详细参考文末代码

三、实现单点登录服务端:

1)使用架构:

  1. springboot
  2. mybatisPlus  for mysql
  3. swagger
  4. xxl-sso

2)代码参考如下:

  •  pom.xml
        <!-- sso core -->
        <dependency>
            <groupId>com.xuxueli</groupId>
            <artifactId>xxl-sso-core</artifactId>
            <version>1.1.0</version>
        </dependency>
        <!-- jedis -->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.9.0</version>
        </dependency>
  • XxlSsoConfig.java
    @Configuration
    public class XxlSsoConfig implements InitializingBean, DisposableBean {
    
        @Value("${xxl.sso.redis.address}")
        private String redisAddress;
    
        @Value("${xxl.sso.redis.expire.minite}")
        private int redisExpireMinite;
    
        @Override
        public void afterPropertiesSet() throws Exception {
            SsoLoginStore.setRedisExpireMinite(redisExpireMinite);
            SsoTokenLoginHelper.setRedisExpireMinite(redisExpireMinite);
            JedisUtil.init(redisAddress);
        }
    
        @Override
        public void destroy() throws Exception {
            JedisUtil.close();
        }
    
    }
  • 登录页初始化
    @RequestMapping(Conf.SSO_LOGIN)
    public String login(Model model, HttpServletRequest request, HttpServletResponse response) {

        // login check
        XxlSsoUser xxlUser = SsoWebLoginHelper.loginCheck(request, response);
        if (xxlUser != null) {
            // success redirect
            String redirectUrl = request.getParameter(Conf.REDIRECT_URL);
            if (redirectUrl != null && redirectUrl.trim().length() > 0) {

                String sessionId = SsoWebLoginHelper.getSessionIdByCookie(request);
                String redirectUrlFinal = redirectUrl + "?" + Conf.SSO_SESSIONID + "=" + sessionId;
                return "redirect:" + redirectUrlFinal;
            } else {
                return "redirect:/";
            }
        }
        // 查询账套(自定义查询)
        List<TSystemSob> sobs = sysUserService.qrySobLst();
        model.addAttribute("sobs", sobs);
        model.addAttribute("errorMsg", request.getParameter("errorMsg"));
        model.addAttribute(Conf.REDIRECT_URL, request.getParameter(Conf.REDIRECT_URL));
        return "login";
    }
  • 登录动作
@RequestMapping("/doLogin")
    public String doLogin(HttpServletRequest request,
                          HttpServletResponse response,
                          RedirectAttributes redirectAttributes,
                          @RequestParam String username,
                          @RequestParam String password,
                          @RequestParam Integer sob,
                          String ifRemember) {

        boolean ifRem = (ifRemember != null && "on".equals(ifRemember)) ? true : false;
        redirectAttributes.addAttribute(Conf.REDIRECT_URL, request.getParameter(Conf.REDIRECT_URL));
        // valid login
        TSysUser usr = sysUserMapper.qryOne(username, sob);
        if (usr == null) {
            redirectAttributes.addAttribute("errorMsg", "用户不存在!");
            return "redirect:/login";
        }
        if (!Md5Util.isMatchPassword(password.trim(), usr.getPassword())) {
            redirectAttributes.addAttribute("errorMsg", "用户名或密码错误!");
            return "redirect:/login";
        }
        // 1、make xxl-sso user
        XxlSsoUser xxlUser = new XxlSsoUser();
        xxlUser.setUserid(String.valueOf(usr.getAccount()));
        xxlUser.setUsername(usr.getRealName());
        xxlUser.setVersion(UUID.randomUUID().toString().replaceAll("-", ""));
        xxlUser.setExpireMinite(SsoLoginStore.getRedisExpireMinite());
        xxlUser.setExpireFreshTime(System.currentTimeMillis());

        // 2、make session id
        String sessionId = SsoSessionIdHelper.makeSessionId(xxlUser);
        // 3、login, store storeKey + cookie sessionId
        SsoWebLoginHelper.login(response, sessionId, xxlUser, ifRem, redisExpireMinite * 60);
        // 4、return, redirect sessionId
        String redirectUrl = request.getParameter(Conf.REDIRECT_URL);
        if (redirectUrl != null && redirectUrl.trim().length() > 0) {
            String redirectUrlFinal = redirectUrl + "?" + Conf.SSO_SESSIONID + "=" + sessionId;
            return "redirect:" + redirectUrlFinal;
        } else {
            return "redirect:/";
        }
    }
  • 退出登录
    @RequestMapping(Conf.SSO_LOGOUT)
    public String logout(HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes) {
        // logout
        SsoWebLoginHelper.logout(request, response);
        // del sessionData
        removeStorageData(request);
        redirectAttributes.addAttribute(Conf.REDIRECT_URL, request.getParameter(Conf.REDIRECT_URL));
        return "redirect:/login";
    }
  • 登录页面( freemarker模板文件 
<form action="${request.contextPath}/doLogin">
        <div class="login-box-body">
            <p class="login-box-msg">统一认证中心</p>
            <div class="form-group has-feedback">
                <input type="text" name="username" class="form-control" placeholder="Please input username."
                       value="admin" maxlength="50">
                <span class="glyphicon glyphicon-envelope form-control-feedback"></span>
            </div>
            <div class="form-group has-feedback">
                <input type="password" name="password" class="form-control" placeholder="Please input password."
                       value="123456" maxlength="50">
                <span class="glyphicon glyphicon-lock form-control-feedback"></span>
            </div>
            <div class="form-group">
                <select class="form-control input-s-sm inline" name="sob">
                    <#list sobs as ss>
                    <option value="${ss.id}">${ss.sobName}</option>
                    </#list>
                </select>
            </div>
            <#if errorMsg?exists>
                <p style="color: red;">${errorMsg}</p>
            </#if>
            <div class="row">
                <div class="col-xs-8">
                    <div class="checkbox icheck">
                        <label>
                            <input type="checkbox" name="ifRemember">记住密码
                        </label>
                    </div>
                </div><!-- /.col -->
                <div class="col-xs-4">
                    <input type="hidden" name="redirect_url" value="${redirect_url!''}"/>
                    <button type="submit" class="btn btn-primary btn-block btn-flat">Login</button>
                </div>
            </div>
        </div>
    </form>

 


四、实现客户端:

  • 配置文件
@Configuration
public class XxlSsoConfig implements DisposableBean {


    @Value("${xxl.sso.server}")
    private String xxlSsoServer;

    @Value("${xxl.sso.logout.path}")
    private String xxlSsoLogoutPath;

    @Value("${xxl.sso.excluded.paths}")
    private String xxlSsoExcludedPaths;

    @Value("${xxl.sso.redis.address}")
    private String xxlSsoRedisAddress;


    @Bean
    public FilterRegistrationBean xxlSsoFilterRegistration() {

        // xxl-sso, redis init
        JedisUtil.init(xxlSsoRedisAddress);

        // xxl-sso, filter init
        FilterRegistrationBean registration = new FilterRegistrationBean();

        registration.setName("XxlSsoWebFilter");
        registration.setOrder(1);
        registration.addUrlPatterns("/*");
        registration.setFilter(new XxlSsoWebFilter());
        registration.addInitParameter(Conf.SSO_SERVER, xxlSsoServer);
        registration.addInitParameter(Conf.SSO_LOGOUT_PATH, xxlSsoLogoutPath);
        registration.addInitParameter(Conf.SSO_EXCLUDED_PATHS, xxlSsoExcludedPaths);

        return registration;
    }

    @Override
    public void destroy() throws Exception {

        // xxl-sso, redis close
        JedisUtil.close();
    }

}
  • 首页跳转
    @RequestMapping("/")
    public String index(Model model, HttpServletRequest request) {

        XxlSsoUser xxlUser = (XxlSsoUser) request.getAttribute(Conf.SSO_USER);
        model.addAttribute("xxlUser", xxlUser);
        return "index";
    }

五、启动程序

启动顺序1. SSOServerApp、2.ClientApp

客户端port:8088

服务端port:8086

在浏览器地址栏输入:http://127.0.0.1:8088/client

完成跳转,如图

注:账套为本人自定义信息,可酌情删除。

用户名:admin   、密码:123456

登录成功:

六、备注:

以上即实现了xxl-sso架构的单点登录系统,由于架构较轻量,即功能性单一,不过扩展较方便。

本文在xxl-sso-core核心包中,做了几处简单修改,旨在实现登出跳转,打印log等功能,喜欢扩展的朋友可自行修改。

 


本文源码地址:

https://gitee.com/zetor2020/ym-paas-sso-xxl   

下载代码的朋友点下star,多谢支持

点赞本文,再次感谢

 

 

原网站

版权声明
本文为[zetor_major]所创,转载请带上原文链接,感谢
https://blog.csdn.net/z2926781/article/details/108995525