单点登录云平台子系统集成方式

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
函数计算FC,每月15万CU 3个月
应用实时监控服务-用户体验监控,每月100OCU免费额度
简介: 单点登录云平台子系统集成方式

单点登录云平台子系统集成方式

 

 

后台集成:

1. 在pom中添加单点登录客户端支持


   cn.dev33
   sa-token-spring-boot-starter
   1.31.0


   cn.dev33
   sa-token-sso
   1.31.0


   cn.dev33
   sa-token-dao-redis
   1.31.0


   org.apache.commons
   commons-pool2



   com.alibaba
   fastjson
   1.2.4

2. 修改application.yml 添加如下内容

spring:
 # redis配置 如果框架在集成前有连接则无需添加,如没有则加入
 redis:
   # Redis数据库索引(默认为0
   database: 1
   # Redis服务器地址
   host: 49.235.237.65
   # Redis服务器连接端口
   port: 6379
   # Redis服务器连接密码(默认为空)
   password: '!1qaz@2WSX'
   # 连接超时时间
   timeout: 10s
   lettuce:
     pool:
       # 连接池最大连接数
       max-active: 200
       # 连接池最大阻塞等待时间(使用负值表示没有限制)
       max-wait: -1ms
       # 连接池中的最大空闲连接
       max-idle: 10
       # 连接池中的最小空闲连接
       min-idle: 0


# sa-token配置
sa-token:
 token-name: X-Token
 # SSO-相关配置
 sso:
   # SSO-Server端 统一认证地址
   auth-url: http://114.116.5.89:8081/ltCloud_manage/sso/auth
   # 是否打开单点注销接口
   is-slo: true

 # 配置Sa-Token单独使用的Redis连接 (此处需要和SSO-Server端连接同一个Redis
 alone-redis:
   # Redis数据库索引 (默认为0)
   database: 1
   # Redis服务器地址
   host: 49.235.237.65
   # Redis服务器连接端口
   port: 6379
   # Redis服务器连接密码(默认为空)
   password: '!1qaz@2WSX'

 

 

3. SsoClientController.java放入Controller包下。

CommonExceptionHandler.java覆盖到common.exceptionHandler包的同名文件。

LoginInterceptor.java 覆盖到interceptor包下

SaTokenConfigure.java拷贝至interceptor包下

4. 检查SpringBootServletInitializer类的buildConfig方法,AllowCredentials值要为true,如下图:

image.png

 

 

 

 

前台集成

1. 所有请求的header里添加client-url参数,值为location.href(当前地址栏),如下图:

image.png

添加后的结果如下图:

image.png

 

 

 

2. 判断所有后台响应的状态码 为50102或50101(两个状态码都说明登录异常),

如出现此情况,将浏览器重定向至返回参数中data. clientLoginUrl的地址,程序会跳转至sso进行登录验证,并自动返回至当前页面。

image.png

 

 

 

 

 

注意事项:

1. 该方案为临时方案,需集成至本司框架下。

2. 使用时需先在http://114.116.5.89:8081/cloudmanage登录,登录后即可将子项目登录成功。

3. 子项目登录成功后,可以通过StpUtil.getLoginId()的静态方法获得登录用户id

