1、对每个用户增加独立的回调url

2、受支持的帐户类型更改为 仅此组织目录,减少任务此应用被误判未钓鱼应用的问题
3、新增应用增加租户ID
This commit is contained in:
LuoYe 2023-01-15 17:42:03 +08:00
parent d88187af32
commit 81b245a749
15 changed files with 185 additions and 58 deletions

View File

@ -191,6 +191,11 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!-- 自定义验证注解 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>

View File

@ -87,6 +87,7 @@ public class Start {
runOutlookList.forEach(outlook -> {
threadPool.execute(new task(outlook,cdl));
});
/*等待线程池内的线程执行完毕*/
try {
cdl.await();

View File

@ -29,7 +29,7 @@ public class UrlAccessDecisionManager implements AccessDecisionManager {
if (collection == null) {
return;
}
log.info("object is a URL. {}", o.toString());
log.debug("object is a URL. {}", o.toString());
//所请求的资源拥有的权限(一个资源对多个权限)
Iterator<ConfigAttribute> iterator = collection.iterator();
while (iterator.hasNext()) {

View File

@ -59,7 +59,7 @@ public class UsernamePasswordAuthenticationProvider implements AuthenticationPro
// 根据用户Token中的用户名查找用户信息如果有该用户信息则验证用户密码是否正确
String code = authenticationToken.getCode();
String state = authenticationToken.getState();
logger.info("认证: code{} state{} Token{}", code, state, authenticationToken.getToken());
logger.debug("认证: code{} state{} Token{}", code, state, authenticationToken.getToken());
Map<String, Object> userInfo_redis = new HashMap<>();
if (!redisUtil.hasKey(states + state)) {

View File

@ -37,11 +37,21 @@ public class Auth {
String client_id;
@Value("${github.replyUrl}")
String replyUrl;
@Value("${github.replyUrlDebug}")
String replyUrlDebug;
@Value("${isdebug}")
boolean isdebug;
@RequestMapping("/getGithubUrl")
public Result getGithubUrl() {
String state = EncryptUtil.getInstance().SHA1Hex(UUID.randomUUID().toString());
redisUtil.set(states + state, true, 600);
return ResultUtil.success("https://github.com/login/oauth/authorize?client_id=" + client_id + "&redirect_uri=https://e5.qyi.io/auth2/receive&state=" + state);
return ResultUtil.success("https://github.com/login/oauth/authorize?client_id=" + client_id + "&redirect_uri=" + (isdebug ? replyUrlDebug : replyUrl) + "&state=" + state);
}
/* @RequestMapping("/receive")

View File

@ -6,16 +6,18 @@ import io.qyi.e5.github.service.IGithubService;
import io.qyi.e5.outlook.service.IOutlookService;
import io.qyi.e5.outlook_log.service.IOutlookLogService;
import io.qyi.e5.util.ResultUtil;
import io.qyi.e5.util.SecurityUtils;
import io.qyi.e5.util.StringUtil;
import io.qyi.e5.util.redis.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.DigestUtils;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@ -41,6 +43,18 @@ public class WebController {
@Autowired
RedisUtil redisUtil;
@Value("${outlook.replyUrl}")
String replyUrl;
@Value("${outlook.replyUrlDebug}")
String replyUrlDebug;
@Value("${outlook.authorize.url}")
String authorizeUrl;
@Value("${isdebug}")
boolean isDebug;
@RequestMapping("/")
public Result index() {
return ResultUtil.error(-1, "This is api server!");
@ -82,4 +96,17 @@ public class WebController {
return s;
}
@RequestMapping("getUserReplyUrlToOutlook")
public Result getUserReplyUrlToOutlook() {
String userIdMd5 = DigestUtils.md5DigestAsHex(String.valueOf(SecurityUtils.getUserInfo().getGithub_id()).getBytes());
String reUrl;
if (isDebug) {
reUrl = String.format(replyUrlDebug, userIdMd5);
} else {
reUrl = String.format(replyUrl, userIdMd5);
}
return ResultUtil.success(reUrl);
}
}

View File

@ -17,4 +17,6 @@ public class OutlookVo {
private Integer cronTimeRandomEnd;
private Integer step;
private Integer status;
private Integer outlookId;
}

View File

@ -2,6 +2,9 @@ package io.qyi.e5.outlook.bean.bo;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
/**
* @program: e5
* @description:
@ -10,7 +13,15 @@ import lombok.Data;
**/
@Data
public class UpdateBo {
@NotEmpty(message = "[客户端]不能为空!")
private String client_id;
@NotEmpty(message = "[客户端密码]不能为空!")
private String client_secret;
private int outlook_id;
@NotEmpty(message = "[租户ID]不能为空!")
private String tenant_id;
@NotNull(message = "[ID]不能为空!")
private Integer outlook_id;
}

View File

@ -9,10 +9,15 @@ import io.qyi.e5.outlook.service.IOutlookService;
import io.qyi.e5.service.task.ITask;
import io.qyi.e5.util.EncryptUtil;
import io.qyi.e5.util.ResultUtil;
import io.qyi.e5.util.SecurityUtils;
import io.qyi.e5.util.redis.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@ -24,6 +29,7 @@ import java.util.UUID;
* @author: 落叶随风
* @create: 2020-02-24 16:02
**/
@Slf4j
@RestController
@RequestMapping("/outlook/auth2")
public class AuthController {
@ -53,13 +59,27 @@ public class AuthController {
@RequestMapping("/receive")
public Result Receive(String code, String state, String session_state) throws Exception {
public void receiveOld() {
throw new APIException("程序已更新,请按照教程重新操作。 https://qyi.io/archives/687.html");
}
@RequestMapping("/{userId}/receive")
public Result Receive(@PathVariable String userId, String code, String state, String session_state) throws Exception {
String userIdMd5 = DigestUtils.md5DigestAsHex(String.valueOf(SecurityUtils.getUserInfo().getGithub_id()).getBytes());
if (StringUtils.isEmpty(userId) || StringUtils.isEmpty(userIdMd5)) {
throw new APIException("用户信息错误");
}
if (!userIdMd5.equals(userId)) {
throw new APIException("你设置的回复Url与你的用户信息不匹配。");
}
if (!redisUtil.hasKey(states + state)) {
throw new APIException("state已过期请到用户中心重新授权!");
}
int outlookId = (int) redisUtil.get(states + state);
/*这里不应该查询在进行授权时因该把基础数据丢到redis*/
QueryWrapper<Outlook> outlookQueryWrapper = new QueryWrapper<>();
int outlookId = (int) redisUtil.get(states + state);
outlookQueryWrapper.eq("id", outlookId);
Outlook outlook = outlookService.getOne(outlookQueryWrapper);
/*删除redis中的此键*/
@ -69,17 +89,18 @@ public class AuthController {
}
String reUrl = "";
if (isDebug) {
reUrl = replyUrlDebug;
reUrl = String.format(replyUrlDebug, userIdMd5);
} else {
reUrl = replyUrl;
reUrl = String.format(replyUrl, userIdMd5);
}
boolean authorization_code = outlookService.getTokenAndSave(code, outlook.getClientId(), outlook.getClientSecret(), reUrl
boolean authorization_code = outlookService.getTokenAndSave(outlook.getTenantId(), code, outlook.getClientId(), outlook.getClientSecret(), reUrl
, "authorization_code");
if (!authorization_code) {
throw new APIException("clientId 或 clientSecret 填写错误!授权失败!");
}
/*添加此用户进消息队列*/
Task.updateOutlookExecDateTime(outlook.getGithubId(),outlookId);
Task.updateOutlookExecDateTime(outlook.getGithubId(), outlookId);
return ResultUtil.success();
}
@ -96,17 +117,25 @@ public class AuthController {
if (outlook.getClientId().length() < 1 || outlook.getClientSecret().length() < 1) {
throw new APIException("没有设置key你授权啥呢!!!");
}
if (StringUtils.isEmpty(outlook.getTenantId())) {
throw new APIException("该应用未设置租户ID请参考教程进行设置。");
}
// 生成随机uuid标识用户
String state = EncryptUtil.getInstance().SHA1Hex(UUID.randomUUID().toString());
redisUtil.set(states + state, id, 600);
String userIdMd5 = DigestUtils.md5DigestAsHex(String.valueOf(SecurityUtils.getUserInfo().getGithub_id()).getBytes());
String reUrl = "";
if (isDebug) {
reUrl = replyUrlDebug;
reUrl = String.format(replyUrlDebug, userIdMd5);
;
} else {
reUrl = replyUrl;
reUrl = String.format(replyUrl, userIdMd5);
}
String url = String.format(authorizeUrl, outlook.getClientId(), reUrl, state);
String url = String.format(authorizeUrl, outlook.getTenantId(), outlook.getClientId(), reUrl, state);
return ResultUtil.success(url);
} else {
throw new APIException("没有此记录");

View File

@ -19,6 +19,7 @@ import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.io.Serializable;
@ -36,6 +37,7 @@ import java.util.List;
@RestController
@RequestMapping("/outlook/outlook")
@Slf4j
@Validated
public class OutlookController {
@Autowired
@ -51,9 +53,9 @@ public class OutlookController {
}
@PostMapping("/save")
public ResultVO save(@RequestBody UpdateBo bo) {
public ResultVO save(@Validated @RequestBody UpdateBo bo) {
UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
if (outlookService.save(bo.getClient_id(), bo.getClient_secret(), bo.getOutlook_id(), authentication.getGithub_id())) {
if (outlookService.save(bo, authentication.getGithub_id())) {
return new ResultVO<>();
}
return new ResultVO<>();
@ -122,10 +124,6 @@ public class OutlookController {
@GetMapping("/getOutlookList")
public Result getOutlookList() {
log.info("测试MOD");
log.debug("测试MOD");
log.warn("测试MOD");
log.error("测试MOD");
UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
int github_id = authentication.getGithub_id();
List<Outlook> outlooklist = outlookService.getOutlooklist(github_id);

View File

@ -76,4 +76,9 @@ public class Outlook implements Serializable {
/*下次调用时间*/
private Integer nextTime;
/**
* 租户id
*/
private String tenantId;
}

View File

@ -1,6 +1,7 @@
package io.qyi.e5.outlook.service;
import com.baomidou.mybatisplus.extension.service.IService;
import io.qyi.e5.outlook.bean.bo.UpdateBo;
import io.qyi.e5.outlook.entity.Outlook;
import java.util.List;
@ -15,11 +16,11 @@ import java.util.List;
*/
public interface IOutlookService extends IService<Outlook> {
boolean getTokenAndSave(String code, String client_id, String client_secret, String redirect_uri, String grant_type) throws Exception;
boolean getTokenAndSave(String tenantId, String code, String client_id, String client_secret, String redirect_uri, String grant_type) throws Exception;
Outlook insertOne(String name, String describe, int github_id);
boolean save(String client_id, String client_secret, int outlook_id, int github_id);
boolean save(UpdateBo updateBo, int github_id);
boolean saveRandomTime(int github_id, int cron_time, int outlook_id, int cron_time_random_start, int cron_time_random_end);
@ -40,8 +41,6 @@ public interface IOutlookService extends IService<Outlook> {
/**
* 更新数据
*
* @param github_id: github_id
* @param outlookId: outlookId
* @param outlook: 更新的数据
* @Author: 落叶随风
* @Date: 2020/12/19 21:29

View File

@ -10,6 +10,7 @@ import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import io.qyi.e5.config.APiCode;
import io.qyi.e5.config.exception.APIException;
import io.qyi.e5.outlook.bean.bo.UpdateBo;
import io.qyi.e5.outlook.entity.Outlook;
import io.qyi.e5.outlook.mapper.OutlookMapper;
import io.qyi.e5.outlook.service.IOutlookService;
@ -49,7 +50,7 @@ public class OutlookServiceImpl extends ServiceImpl<OutlookMapper, Outlook> impl
// 2020-03-2 10:38 这里需要进行查询判断数据库是否有内容再进行插入
@Override
public boolean getTokenAndSave(String code, String client_id, String client_secret, String redirect_uri, String grant_type) throws Exception {
public boolean getTokenAndSave(String tenantId, String code, String client_id, String client_secret, String redirect_uri, String grant_type) throws Exception {
Map<String, Object> head = new HashMap<>();
head.put("Content-Type", "application/x-www-form-urlencoded");
Map<String, Object> par = new HashMap<>();
@ -58,7 +59,7 @@ public class OutlookServiceImpl extends ServiceImpl<OutlookMapper, Outlook> impl
par.put("code", code);
par.put("redirect_uri", redirect_uri);
par.put("grant_type", grant_type);
String s = OkHttpClientUtil.doPost("https://login.microsoftonline.com/common/oauth2/v2.0/token", head, par);
String s = OkHttpClientUtil.doPost("https://login.microsoftonline.com/" + tenantId + "/oauth2/v2.0/token", head, par);
JSONObject jsonObject = JSON.parseObject(s);
logger.info("请求access_token返回数据" + s);
if (jsonObject.get("error") != null) {
@ -91,7 +92,7 @@ public class OutlookServiceImpl extends ServiceImpl<OutlookMapper, Outlook> impl
* @Author: 落叶随风
* @Date: 2020/12/19 21:25
* @Return: * @return: io.qyi.e5.outlook.entity.Outlook
*/
*/
@Override
public Outlook insertOne(String name, String describe, int github_id) {
if (StringUtils.isBlank(name)) {
@ -107,6 +108,7 @@ public class OutlookServiceImpl extends ServiceImpl<OutlookMapper, Outlook> impl
}
return outlook;
}
/*
* 保存key
* @param client_id:
@ -116,38 +118,34 @@ public class OutlookServiceImpl extends ServiceImpl<OutlookMapper, Outlook> impl
* @Author: 落叶随风
* @Date: 2020/12/19 21:24
* @Return: * @return: boolean
*/
*/
@Override
public boolean save(String client_id, String client_secret, int outlook_id, int github_id) {
if (github_id == 0) {
throw new APIException(APiCode.OUTLOOK_NAME_NOT_NULL);
}
if (outlook_id == 0 || StringUtils.isBlank(client_id) || StringUtils.isBlank(client_secret)) {
throw new APIException("缺少参数!");
}
public boolean save(UpdateBo updateBo, int github_id) {
QueryWrapper<Outlook> queryWrapper = new QueryWrapper<>();
// HashMap<String, Object> sc = new HashMap<>();
// sc.put("github_id", github_id);
// sc.put("id", outlook_id);
// queryWrapper.allEq(sc);
queryWrapper.eq("github_id", github_id).eq("id", outlook_id);
queryWrapper.eq("github_id", github_id).eq("id", updateBo.getOutlook_id());
/*2020-12-10 mybatis plus问题导致会被截断*/
// Outlook outlook1 = baseMapper.selectOne(queryWrapper);
Outlook outlook1 = baseMapper.selectOutlookOne(outlook_id, github_id);
Outlook outlook1 = baseMapper.selectOutlookOne(updateBo.getOutlook_id(), github_id);
if (outlook1 == null) {
throw new APIException("未查询到此条记录!");
}
outlook1.setClientId(client_id);
outlook1.setClientSecret(client_secret);
outlook1.setStep(1)
.setStatus(8);
outlook1.setClientId(updateBo.getClient_id())
.setClientSecret(updateBo.getClient_secret())
.setStep(1)
.setStatus(8)
.setTenantId(updateBo.getTenant_id());
;
if (baseMapper.update(outlook1, queryWrapper) != 1) {
throw new APIException("更新记录失败!");
}
return true;
}
/*
* 保存随机调用时间
* @param github_id: github_id
@ -158,7 +156,7 @@ public class OutlookServiceImpl extends ServiceImpl<OutlookMapper, Outlook> impl
* @Author: 落叶随风
* @Date: 2020/12/19 21:24
* @Return: * @return: boolean
*/
*/
@Override
public boolean saveRandomTime(int github_id, int cron_time, int outlook_id, int cron_time_random_start, int cron_time_random_end) {
if (github_id == 0 || outlook_id == 0) {
@ -181,19 +179,20 @@ public class OutlookServiceImpl extends ServiceImpl<OutlookMapper, Outlook> impl
}
return false;
}
/*
* 查询所有列表
* @Author: 落叶随风
* @Date: 2020/12/19 21:23
* @Return: * @return: java.util.List<io.qyi.e5.outlook.entity.Outlook>
*/
*/
@Override
public List<Outlook> findAll() {
return baseMapper.selectList(null);
}
@Override
public List<Outlook> findRunOutlookList(){
public List<Outlook> findRunOutlookList() {
int nowDateTime = (int) (System.currentTimeMillis() / 1000);
List<Outlook> outlooks = baseMapper.selectList(new QueryWrapper<Outlook>().eq("status", 3).lt("next_time", nowDateTime));
return outlooks;
@ -221,7 +220,7 @@ public class OutlookServiceImpl extends ServiceImpl<OutlookMapper, Outlook> impl
* @Author: 落叶随风
* @Date: 2020/12/19 21:22
* @Return: * @return: int
*/
*/
@Override
public int getMailList(Outlook outlook) throws Exception {
String s = MailList(outlook.getAccessToken());
@ -247,9 +246,9 @@ public class OutlookServiceImpl extends ServiceImpl<OutlookMapper, Outlook> impl
throw new Exception("无法刷新令牌!code:2,错误消息: " + json.getJSONObject("error").getString("message"));
}
}
logger.info("邮件列表请求成功!" + s);
logger.debug("邮件列表请求成功!" + s);
int mail_count = getMailBody(5, s, outlook.getAccessToken());
logger.info("读取邮件数量: {}", mail_count);
logger.debug("读取邮件数量: {}", mail_count);
return mail_count;
}
@ -291,13 +290,13 @@ public class OutlookServiceImpl extends ServiceImpl<OutlookMapper, Outlook> impl
}
/**
* @throws
* @title 获取邮件列表默认5封
* @description
* @author 落叶随风
* @param: access_token
* @updateTime 2020/12/19 21:17
* @return: java.lang.String
* @throws
*/
public String MailList(String access_token) throws Exception {
Map<String, String> head = new HashMap<>();
@ -320,7 +319,7 @@ public class OutlookServiceImpl extends ServiceImpl<OutlookMapper, Outlook> impl
par.put("grant_type", "refresh_token");
par.put("refresh_token", outlook.getRefreshToken());
String s = null;
s = OkHttpClientUtil.doPost("https://login.microsoftonline.com/common/oauth2/v2.0/token", head, par);
s = OkHttpClientUtil.doPost("https://login.microsoftonline.com/" + outlook.getTenantId() + "/oauth2/v2.0/token", head, par);
logger.info("请求刷新列表返回数据:" + s);
JSONObject jsonObject = JSON.parseObject(s);
if (!jsonObject.containsKey("access_token")) {
@ -359,17 +358,16 @@ public class OutlookServiceImpl extends ServiceImpl<OutlookMapper, Outlook> impl
}
/**
* @throws
* @title 获取本账号下的outlook 应用列表
* @description
* @author 落叶随风
* @param: github_id
* @updateTime 2020/12/19 21:16
* @return: java.util.List<io.qyi.e5.outlook.entity.Outlook>
* @throws
*/
@Override
public List<Outlook> getOutlooklist(int github_id) {
log.info("测试MOD service");
QueryWrapper<Outlook> qw = new QueryWrapper<Outlook>().eq("github_id", github_id);
List<Outlook> outlooks = baseMapper.selectList(qw);
return outlooks;
@ -377,13 +375,14 @@ public class OutlookServiceImpl extends ServiceImpl<OutlookMapper, Outlook> impl
/**
* 设置暂停状态
*
* @throws
* @title setPause
* @description
* @author 落叶随风
* @param: github_id
* @param: outlookId
* @updateTime 2020/12/19 21:16
* @throws
*/
@Override
public void setPause(int github_id, int outlookId) {
@ -404,13 +403,14 @@ public class OutlookServiceImpl extends ServiceImpl<OutlookMapper, Outlook> impl
/**
* 设置开始状态
*
* @throws
* @title setStart
* @description
* @author 落叶随风
* @param: github_id
* @param: outlookId
* @updateTime 2020/12/19 21:16
* @throws
*/
@Override
public void setStart(int github_id, int outlookId) {
@ -420,15 +420,17 @@ public class OutlookServiceImpl extends ServiceImpl<OutlookMapper, Outlook> impl
throw new APIException("更新失败!");
}
}
/**
* 更新数据
* @param outlook: 更新的数据
* 更新数据
*
* @param outlook: 更新的数据
* @Author: 落叶随风
* @Date: 2020/12/19 21:29
* @Return: * @return: void
*/
*/
@Override
public void update( Outlook outlook) {
public void update(Outlook outlook) {
UpdateWrapper<Outlook> uw = new UpdateWrapper<>();
uw.eq("id", outlook.getId());
uw.eq("github_id", outlook.getGithubId());
@ -445,8 +447,9 @@ public class OutlookServiceImpl extends ServiceImpl<OutlookMapper, Outlook> impl
throw new APIException("删除失败!");
}
}
@Override
public boolean isStatusRun(int github_id, int outlookId){
public boolean isStatusRun(int github_id, int outlookId) {
QueryWrapper<Outlook> wp = new QueryWrapper<>();
wp.eq("github_id", github_id);
wp.eq("id", outlookId);

View File

@ -0,0 +1,36 @@
package io.qyi.e5.util;
import io.qyi.e5.config.security.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
public class SecurityUtils {
/**
* 获取当前登录用户
* @return
*/
public static String getCurrentLoginUser() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication == null) {
throw new RuntimeException("当前无用户登录");
} else {
return authentication.getName();
}
}
/**
* 获取当前登录用户信息
* @return
*/
public static UsernamePasswordAuthenticationToken getUserInfo() {
UsernamePasswordAuthenticationToken details = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
if (details == null) {
throw new RuntimeException("当前无用户登录");
}
return details;
}
}

View File

@ -84,6 +84,7 @@
<loggers>
<!--过滤掉spring和hibernate的一些无用的debug信息-->
<logger name="org.springframework" level="INFO"/>
<logger name="io.qyi.e5" level="debug"/>
<logger name="org.mybatis" level="INFO">
<!-- 添加如下设置,控制台会再打印一次 -->
<AppenderRef ref="Console"/>