当前位置:网站首页>Two controller layer interface authentication methods
Two controller layer interface authentication methods
2022-06-29 17:45:00 【llp1110】
Two kinds of Controller Layer interface authentication mode
Recently, I was working on an instant messaging service , It is required to authenticate the input parameters of each interface , Here I have sorted out two ways :1. Authentication based on annotations and interceptors 2. Based on annotations and AOP authentication
What I am using here is aop The way , The interceptor here only completes the pseudo code as a record .
1. Authentication based on annotations and interceptors
Interceptor mode mainly needs to be solved requestBody The problem of repeated acquisition
1. First, we need to define an authentication identifier annotation
/** * Authentication mark annotation */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface Authorization {
}
2. rewrite HttpServletRequestWrapper
Through custom HttpServletRequestWrapper Back up the dirty data , Customize HttpServletRequestWrapper Call the parent class request.getInputStream() Read all the data and save it in one byte In array , When the stream data is retrieved again , Self defined HttpServletRequestWrapper Will use byte Array regenerates a new stream . The backed up stream data remains in byte Array .
public class RepeatableReadRequestWrapper extends HttpServletRequestWrapper {
private final byte[] bytes;
public RepeatableReadRequestWrapper(HttpServletRequest request, HttpServletResponse response) throws IOException {
super(request);
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
bytes = request.getReader().readLine().getBytes();
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(getInputStream()));
}
@Override
public ServletInputStream getInputStream() throws IOException {
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
return new ServletInputStream() {
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
}
@Override
public int read() throws IOException {
return bais.read();
}
@Override
public int available() throws IOException {
return bytes.length;
}
};
}
}
3. Define an interceptor
@Component
public class RepeatSubmitInterceptor implements HandlerInterceptor {
@Autowired
RedisCache redisCache;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
if (method.isAnnotationPresent(Authorization.class)) {
// Request parameter string
String nowParams = "";
if (request instanceof RepeatableReadRequestWrapper) {
try {
nowParams = ((RepeatableReadRequestWrapper) request).getReader().readLine();
System.out.println("nowParams: " + nowParams);
//TODO Carry out authentication processing
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
return true;
}
}
4. Define a filter
public class RepeatableRequestFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
if (StringUtils.startsWithIgnoreCase(request.getContentType(), "application/json")) {
RepeatableReadRequestWrapper requestWrapper = new RepeatableReadRequestWrapper(request, (HttpServletResponse) servletResponse);
filterChain.doFilter(requestWrapper,servletResponse);
return;
}
filterChain.doFilter(servletRequest, servletResponse);
}
}
5. Configuration class
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
RepeatSubmitInterceptor repeatSubmitInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(repeatSubmitInterceptor).addPathPatterns("/**");
}
@Bean
FilterRegistrationBean<RepeatableRequestFilter> repeatableRequestFilterFilterRegistrationBean() {
FilterRegistrationBean<RepeatableRequestFilter> bean = new FilterRegistrationBean<>();
bean.setFilter(new RepeatableRequestFilter());
bean.addUrlPatterns("/*");
return bean;
}
}
6. Test class
@RestController
public class HelloController {
@Authorization
@PostMapping("/test")
public String authorization(@RequestBody User user) {
System.out.println(user);
return "succes";
}
}
test result

