添加服务端注册接口
This commit is contained in:
parent
39f2de6628
commit
136a208603
@ -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)
|
||||
)
|
||||
|
@ -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,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;
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
@ -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 findClientById(int id);
|
||||
Client findClientByToken(String token);
|
||||
boolean verifyAndRegister(String token);
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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";
|
||||
//用户角色
|
||||
|
Loading…
x
Reference in New Issue
Block a user