添加客户端注册接口
This commit is contained in:
parent
70d7cca7cd
commit
4695864db8
@ -54,6 +54,7 @@ public class SecurityConfiguration {
|
|||||||
return http
|
return http
|
||||||
.authorizeHttpRequests(conf -> conf
|
.authorizeHttpRequests(conf -> conf
|
||||||
.requestMatchers("/api/auth/**", "/error").permitAll()
|
.requestMatchers("/api/auth/**", "/error").permitAll()
|
||||||
|
.requestMatchers("/monitor/**").permitAll()
|
||||||
.requestMatchers("/swagger-ui/**", "/v3/api-docs/**").permitAll()
|
.requestMatchers("/swagger-ui/**", "/v3/api-docs/**").permitAll()
|
||||||
.anyRequest().hasAnyRole(Const.ROLE_DEFAULT)
|
.anyRequest().hasAnyRole(Const.ROLE_DEFAULT)
|
||||||
)
|
)
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
package com.example.controller;
|
||||||
|
|
||||||
|
import com.example.entity.RestBean;
|
||||||
|
import com.example.service.ClientService;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestHeader;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/monitor")
|
||||||
|
public class ClientController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
ClientService service;
|
||||||
|
|
||||||
|
@GetMapping("/register")
|
||||||
|
public RestBean<Void> registerClient(@RequestHeader("Authorization") String token) {
|
||||||
|
return service.verifyAndRegister(token) ?
|
||||||
|
RestBean.success() : RestBean.failure(401, "客户端注册失败,请检查Token是否正确");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package com.example.entity.dto;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.example.entity.BaseData;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@TableName("db_client")
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class Client implements BaseData {
|
||||||
|
Integer id;
|
||||||
|
String name;
|
||||||
|
String token;
|
||||||
|
Date registerTime;
|
||||||
|
}
|
@ -1,6 +1,8 @@
|
|||||||
package com.example.filter;
|
package com.example.filter;
|
||||||
|
|
||||||
import com.auth0.jwt.interfaces.DecodedJWT;
|
import com.auth0.jwt.interfaces.DecodedJWT;
|
||||||
|
import com.example.entity.dto.Client;
|
||||||
|
import com.example.service.ClientService;
|
||||||
import com.example.utils.Const;
|
import com.example.utils.Const;
|
||||||
import com.example.utils.JwtUtils;
|
import com.example.utils.JwtUtils;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
@ -27,20 +29,37 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
|||||||
@Resource
|
@Resource
|
||||||
JwtUtils utils;
|
JwtUtils utils;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
ClientService service;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doFilterInternal(HttpServletRequest request,
|
protected void doFilterInternal(HttpServletRequest request,
|
||||||
HttpServletResponse response,
|
HttpServletResponse response,
|
||||||
FilterChain filterChain) throws ServletException, IOException {
|
FilterChain filterChain) throws ServletException, IOException {
|
||||||
String authorization = request.getHeader("Authorization");
|
String authorization = request.getHeader("Authorization");
|
||||||
DecodedJWT jwt = utils.resolveJwt(authorization);
|
String uri = request.getRequestURI();
|
||||||
if(jwt != null) {
|
if(uri.startsWith("/monitor")) {
|
||||||
UserDetails user = utils.toUser(jwt);
|
if(!uri.endsWith("/register")) {
|
||||||
UsernamePasswordAuthenticationToken authentication =
|
Client client = service.findClient(authorization);
|
||||||
new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
|
if(client == null) {
|
||||||
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
|
response.setStatus(401);
|
||||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
return;
|
||||||
request.setAttribute(Const.ATTR_USER_ID, utils.toId(jwt));
|
} else {
|
||||||
|
request.setAttribute(Const.ATTR_CLIENT, client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
filterChain.doFilter(request, response);
|
||||||
|
} else {
|
||||||
|
DecodedJWT jwt = utils.resolveJwt(authorization);
|
||||||
|
if(jwt != null) {
|
||||||
|
UserDetails user = utils.toUser(jwt);
|
||||||
|
UsernamePasswordAuthenticationToken authentication =
|
||||||
|
new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
|
||||||
|
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
|
||||||
|
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||||
|
request.setAttribute(Const.ATTR_USER_ID, utils.toId(jwt));
|
||||||
|
}
|
||||||
|
filterChain.doFilter(request, response);
|
||||||
}
|
}
|
||||||
filterChain.doFilter(request, response);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
package com.example.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.example.entity.dto.Client;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface ClientMapper extends BaseMapper<Client> {
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
package com.example.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import com.example.entity.dto.Client;
|
||||||
|
|
||||||
|
public interface ClientService extends IService<Client> {
|
||||||
|
String registerToken();
|
||||||
|
Client findClient(String token);
|
||||||
|
Client findClient(Integer id);
|
||||||
|
boolean verifyAndRegister(String token);
|
||||||
|
}
|
@ -0,0 +1,77 @@
|
|||||||
|
package com.example.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import com.example.entity.dto.Client;
|
||||||
|
import com.example.mapper.ClientMapper;
|
||||||
|
import com.example.service.ClientService;
|
||||||
|
import jakarta.annotation.PostConstruct;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class ClientServiceImpl extends ServiceImpl<ClientMapper, Client> implements ClientService {
|
||||||
|
|
||||||
|
private String registerToken = this.generateNewToken();
|
||||||
|
|
||||||
|
private final HashMap<Integer, Client> clientIdCache = new HashMap<>();
|
||||||
|
private final HashMap<String, Client> clientTokenCache = new HashMap<>();
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void initClientCache() {
|
||||||
|
this.list().forEach(this::addClientCache);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Client findClient(Integer id) {
|
||||||
|
return clientIdCache.get(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Client findClient(String token) {
|
||||||
|
return clientTokenCache.get(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String registerToken() {
|
||||||
|
return registerToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized boolean verifyAndRegister(String token) {
|
||||||
|
if(this.registerToken.equals(token)) {
|
||||||
|
int id = this.randomClientId();
|
||||||
|
Client client = new Client(id, "未命名主机", token, new Date());
|
||||||
|
if(this.save(client)) {
|
||||||
|
registerToken = this.generateNewToken();
|
||||||
|
this.addClientCache(client);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
log.warn("在注册客户端时Token验证成功,但客户端数据插入失败,请检查问题原因!");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addClientCache(Client client) {
|
||||||
|
clientIdCache.put(client.getId(), client);
|
||||||
|
clientTokenCache.put(client.getToken(), client);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int randomClientId(){
|
||||||
|
return new Random().nextInt(90000000) + 10000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String generateNewToken() {
|
||||||
|
String CHARACTERS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||||
|
SecureRandom random = new SecureRandom();
|
||||||
|
StringBuilder sb = new StringBuilder(24);
|
||||||
|
for (int i = 0; i < 24; i++)
|
||||||
|
sb.append(CHARACTERS.charAt(random.nextInt(CHARACTERS.length())));
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
}
|
@ -18,6 +18,7 @@ public final class Const {
|
|||||||
public final static int ORDER_CORS = -102;
|
public final static int ORDER_CORS = -102;
|
||||||
//请求自定义属性
|
//请求自定义属性
|
||||||
public final static String ATTR_USER_ID = "userId";
|
public final static String ATTR_USER_ID = "userId";
|
||||||
|
public final static String ATTR_CLIENT = "client";
|
||||||
//消息队列
|
//消息队列
|
||||||
public final static String MQ_MAIL = "mail";
|
public final static String MQ_MAIL = "mail";
|
||||||
//用户角色
|
//用户角色
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
<exclude-output />
|
<exclude-output />
|
||||||
<content url="file://$MODULE_DIR$">
|
<content url="file://$MODULE_DIR$">
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/log" />
|
||||||
</content>
|
</content>
|
||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="inheritedJdk" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
Loading…
x
Reference in New Issue
Block a user