2. Based on annotations and AOP authentication
1. Define an authentication identifier annotation
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Authorization {
}
2. Definition AOP class
@Aspect
@Order(value = Integer.MAX_VALUE-1)
@Component
public class AuthorizationAspect {
private static Logger log = LoggerFactory.getLogger(AuthorizationAspect.class);
@Autowired
private AuthConfigService authConfigService;
@Before(value = "@annotation(com.llp.api.annotation.Authorization))")
public void authorization(JoinPoint joinPoint) throws Exception {
// Get request parameters
Object[] args = joinPoint.getArgs();
Signature signature = joinPoint.getSignature();
// Get method signature
MethodSignature methodSignature = (MethodSignature) signature;
// obtain Method object
Method method = methodSignature.getMethod();
// Determine whether the method is customized by us @Authorization To modify
if (method.isAnnotationPresent(Authorization.class)) {
// Traversal request parameters
for (Object arg : args) {
// Judge whether the request parameter belongs to BaseConfigRequest type
if (arg instanceof BaseConfigRequest) {
// Belong to , Then the request parameters are forcibly converted
BaseConfigRequest baseConfigRequest = (BaseConfigRequest) arg;
log.info(" Authentication base class -baseConfigRequest:{}", ObjectUtils.getDisplayString(baseConfigRequest));
// Get Authentication id
String appId = baseConfigRequest.getAppId();
// Get ciphertext
String cipherText = baseConfigRequest.getCipherText();
// Through authentication id Get the authentication configuration object
EduAuthConfig authConfig = authConfigService.getAuthConfig(appId);
log.info("authConfig:{}", ObjectUtils.getDisplayString(authConfig));
// If authentication id If it is not found, an exception will be thrown. Authentication fails
Assert.notNull(authConfig, " No appId Corresponding authentication configuration information , Authentication failure ");
// According to the ciphertext 、 Decrypt the private key to obtain authentication key
String appKey = RSAUtil.decrypt(cipherText, authConfig.getPrivateKey());
log.info(" Decrypt and get appKey:{}", appKey);
// If authentication key Null or decrypted authentication key And configured authentication key If not, an exception will be thrown. Authentication fails
if (appKey == null || !appKey.equals(authConfig.getAppKey())) {
throw new BaseException(" Authentication parameter error , Authentication failure ");
}
// The authentication ends the cycle
return;
}
}
}
}
}
3. Define an authentication base class
@Data
@ApiModel(value = " Authentication base class ")
public class BaseConfigRequest<T> implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = " authentication Id")
@NotBlank(message = " authentication id Can't be empty ")
private String appId;
@ApiModelProperty(value = " Ciphertext ")
@NotBlank(message = " Ciphertext cannot be empty ")
private String cipherText;
@ApiModelProperty(value = " Any other data ",notes = " Use when authenticating @Valid Comment on check ")
@Valid
private T data;
}
4. The test method
@Authorization
@ApiOperation(value = " receive messages ")
@RequestMapping(value = "/receiveMsg", method = RequestMethod.POST)
public BaseResult<String> receiveMsg(@Validated @RequestBody BaseConfigRequest<MessageSendRequest> request) {
return BaseResult.judgeOperate(messageService.receiveMsg(request));
}
边栏推荐
- Analyze the implementation principle of zero copy mechanism, applicable scenarios and code implementation
- Selenium upload file
- Visio标注、批注位置
- 剑指 Offer 13. 机器人的运动范围 (BFS)
- 最受欢迎的30款开源软件
- [the sixth operation of modern signal processing]
- 力扣今日题-535. TinyURL 的加密与解密
- mongoTemplate - distinct 使用
- R语言ggplot2可视化:使用patchwork包(直接使用加号+)将两个ggplot2可视化结果横向组合、接着再和第三个图像横向组合起来(三幅图各占比例为50%、25%、25%)
- SCM系统是什么?供应链管理系统有哪些优势?
猜你喜欢
随机推荐
Selenium upload file
Split palindrome string [dp + DFS combination]
R language uses user-defined functions to write deep learning leaky relu activation functions and visualize leaky relu activation functions
Inherit Chinese virtues, pay attention to the health of the middle-aged and the elderly, and Yurun milk powder has strong respect for the elderly
VB.Net读写NFC Ntag标签源码
phpunit骚操作之静态类的部分mock
小程序容器是什么技术?能助力物联网企业红海突围?
R语言epiDisplay包的aggregate函数将数值变量基于因子变量拆分为不同的子集,计算每个子集的汇总统计信息、aggregate.data.frame函数包含缺失值的情况下分组统计结果为NA
mysql游标的作用是什么
Selenium key combination operation
开源仓库贡献 —— 提交 PR
位图的详细介绍及模拟实现
最受欢迎的30款开源软件
SRM supplier collaborative management system function introduction
Multi mode concurrent implementation of tortoise and rabbit race in go language
跨境独立站语言unicode转希伯来语
Master slave replication of MySQL
What is the function of MySQL cursors
The dplyr package filter function of R language filters the data in dataframe data through combinatorial logic (and logic). The content of one field is equal to one of the specified vectors, and the v
linux中mysql 1045错误如何解决


![Split palindrome string [dp + DFS combination]](/img/7b/221b000984977508f849e19802c2c2.png)





![[the sixth operation of modern signal processing]](/img/49/7844a00077e56fd4d73e3ba515f8a6.png)