gpt4 book ai didi

java - 对每个 API 调用进行身份验证

转载 作者:行者123 更新时间:2023-12-02 09:44:49 24 4
gpt4 key购买 nike

我目前有一个通过登录页面进行身份验证的 Spring 服务。现在的愿望是有一种方法使用客户端证书和私钥对每个 API 请求的用户进行身份验证。我创建了一个到外部端点的 POST 请求,用于对用户进行身份验证。我能够在身份验证过滤器中对用户进行身份验证,但随后显示 405 错误。

public class AuthenticationFilter extends GenericFilterBean {

private AuthenticationManager authenticationManager;

public AuthenticationFilter(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest http_request = (HttpServletRequest) request;
HttpServletResponse http_response = (HttpServletResponse) response;

String cert_filename = "certificate.pem";
File cert_file = new File(cert_filename);

if(cert_file.createNewFile())
System.out.println("Successfully created private cert file");
else
System.out.println("Cert file could not be created");

BufferedWriter cert_writer = new BufferedWriter(new FileWriter(cert_filename));
cert_writer.write(cert);
cert_writer.close();

String key_filename = "private_key.key";
File key_file = new File(key_filename);

if(key_file.createNewFile())
System.out.println("Successfully created private key file");
else
System.out.println("Key file could not be created");

BufferedWriter key_writer = new BufferedWriter(new FileWriter(key_filename));
key_writer.write(key);
key_writer.close();

ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.redirectErrorStream(true);
processBuilder.command("curl", ..., ...);
Process process = processBuilder.start();
BufferedReader reader =
new BufferedReader(new InputStreamReader(process.getInputStream()));
StringBuilder builder = new StringBuilder();
String line;
while ( (line = reader.readLine()) != null) {
builder.append(line);
builder.append(System.getProperty("line.separator"));
}
String result = builder.toString();

System.out.println(result);
if(result.contains("\"successful\": true")) {
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("user", "password");
Authentication auth = authenticationManager.authenticate(token);
SecurityContextHolder.getContext().setAuthentication(auth);
// TokenResponse tokenResponse = new TokenResponse(auth.getDetails().toString());
// String tokenJsonResponse = new ObjectMapper().writeValueAsString(tokenResponse);
http_response.setStatus(HttpServletResponse.SC_OK);
//http_response.sendError(HttpServletResponse.SC_OK);
// http_response.addHeader("Content-Type", "application/json");
// http_response.getWriter().print(tokenJsonResponse);
chain.doFilter(request, response);
}
else{
http_response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
http_response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
}

}
}


@EnableWebSecurity
@Order(1000)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

RestAuthenticationEntryPoint restAuthenticationEntryPoint;

String[] permitted = {
"/login",
...
};

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user")
.password("{noop}password")
.roles("USER");

}


@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.exceptionHandling().authenticationEntryPoint(restAuthenticationEntryPoint)
.and()
.authorizeRequests()
.antMatchers(permitted).permitAll()
.anyRequest().authenticated()
.and()
.oauth2Login()
.loginPage("/login")
.defaultSuccessUrl("/swagger-ui.html", true)
.and()
.logout()
.clearAuthentication(true)
.logoutUrl("/logout")
.logoutSuccessUrl("/login").permitAll()
.deleteCookies("JSESSIONID")
.invalidateHttpSession(true);
http.addFilterAfter(new AuthenticationFilter(authenticationManager()), BasicAuthenticationFilter.class);
}


}

最佳答案

The desire now is to have a way to authenticate the user for each API request using a client certificate and private key

显然您缺少一些非常基本的原则,即通过 ssl 进行客户端身份验证的工作原理。这个想法是,客户端拥有其 key 对(私钥和公钥)和一个需要由受信任的证书颁发机构签名的证书。

出于测试目的,您可以使用自签名证书,只是需要信任它(在信任库中),请参阅下面的博客链接。

身份验证将在 channel (https) 级别进行,客户端信息(证书 dn,..)由引擎作为 header 或请求上下文传递

您可以看看以下博客:X.509 Authentication in Spring Security

我通常会将相关信息从外部资源复制到答案中,但在这种情况下,我将复制整个帖子。

关于java - 对每个 API 调用进行身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56743098/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com