mirror of
https://github.com/luoye663/e5.git
synced 2024-12-25 11:18:50 +00:00
Merge remote-tracking branch 'origin/master'
# Conflicts: # src/main/java/io/qyi/e5/config/security/SecurityAuthenticationHandler.java # src/main/java/io/qyi/e5/config/security/SecurityConfig.java # src/main/java/io/qyi/e5/config/security/UsernamePasswordAuthenticationProvider.java # src/main/java/io/qyi/e5/config/security/filter/LinkTokenAuthenticationFilter.java
This commit is contained in:
commit
fe77f2d7f2
21
pom.xml
21
pom.xml
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.2.4.RELEASE</version>
|
||||
<version>2.3.1.RELEASE</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<groupId>io.qyi</groupId>
|
||||
@ -35,16 +35,23 @@
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<!-- log4j2 -->
|
||||
<!--排除自带的logging-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-logging</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!--log4j2-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-log4j2</artifactId>
|
||||
</dependency>
|
||||
<!-- freemarker 模板引擎-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-freemarker</artifactId>
|
||||
</dependency>
|
||||
<!--权限管理插件-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
|
@ -0,0 +1,65 @@
|
||||
package io.qyi.e5.config.security;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.access.AccessDecisionManager;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.security.access.ConfigAttribute;
|
||||
import org.springframework.security.authentication.InsufficientAuthenticationException;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* 决策管理器
|
||||
*
|
||||
* @program: e5
|
||||
* @description:
|
||||
* @author: 落叶随风
|
||||
* @create: 2020-06-15 16:11
|
||||
**/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class MyAccessDecisionManager implements AccessDecisionManager {
|
||||
@Override
|
||||
public void decide(Authentication authentication, Object o, Collection<ConfigAttribute> collection) throws AccessDeniedException, InsufficientAuthenticationException {
|
||||
if (collection == null) {
|
||||
return;
|
||||
}
|
||||
System.out.println(o.toString()); // object is a URL.
|
||||
log.info("object is a URL. {}", o.toString());
|
||||
//所请求的资源拥有的权限(一个资源对多个权限)
|
||||
Iterator<ConfigAttribute> iterator = collection.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
ConfigAttribute configAttribute = iterator.next();
|
||||
//访问所请求资源所需要的权限
|
||||
String needPermission = configAttribute.getAttribute();
|
||||
log.info("访问 " + o.toString() + " 需要的权限是:" + needPermission);
|
||||
if (needPermission == null) {
|
||||
break;
|
||||
}
|
||||
//用户所拥有的权限authentication
|
||||
Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
|
||||
for (GrantedAuthority ga : authorities) {
|
||||
if (needPermission.equals(ga.getAuthority())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
//没有权限
|
||||
throw new AccessDeniedException(" 无权限! ");
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supports(ConfigAttribute configAttribute) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supports(Class<?> aClass) {
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
package io.qyi.e5.config.security;
|
||||
|
||||
import org.springframework.security.access.ConfigAttribute;
|
||||
import org.springframework.security.access.SecurityConfig;
|
||||
import org.springframework.security.web.FilterInvocation;
|
||||
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
|
||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @program: e5
|
||||
* @description:
|
||||
* @author: 落叶随风
|
||||
* @create: 2020-06-17 16:25
|
||||
**/
|
||||
@Service
|
||||
public class MyInvocationSecurityMetadataSourceService implements FilterInvocationSecurityMetadataSource {
|
||||
|
||||
private HashMap<String, Collection<ConfigAttribute>> map =null;
|
||||
/**
|
||||
* 加载权限表中所有权限
|
||||
*/
|
||||
public void loadResourceDefine(){
|
||||
map = new HashMap<>();
|
||||
Collection<ConfigAttribute> array;
|
||||
ConfigAttribute cfg;
|
||||
List<Map<String, String>> permissions = new LinkedList<>();
|
||||
for(Map<String, String> permission : permissions) {
|
||||
array = new ArrayList<>();
|
||||
cfg = new SecurityConfig("ADMIN");
|
||||
//此处只添加了用户的名字,其实还可以添加更多权限的信息,例如请求方法到ConfigAttribute的集合中去。此处添加的信息将会作为MyAccessDecisionManager类的decide的第三个参数。
|
||||
array.add(cfg);
|
||||
//用权限的getUrl() 作为map的key,用ConfigAttribute的集合作为 value,
|
||||
map.put("/admin/test", array);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ConfigAttribute> getAttributes(Object o) throws IllegalArgumentException {
|
||||
if(map ==null) loadResourceDefine();
|
||||
//object 中包含用户请求的request 信息
|
||||
HttpServletRequest request = ((FilterInvocation) o).getHttpRequest();
|
||||
AntPathRequestMatcher matcher;
|
||||
String resUrl;
|
||||
for(Iterator<String> iter = map.keySet().iterator(); iter.hasNext(); ) {
|
||||
resUrl = iter.next();
|
||||
matcher = new AntPathRequestMatcher(resUrl);
|
||||
if(matcher.matches(request)) {
|
||||
return map.get(resUrl);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Collection<ConfigAttribute> getAllConfigAttributes() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supports(Class<?> aClass) {
|
||||
return false;
|
||||
}
|
||||
}
|
@ -58,11 +58,12 @@ public class UsernamePasswordAuthenticationToken extends AbstractAuthenticationT
|
||||
|
||||
|
||||
// 创建已认证的用户密码认证对象
|
||||
public UsernamePasswordAuthenticationToken(String name, String avatar_url, int github_id, Collection<? extends GrantedAuthority> authorities) {
|
||||
public UsernamePasswordAuthenticationToken(String name, String avatar_url, int github_id,String Authority, Collection<? extends GrantedAuthority> authorities) {
|
||||
super(authorities);
|
||||
this.name = name;
|
||||
this.avatar_url = avatar_url;
|
||||
this.github_id = github_id;
|
||||
this.Authority = Authority;
|
||||
super.setAuthenticated(true);
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
package io.qyi.e5.controller;
|
||||
package io.qyi.e5.controller.admin;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.google.gson.Gson;
|
||||
@ -10,8 +10,12 @@ import org.springframework.amqp.core.MessageProperties;
|
||||
import org.springframework.amqp.rabbit.connection.CorrelationData;
|
||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.annotation.Secured;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.UUID;
|
||||
@ -22,8 +26,8 @@ import java.util.UUID;
|
||||
* @author: 落叶随风
|
||||
* @create: 2020-03-16 01:01
|
||||
**/
|
||||
@Controller
|
||||
@RestController
|
||||
@RequestMapping("/admin")
|
||||
public class TestController {
|
||||
@Autowired
|
||||
RabbitTemplate rabbitTemplate;
|
||||
@ -47,5 +51,18 @@ public class TestController {
|
||||
return "ok";
|
||||
}
|
||||
|
||||
@GetMapping("/emptyRedis")
|
||||
public String emptyRedis() {
|
||||
redisUtil.deleteALL();
|
||||
return "ok";
|
||||
}
|
||||
|
||||
@GetMapping("/test")
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||
public String test() {
|
||||
return "ok";
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -6,6 +6,7 @@ import io.qyi.e5.bean.result.ResultEnum;
|
||||
import io.qyi.e5.config.security.UsernamePasswordAuthenticationToken;
|
||||
import io.qyi.e5.outlook.entity.Outlook;
|
||||
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.redis.RedisUtil;
|
||||
@ -42,6 +43,9 @@ public class AuthController {
|
||||
@Value("${outlook.authorize.url}")
|
||||
String authorizeUrl;
|
||||
|
||||
@Autowired
|
||||
ITask Task;
|
||||
|
||||
@RequestMapping("/receive")
|
||||
public Result Receive(String code, String state, String session_state) throws Exception {
|
||||
if (!redisUtil.hasKey(states + state)) {
|
||||
@ -62,6 +66,8 @@ public class AuthController {
|
||||
if (!authorization_code) {
|
||||
return ResultUtil.error(-3, "clientId 或 clientSecret 填写错误!授权失败!");
|
||||
}
|
||||
/*添加此用户进消息队列*/
|
||||
Task.sendTaskOutlookMQ(outlook.getGithubId());
|
||||
return ResultUtil.success();
|
||||
}
|
||||
|
||||
|
@ -206,6 +206,9 @@ public class OutlookServiceImpl extends ServiceImpl<OutlookMapper, Outlook> impl
|
||||
count = jsonObject.get("value").getAsJsonArray().size();
|
||||
}
|
||||
JsonArray value = jsonObject.get("value").getAsJsonArray();
|
||||
if (count == 0) {
|
||||
count = value.size();
|
||||
}
|
||||
for (int i = 0; i < count - 1; i++) {
|
||||
JsonObject mail = value.get(i).getAsJsonObject();
|
||||
String id = mail.get("id").getAsString();
|
||||
|
@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import io.qyi.e5.outlook.entity.Outlook;
|
||||
import io.qyi.e5.outlook.service.IOutlookService;
|
||||
import io.qyi.e5.service.task.ITask;
|
||||
import io.qyi.e5.util.redis.RedisUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.amqp.core.MessageProperties;
|
||||
@ -33,6 +34,9 @@ public class TaskImpl implements ITask {
|
||||
@Autowired
|
||||
RabbitTemplate rabbitTemplate;
|
||||
|
||||
@Autowired
|
||||
RedisUtil redisUtil;
|
||||
|
||||
@Override
|
||||
@Async
|
||||
public void sendTaskOutlookMQ(int github_id) {
|
||||
@ -42,9 +46,12 @@ public class TaskImpl implements ITask {
|
||||
return;
|
||||
}
|
||||
/*根据用户设置生成随机数*/
|
||||
String Expiration = getRandom(Outlook.getCronTimeRandomStart(), Outlook.getCronTimeRandomEnd());
|
||||
send(github_id, Expiration);
|
||||
|
||||
int Expiration = getRandom(Outlook.getCronTimeRandomStart(), Outlook.getCronTimeRandomEnd());
|
||||
/*将此用户信息加入redis,如果存在则代表在队列中,同时提前10秒过期*/
|
||||
if (!redisUtil.hasKey("user.mq:" + github_id)) {
|
||||
redisUtil.set("user.mq:" + github_id, 0, Expiration - 10);
|
||||
send(github_id, Expiration* 1000);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -55,14 +62,16 @@ public class TaskImpl implements ITask {
|
||||
while (iterator.hasNext()) {
|
||||
Outlook next = iterator.next();
|
||||
/*根据用户设置生成随机数*/
|
||||
String Expiration = getRandom(next.getCronTimeRandomStart(), next.getCronTimeRandomEnd());
|
||||
// System.out.println("生成随机调用时间,github ID" + next.getGithubId() + ",时间:" + Expiration);
|
||||
send(next.getGithubId(), Expiration);
|
||||
int Expiration = getRandom(next.getCronTimeRandomStart(), next.getCronTimeRandomEnd());
|
||||
/*将此用户信息加入redis,如果存在则代表在队列中,同时提前10秒过期*/
|
||||
if (!redisUtil.hasKey("user.mq:" + next.getGithubId())) {
|
||||
redisUtil.set("user.mq:" + next.getGithubId(), 0, Expiration - 10);
|
||||
send(next.getGithubId(), Expiration * 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Async
|
||||
public void executeE5(int github_id) {
|
||||
Outlook Outlook = outlookService.getOne(new QueryWrapper<Outlook>().eq("github_id", github_id));
|
||||
if (Outlook == null) {
|
||||
@ -82,7 +91,7 @@ public class TaskImpl implements ITask {
|
||||
* @Author: 落叶随风
|
||||
* @Date: 2020/4/16
|
||||
*/
|
||||
public void send(Object msg, String Expiration) {
|
||||
public void send(Object msg, int Expiration) {
|
||||
CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
|
||||
|
||||
rabbitTemplate.convertAndSend("delay", "delay", msg, message -> {
|
||||
@ -90,7 +99,7 @@ public class TaskImpl implements ITask {
|
||||
// 设置这条消息的过期时间
|
||||
// messageProperties.setExpiration(Expiration);
|
||||
|
||||
messageProperties.setHeader("x-delay",Expiration);
|
||||
messageProperties.setHeader("x-delay", Expiration);
|
||||
return message;
|
||||
}, correlationData);
|
||||
}
|
||||
@ -105,9 +114,9 @@ public class TaskImpl implements ITask {
|
||||
* @Author: 落叶随风
|
||||
* @Date: 2020/4/16
|
||||
*/
|
||||
public String getRandom(int start, int end) {
|
||||
public int getRandom(int start, int end) {
|
||||
Random r = new Random();
|
||||
String Expiration = String.valueOf((r.nextInt(end - start + 1) + start) * 1000);
|
||||
int Expiration = (r.nextInt(end - start + 1) + start);
|
||||
return Expiration;
|
||||
}
|
||||
}
|
||||
|
@ -49,6 +49,19 @@ public class RedisUtil {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除所有键值对
|
||||
* @title deleteALl
|
||||
* @description
|
||||
* @author 落叶随风
|
||||
* @updateTime 2020/4/22 22:53
|
||||
* @throws
|
||||
*/
|
||||
public void deleteALL() {
|
||||
Set<String> keys = redisTemplate.keys("*");
|
||||
redisTemplate.delete(keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据key 获取过期时间
|
||||
*
|
||||
|
@ -4,7 +4,7 @@
|
||||
<!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,
|
||||
当设置成trace时,会看到log4j2内部各种详细输出-->
|
||||
<!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数-->
|
||||
<configuration status="DEBUG" monitorInterval="5">
|
||||
<configuration status="INFO" monitorInterval="5">
|
||||
<Properties>
|
||||
<!-- 日志模板 -->
|
||||
<Property name="log_pattern" value="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
|
||||
|
Loading…
Reference in New Issue
Block a user