XXL-SSO项目结构图
微服务项目整合XXL-SSO框架实现单点登录1.png

概念说明
SSO Server中央认证服务,支持集群
SSO Client接入SSO认证中心的Client应用
SSO SessionId登录用户会话ID,SSO 登录成功为用户自动分配
SSO User登录用户信息,与 SSO SessionId 相对应

官网:https://github.com/xuxueli/xxl-sso/

客户端整合

首先整合XXL-SSO服务端,导入maven依赖

<!-- xxl-sso-core -->
<dependency>
    <groupId>com.xuxueli</groupId>
    <artifactId>xxl-sso-core</artifactId>
    <version>1.1.0</version>
</dependency>

再下载好的xxl-sso框架中找到com.xxl.sso.service.config下的XxlSsoConfig类,复制到项目中

@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);
        JedisUtil.init(redisAddress);
    }

    @Override
    public void destroy() throws Exception {
        JedisUtil.close();
    }

}

xxl-sso框架中找到com.xxl.sso.service.controller下的WebController类,复制到项目中,修改之后

@Controller
public class  WebController extends BaseWebController {

    @Autowired
    private MemberServiceFeign memberServiceFeign;

    @RequestMapping("/")
    public String index(Model model, HttpServletRequest request, HttpServletResponse response) {

        // login check
        XxlSsoUser xxlUser = SsoWebLoginHelper.loginCheck(request, response);

        if (xxlUser == null) {
            return "redirect:/login";
        } else {
            model.addAttribute("xxlUser", xxlUser);
            return "index";
        }
    }

    /**
     * Login page
     *
     * @param model
     * @param request
     * @return
     */
    @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:/";
            }
        }

        model.addAttribute("errorMsg", request.getParameter("errorMsg"));
        model.addAttribute(Conf.REDIRECT_URL, request.getParameter(Conf.REDIRECT_URL));
        return "login";
    }

    /**
     * Login
     *
     * @param request
     * @param redirectAttributes
     * @param username
     * @param password
     * @return
     */
    @RequestMapping("/doLogin")
    public String doLogin(HttpServletRequest request,
                          HttpServletResponse response,
                          RedirectAttributes redirectAttributes,
                          String username,
                          String password,
                          String ifRemember) {

        boolean ifRem = (ifRemember!=null&&"on".equals(ifRemember))?true:false;

        // valid login 默认代码
//        ReturnT<UserInfo> result = userService.findUser(username, password);
//        if (result.getCode() != ReturnT.SUCCESS_CODE) {
//            redirectAttributes.addAttribute("errorMsg", result.getMsg());
//
//            redirectAttributes.addAttribute(Conf.REDIRECT_URL, request.getParameter(Conf.REDIRECT_URL));
//            return "redirect:/login";
//        }

        //修改之后代码开始
        //认证授权中心调用会员接口
        UserLoginInpDTO userLoginInpDTO = new UserLoginInpDTO();
        //设置帐号
        userLoginInpDTO.setMobile(username);
        //设置密码
        userLoginInpDTO.setPassword(password);
        //设置设备信息
        String info = webBrowserInfo(request);
        userLoginInpDTO.setDeviceInfor(info);
        //设置登录类型
        userLoginInpDTO.setLoginType(Constants.MEMBER_LOGIN_TYPE_PC);
        //调用sso单点登录接口
        BaseResponse<UserOutDTO> ssoLogin = memberServiceFeign.ssoLogin(userLoginInpDTO);
        //如果等于空或者500
        if (!isSuccess(ssoLogin)){
            redirectAttributes.addAttribute("errorMsg", ssoLogin.getMsg());
            redirectAttributes.addAttribute(Conf.REDIRECT_URL, request.getParameter(Conf.REDIRECT_URL));
            return "redirect:/login";
        }
        //获取用户信息
        UserOutDTO data = ssoLogin.getData();
        //
        System.out.println("ssoLogin.getMsg():"+ssoLogin.getMsg());
        if (data == null){
            redirectAttributes.addAttribute("errorMsg", ssoLogin.getMsg());
            redirectAttributes.addAttribute(Conf.REDIRECT_URL, request.getParameter(Conf.REDIRECT_URL));
            return "redirect:/login";
        }
        //修改的代码结束
        //默认代码
        XxlSsoUser xxlUser = new XxlSsoUser();
        System.out.println("xxlUser"+xxlUser);
        xxlUser.setUserid(String.valueOf(data.getUserId()));
        xxlUser.setUsername(data.getMobile());
        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);

        // 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:/";
        }

    }

    /**
     * Logout
     *
     * @param request
     * @param redirectAttributes
     * @return
     */
    @RequestMapping(Conf.SSO_LOGOUT)
    public String logout(HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes) {

        // logout
        SsoWebLoginHelper.logout(request, response);

        redirectAttributes.addAttribute(Conf.REDIRECT_URL, request.getParameter(Conf.REDIRECT_URL));
        return "redirect:/login";
    }
    
}