4. 请保持网络连接;请保持自己开发的项目前后端在同一个域,但可以不同端口(例如,前端是http://localhost:8080,后端是http://localhost:8081,但不可以是前端http://localhost:8080,后端http://127.0.0.1:8081



所需文件:

CommonExceptionHandler.java:

package com.todod.ltcloud.manage.common.exceptionHandler;

import java.util.List;

import cn.dev33.satoken.context.SaHolder;

import cn.dev33.satoken.util.SaFoxUtil;

import com.alibaba.fastjson.JSONObject;

import com.todod.ltcloud.manage.exception.BusinessException;

import com.todod.ltcloud.manage.exception.LoginExpiredException;

import com.todod.ltcloud.manage.exception.LoginOutException;

import com.todod.ltcloud.manage.exception.SingleLoginException;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.validation.BindException;

import org.springframework.validation.FieldError;

import org.springframework.validation.ObjectError;

import org.springframework.web.HttpRequestMethodNotSupportedException;

import org.springframework.web.bind.MethodArgumentNotValidException;

import org.springframework.web.bind.annotation.ControllerAdvice;

import org.springframework.web.bind.annotation.ExceptionHandler;

import org.springframework.web.bind.annotation.ResponseBody;

import org.springframework.web.client.RestClientException;

/**

* 统一异常处理

*

* @author gsh

* @version 创建时间:2018年11月30日 下午5:25:35

*/

@ControllerAdvice

public class CommonExceptionHandler {

   Logger log = LoggerFactory.getLogger(this.getClass());

   /**

    * 参数校验失败

    *

    * @param ex

    * @return

    * @Title: handleBindException

    * @Description:

    * @author gsh

    * @date 2019年8月13日

    */

   @ExceptionHandler(BindException.class)

   @ResponseBody

   public ResultData handleBindException(BindException ex) {

       // ex.getFieldError():随机返回一个对象属性的异常信息。如果要一次性返回所有对象属性异常信息,则调用ex.getAllErrors();

       FieldError fieldError = ex.getFieldError();

       log.warn("参数校验失败异常:-----------------" + fieldError.getDefaultMessage());

       return ResultData.error(ResultData.PARAM_ERROR_CODE, fieldError.getDefaultMessage());

   }

   /**

    * 参数校验失败

    *

    * @param ex

    * @return

    * @Title: handleBindException

    * @Description:

    * @author gsh

    * @date 2020年7月15日

    */

   @ExceptionHandler(MethodArgumentNotValidException.class)

   @ResponseBody

   public ResultData handleBindException(MethodArgumentNotValidException ex) {

       List errors = ex.getBindingResult().getAllErrors();

       String message = "参数不合法";

       if (errors.size() > 0) {

           message = errors.get(0).getDefaultMessage();

       }

       log.warn("参数校验失败异常:-----------------" + message);

       return ResultData.error(ResultData.PARAM_ERROR_CODE, message);

   }

   /**

    * 请求方式不正确

    *

    * @param e

    * @return

    * @Title: exceptionHandler

    * @Description:

    * @author gsh

    * @date 2019年10月14日

    */

   @ExceptionHandler(HttpRequestMethodNotSupportedException.class)

   @ResponseBody

   public ResultData exceptionHandler(HttpRequestMethodNotSupportedException e) {

       log.warn("请求方式不正确", e.getMessage());

       return ResultData.error(ResultData.METHOD_NOT_SUPPORTED, e.getMessage());

   }

   /**

    * 拦截Exception类的异常

    *

    * @param e

    * @return

    */

   @ExceptionHandler(Exception.class)

   @ResponseBody

   public ResultData exceptionHandler(Exception e) {

       log.error("error-info", e);

       return ResultData.error("系统异常");

   }

   /**

    * restTemplate 请求异常

    *

    * @param e

    * @return

    * @Title: exceptionHandler

    * @Description:

    * @author gsh

    * @date 2019年10月15日

    */

   @ExceptionHandler(RestClientException.class)

   @ResponseBody

   public ResultData exceptionHandler(RestClientException e) {

       log.error("error-info", e);

       return ResultData.error(ResultData.REQUEST_INTERFACE_ERROE_CODE, "请求接口异常:" + e.getMessage());

   }

   /**

    * @param e

    * @return

    * @return Map

    * @Title: exceptionHandler

    * @Description: 自定义异常处理

    * @author:gsh

    * @date: 2018年11月30日

    */

   @ExceptionHandler(BusinessException.class)

   @ResponseBody

   public ResultData exceptionHandler(BusinessException e) {

       log.warn("自定义异常:-----------------" + e.getMessage());

       return ResultData.error(ResultData.ESTIMATE_ERROR_CODE, e.getMessage());

   }

   /**

    * 用户登陆过期

    *

    * @param e

    * @return

    * @Title: exceptionHandler

    * @Description:

    * @author gsh

    * @date 2019年10月11日

    */

   @ExceptionHandler(LoginExpiredException.class)

   @ResponseBody

   public ResultData exceptionHandler(LoginExpiredException e) {

       JSONObject data = new JSONObject();

       String host = SaHolder.getRequest().getUrl().replaceAll(SaHolder.getRequest().getRequestPath(), "");

       String clientLoginUrl = host + "/sso/login?back=" + SaFoxUtil.encodeUrl(SaHolder.getRequest().getHeader("client-url"));

       data.put("clientLoginUrl", clientLoginUrl);

       //SaHolder.getRequest().getHeader("client-url")

       return ResultData.error(ResultData.USER_LOGIN_EXPIRED, e.getMessage(), data);

   }

   /**

    * 用户未过期

    *

    * @param e

    * @return

    * @Title: exceptionHandler

    * @Description:

    * @author gsh

    * @date 2019年10月11日

    */

   @ExceptionHandler(LoginOutException.class)

   @ResponseBody

   public ResultData exceptionHandler(LoginOutException e) {

       return ResultData.error(ResultData.USER_NOT_LOGIN, e.getMessage());

   }

   /**

    * 单用户登录异常

    *

    * @param e

    * @return

    * @Title: exceptionHandler

    * @Description:

    * @author gsh

    * @date 2019年10月11日

    */

   @ExceptionHandler(SingleLoginException.class)

   @ResponseBody

   public ResultData exceptionHandler(SingleLoginException e) {

       return ResultData.error(ResultData.SINGLE_LOGIN_ERROR, e.getMessage());

   }

}


LoginInterceptor.java:

package com.todod.ltcloud.manage.interceptor;

import java.lang.reflect.Method;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import cn.dev33.satoken.stp.StpUtil;

import com.todod.ltcloud.manage.annotaion.NotLogging;

import com.todod.ltcloud.manage.exception.LoginExpiredException;

import com.todod.ltcloud.manage.exception.LoginOutException;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.stereotype.Component;

import org.springframework.web.method.HandlerMethod;

import org.springframework.web.servlet.HandlerInterceptor;

import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

public class LoginInterceptor implements HandlerInterceptor {

Logger log = LoggerFactory.getLogger(LoginInterceptor.class);

@Override

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)

  throws Exception {

 if (handler instanceof HandlerMethod) {

  HandlerMethod hm = (HandlerMethod) handler;

  Method m = hm.getMethod();

  if (m.isAnnotationPresent(NotLogging.class)) { // 不需登陆

   return true;

  }

  // 需要登陆

//   String token = request.getHeader("X-Token"); // 取得token

//

//   if (StringUtils.isBlank(token)) {

//    throw new LoginOutException("未登录");

//   }

  try {

   // 校验token

//    String userId = EncryptUtil.decrypt(token);

   if (StpUtil.isLogin()) {

    request.setAttribute("_userId", StpUtil.getLoginId());// 添加用户id

    return true;

   } else {

    throw new LoginOutException("未登录");

   }

  } catch (Exception e) {

   throw new LoginExpiredException("登陆过期");

  }

 }

 return true;

}

}


