Skip to content

Commit

Permalink
resolve #41
Browse files Browse the repository at this point in the history
支持单用户登录
  • Loading branch information
kawhii committed Nov 29, 2017
1 parent bd5eaec commit 437272b
Show file tree
Hide file tree
Showing 11 changed files with 260 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
* 验证码发送、校验(注册发送邮箱验证码)
* 服务监控检测
* 校验码登录
* 单用户登录

## Tutorial: [![Csdn Blog Tutorial](https://img.shields.io/badge/csdn%20blog-tutorial-orange.svg)](http://blog.csdn.net/u010475041/article/category/7156505)

Expand Down
6 changes: 6 additions & 0 deletions sso-server/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@
<artifactId>sso-support-custom-auth</artifactId>
<version>${project.version}</version>
</dependency>
<!--单用户登录-->
<dependency>
<groupId>com.carl.auth</groupId>
<artifactId>sso-support-single-login</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.carl.auth</groupId>
<artifactId>sso-support-captcha</artifactId>
Expand Down
1 change: 1 addition & 0 deletions sso-support/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
<module>sso-support-custom-auth</module>
<module>sso-support-captcha</module>
<module>sso-support-validate</module>
<module>sso-support-single-login</module>
</modules>


Expand Down
1 change: 1 addition & 0 deletions sso-support/sso-support-single-login/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
单用户登录,用户踢出
42 changes: 42 additions & 0 deletions sso-support/sso-support-single-login/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 版权所有.(c)2008-2017. 卡尔科技工作室
-->

<!--
~ 版权所有.(c)2008-2017. 卡尔科技工作室
-->

<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>sso-support</artifactId>
<groupId>com.carl.auth</groupId>
<version>1.7.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>sso-support-single-login</artifactId>