通过feign客户端调用会员服务

/**
 * @author songzixian
 * @create 2019-10-14 下午 5:54
 */
@FeignClient("app-songzixian-member")
public interface MemberServiceFeign extends MemberService {
}

然后把resources文件下的静态资料复制到项目zhon
微服务项目整合XXL-SSO框架实现单点登录2.png
修改application.yml文件

spring:
  application:
    name: app-shop-xxl-sso-server
  freemarker:
    settings:
      number_format: 0.##########
    charset: UTF-8
    request-context-attribute: request
    templateLoaderPath: classpath:/templates/
    suffix: .ftl
  resources:
    static-locations: classpath:/static/
  mvc:
    static-path-pattern: /static/**
###服务注册到eureka地址
eureka:
  client:
    service-url:
           defaultZone: http://localhost:8100/eureka   
server:
#  context-path: /xxl-sso-server
  port: 8888
  servlet:
    context-path: /xxl-sso-server

xxl:
  sso:
    redis:
      address: redis://192.168.153.131:6379
      expire:
        minite: 1440

然后服务端就整合完毕了
访问:http://ip:端口号/xxl-sso-server/login
微服务项目整合XXL-SSO框架实现单点登录3.png

服务端整合

整合XXL-SSO客户端端,导入maven依赖

<!--spring session 与redis应用基本环境配置,需要开启redis后才可以使用-->
<dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session-data-redis</artifactId>
</dependency>
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
</dependency>
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
</dependency>
<!-- xxl-sso -->
<dependency>
    <groupId>com.xuxueli</groupId>
    <artifactId>xxl-sso-core</artifactId>
    <version>1.1.0</version>
</dependency>

复制com.xxl.sso.sample.config包下的XxlSsoConfig类到项目中

@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();
    }

}

配置redis服务器的连接

//这个类用配置redis服务器的连接
//maxInactiveIntervalInSeconds为SpringSession的过期时间(单位:秒)
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 1800)
public class SessionConfig {

    // 冒号后的值为没有配置文件时,制动装载的默认值
    @Value("${redis.hostname:localhost}")
    String hostName;
    @Value("${redis.port:6379}")
    int port;

    @Bean
    public JedisConnectionFactory connectionFactory() {
        JedisConnectionFactory connection = new JedisConnectionFactory();
        connection.setPort(port);
        connection.setHostName(hostName);
        return connection;
    }
}

修改application.yml文件

#### 整合freemarker
spring:
    freemarker:
        cache: false
        charset: UTF-8
        check-template-location: true
        content-type: text/html
        expose-request-attributes: true
        expose-session-attributes: true
        request-context-attribute: request
        suffix: .ftl
        template-loader-path:
        - classpath:/templates
    application:
        name: szx-shop-portal-pay
###服务注册到eureka地址
eureka:
  client:
    service-url:
           defaultZone: http://localhost:8100/eureka
server:
  port: 8081

redis:
    hostname: 192.168.153.131
    port: 6379
    password:

xxl-sso:
  excluded:
    paths:

xxl:
  sso:
    server: http://xxlssoserver.com:8888/xxl-sso-server
    logout:
      path: /logout
    redis:
      address: redis://192.168.153.131:6379

然后sso单点登录客户端配置完毕

Last modification:October 19, 2019
如果觉得这篇技术文章对你有用,请随意赞赏