SaTokenConfigure.java:

package com.todod.ltcloud.manage.interceptor;

import cn.dev33.satoken.context.SaHolder;

import cn.dev33.satoken.filter.SaServletFilter;

import cn.dev33.satoken.router.SaRouter;

import cn.dev33.satoken.spring.SpringMVCUtil;

import cn.dev33.satoken.stp.StpUtil;

import cn.dev33.satoken.util.SaFoxUtil;

import com.todod.ltcloud.manage.interceptor.LoginInterceptor;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.web.servlet.config.annotation.InterceptorRegistry;

import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration

public class SaTokenConfigure implements WebMvcConfigurer {

   @Override

   public void addInterceptors(InterceptorRegistry registry) {

       //加载登录适配器

       registry.addInterceptor(new LoginInterceptor())

               .excludePathPatterns("/sso/*");

   }

//    @Bean

//    public SaServletFilter getSaServletFilter() {

//        return new SaServletFilter()

//                .addInclude("/**")

//                .addExclude("/sso/*", "/favicon.ico")

//                .setAuth(obj -> {

////                    if(StpUtil.isLogin() == false) {

////                        String back = SaFoxUtil.joinParam(SaHolder.getRequest().getUrl(), SpringMVCUtil.getRequest().getQueryString());

////                        SaHolder.getResponse().redirect("/sso/login?back=" + SaFoxUtil.encodeUrl(back));

////                        SaRouter.back();

////                    }

//                });

//    }

}


SsoClientController.java:

package com.todod.ltcloud.manage.controller;

import cn.dev33.satoken.sso.SaSsoHandle;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

/**

* Sa-Token-SSO Client端 Controller

*/

@RestController

public class SsoClientController {

   /*

    * SSO-Client端:处理所有SSO相关请求

    */

   @RequestMapping("/sso/*")

   public Object ssoRequest() {

       return SaSsoHandle.clientRequest();

   }

}


目录
相关文章
|
7月前
|
安全 Java 数据安全/隐私保护
在Java项目中集成单点登录(SSO)方案
在Java项目中集成单点登录(SSO)方案
|
7月前
|
安全 Java 数据安全/隐私保护
在Java项目中集成单点登录(SSO)方案
在Java项目中集成单点登录(SSO)方案
|
移动开发 数据安全/隐私保护
钉钉可以集成企业内网部署的网盘系统实现账号单点登录吗?
最近接到客户的咨询,他们近期在公司局域网里部署了一套文档管理系统(一般叫私有网盘),领导希望平时通过手机钉钉就能访问到这套系统。客户就有些为难,钉钉是部署在公有云互联网环境的,而这套文档管理系统是部署在企业内网的,看上去应该打通不了,于是前来求助。
343 1
淘东电商项目(34) -SSO单点登录(Client端集成)
淘东电商项目(34) -SSO单点登录(Client端集成)
67 0
|
Java Maven
淘东电商项目(32) -SSO单点登录(集成SSO认证服务)
淘东电商项目(32) -SSO单点登录(集成SSO认证服务)
95 0
|
SQL 安全 NoSQL
告别shiro-cas单点登录集成库,这款简单且强壮的Java Web安全引擎pac4j你值得拥有
告别shiro-cas单点登录集成库,这款简单且强壮的Java Web安全引擎pac4j你值得拥有
548 0
告别shiro-cas单点登录集成库,这款简单且强壮的Java Web安全引擎pac4j你值得拥有
|
Java 关系型数据库 应用服务中间件