XXL-SSO项目结构图
概念 | 说明 |
---|---|
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
修改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客户端端,导入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单点登录客户端配置完毕