<dependencies>
<dependency>
<groupId>org.apereo.cas</groupId>
<artifactId>cas-server-core-configuration</artifactId>
<version>${cas.version}</version>
</dependency>
<dependency>
<groupId>org.apereo.cas</groupId>
<artifactId>cas-server-core-audit</artifactId>
<version>${cas.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apereo.cas</groupId>
<artifactId>cas-server-core</artifactId>
<version>${cas.version}</version>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* 版权所有.(c)2008-2017. 卡尔科技工作室
*/


package com.carl.sso.support.single.config;

import com.carl.sso.support.single.listener.TGTCreateEventListener;
import com.carl.sso.support.single.service.TriggerLogoutService;
import com.carl.sso.support.single.service.UserIdObtainServiceImpl;
import org.apereo.cas.CentralAuthenticationService;
import org.apereo.cas.configuration.CasConfigurationProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
* 登出配置
*
* @author Carl
* @date 2017/11/29
*/
@Configuration("singleLogoutTriggerConfiguration")
@EnableConfigurationProperties(CasConfigurationProperties.class)
public class SingleLogoutTriggerConfiguration {
@Autowired
private CentralAuthenticationService centralAuthenticationService;

/**
* 触发登出服务
*
* @return 触发登出服务
*/
@Bean
protected TriggerLogoutService triggerLogoutService() {
return new TriggerLogoutService(centralAuthenticationService);
}

@Bean
//注册事件监听tgt的创建
protected TGTCreateEventListener tgtCreateEventListener() {
TGTCreateEventListener listener = new TGTCreateEventListener(triggerLogoutService(), new UserIdObtainServiceImpl());
return listener;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* 版权所有.(c)2008-2017. 卡尔科技工作室
*/

package com.carl.sso.support.single.listener;

import com.carl.sso.support.single.service.IUserIdObtainService;
import com.carl.sso.support.single.service.TriggerLogoutService;
import org.apereo.cas.support.events.ticket.CasTicketGrantingTicketCreatedEvent;
import org.apereo.cas.ticket.TicketGrantingTicket;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;

import javax.validation.constraints.NotNull;
import java.util.List;

/**
* 识别事件然后删除
*
* @author Carl
* @version 创建时间:2017/11/29
*/
public class TGTCreateEventListener {
private TriggerLogoutService logoutService;
private IUserIdObtainService service;

public TGTCreateEventListener(@NotNull TriggerLogoutService logoutService, @NotNull IUserIdObtainService service) {
this.logoutService = logoutService;
this.service = service;
}

@EventListener
@Async
public void onTgtCreateEvent(CasTicketGrantingTicketCreatedEvent event) {
TicketGrantingTicket ticketGrantingTicket = event.getTicketGrantingTicket();
String id = ticketGrantingTicket.getAuthentication().getPrincipal().getId();
String tgt = ticketGrantingTicket.getId();
String clientName = (String) ticketGrantingTicket.getAuthentication().getAttributes().get("clientName");
//获取可以认证的id
List<String> authIds = service.obtain(clientName, id);
if (authIds != null) {
//循环触发登出
authIds.forEach(authId -> logoutService.triggerLogout(authId, tgt));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* 版权所有.(c)2008-2017. 卡尔科技工作室
*/
package com.carl.sso.support.single.service;

import java.util.List;

/**
* 用户认证识别器
*
* @author Carl
* @version 创建时间:2017/11/29
*/
public interface IUserIdObtainService {

/**
* 通过登录方式查询其他的id
*
* @param clientName 登录方式
* @param id 用户id
* @return 所有用户id
*/
List<String> obtain(String clientName, String id);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* 版权所有.(c)2008-2017. 卡尔科技工作室
*/



package com.carl.sso.support.single.service;

import org.apereo.cas.CentralAuthenticationService;
import org.apereo.cas.authentication.Authentication;
import org.apereo.cas.ticket.Ticket;
import org.apereo.cas.ticket.TicketGrantingTicket;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collection;

/**
* 登出触发器
*
* @author Carl
* @date 2017/11/29
*/
public class TriggerLogoutService {
private static final Logger LOGGER = LoggerFactory.getLogger(TriggerLogoutService.class);
private CentralAuthenticationService service;

public TriggerLogoutService(CentralAuthenticationService service) {
this.service = service;
}

/**
* 触发其他用户退出
*
* @param id 用户id
* @param tgt 当前登录的tgt
*/
public void triggerLogout(String id, String tgt) {
//找出用户id,并且不为当前tgt的,这里应当考虑数据性能,直接筛选用户再筛选tgt
Collection<Ticket> tickets = this.service.getTickets(ticket -> {
if(ticket instanceof TicketGrantingTicket) {
TicketGrantingTicket t = ((TicketGrantingTicket)ticket).getRoot();
Authentication authentication = t.getAuthentication();
return t != null && authentication != null
&& authentication.getPrincipal() != null && id.equals(authentication.getPrincipal().getId())
&& !tgt.equals(t.getId());
} else {
return false;
}

});

if (tickets != null && tickets.size() > 0) {
LOGGER.info(String.format("[%s]强制强制注销%s", id, tickets.size()));
}

//发出注销
for (Ticket ticket : tickets) {
service.destroyTicketGrantingTicket(ticket.getId());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* 版权所有.(c)2008-2017. 卡尔科技工作室
*/

package com.carl.sso.support.single.service;


import java.util.ArrayList;
import java.util.List;

/**
* @author Carl
* @version 创建时间:2017/11/29
*/
public class UserIdObtainServiceImpl implements IUserIdObtainService {

public UserIdObtainServiceImpl() {

}

@Override
public List<String> obtain(String clientName, String id) {
//由于这里目前只做测试所以只返回当前的id,在正常的情况逻辑应该如下

//根据校验client以及登录的id找到其他同一个用户的所有校验id返回,如通过邮箱登录的id,通过github登录的id等等
List<String> ids = new ArrayList<>();
ids.add(id);
return ids;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.carl.sso.support.single.config.SingleLogoutTriggerConfiguration

0 comments on commit 437272b

Please sign in to comment.