添加服务端注册接口

This commit is contained in:
柏码の讲师 2023-12-07 16:57:40 +08:00
parent 39f2de6628
commit 136a208603
8 changed files with 167 additions and 8 deletions

View File

@ -54,6 +54,7 @@ public class SecurityConfiguration {
return http
.authorizeHttpRequests(conf -> conf
.requestMatchers("/api/auth/**", "/error").permitAll()
.requestMatchers("/monitor/**").permitAll()
.requestMatchers("/swagger-ui/**", "/v3/api-docs/**").permitAll()
.anyRequest().hasAnyRole(Const.ROLE_DEFAULT)
)

View File

@ -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是否正确");
}
}

View File

@ -0,0 +1,19 @@
package com.example.entity.dto;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.Date;
@Data
@TableName("db_client")
@AllArgsConstructor
public class Client {
@TableId
Integer id;
String name;
String token;
Date registerTime;
}

View File

@ -1,6 +1,9 @@
package com.example.filter;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.example.entity.RestBean;
import com.example.entity.dto.Client;
import com.example.service.ClientService;
import com.example.utils.Const;
import com.example.utils.JwtUtils;
import jakarta.annotation.Resource;
@ -27,19 +30,36 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
@Resource
JwtUtils utils;
@Resource
ClientService service;
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
String authorization = request.getHeader("Authorization");
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));
String uri = request.getRequestURI();
if(uri.startsWith("/monitor")) {
if(!uri.endsWith("/register")) {
Client client = service.findClientByToken(authorization);
if(client == null) {
response.setStatus(401);
response.getWriter().write(RestBean.failure(401, "未注册").asJsonString());
return;
} else {
request.setAttribute(Const.ATTR_CLIENT, client);
}
}
} 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);
}

View File

@ -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> {
}

View File

@ -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 findClientById(int id);
Client findClientByToken(String token);
boolean verifyAndRegister(String token);
}

View File

@ -0,0 +1,75 @@
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 org.springframework.stereotype.Service;
import java.security.SecureRandom;
import java.util.Date;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
@Service
public class ClientServiceImpl extends ServiceImpl<ClientMapper, Client> implements ClientService {
private String registerToken = this.generateNewToken();
private final Map<Integer, Client> clientIdCache = new ConcurrentHashMap<>();
private final Map<String, Client> clientTokenCache = new ConcurrentHashMap<>();
@PostConstruct
public void initClientCache() {
this.list().forEach(this::addClientCache);
}
@Override
public String registerToken() {
return registerToken;
}
@Override
public Client findClientById(int id) {
return clientIdCache.get(id);
}
@Override
public Client findClientByToken(String token) {
return clientTokenCache.get(token);
}
@Override
public 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;
}
}
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();
}
}

View File

@ -18,6 +18,7 @@ public final class Const {
public final static int ORDER_CORS = -102;
//请求自定义属性
public final static String ATTR_USER_ID = "userId";
public final static String ATTR_CLIENT = "client";
//消息队列
public final static String MQ_MAIL = "mail";
//用户角色