gpt4 book ai didi

java - 如何禁用特定网址的 Spring 安全性

转载 作者:IT老高 更新时间:2023-10-28 13:02:14 24 4
gpt4 key购买 nike

我正在使用无状态 Spring 安全,但在注册的情况下我想禁用 Spring 安全。我禁用了使用

antMatchers("/api/v1/signup").permitAll().

但它不起作用,我收到以下错误:

 message=An Authentication object was not found in the SecurityContext, type=org.springframework.security.authentication.AuthenticationCredentialsNotFoundException

我认为这意味着 spring 安全过滤器正在工作

我的 url 的顺序总是“/api/v1”

我的 Spring 配置是

@Override
protected void configure(HttpSecurity http) throws Exception {

http.
csrf().disable().
sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).
and().
authorizeRequests().
antMatchers("/api/v1/signup").permitAll().
anyRequest().authenticated().
and().
anonymous().disable();
http.addFilterBefore(new AuthenticationFilter(authenticationManager()), BasicAuthenticationFilter.class);
}

我的身份验证过滤器是

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

String username = httpRequest.getHeader("X-Auth-Username");
String password = httpRequest.getHeader("X-Auth-Password");
String token = httpRequest.getHeader("X-Auth-Token");

String resourcePath = new UrlPathHelper().getPathWithinApplication(httpRequest);

try {

if (postToAuthenticate(httpRequest, resourcePath)) {
processUsernamePasswordAuthentication(httpResponse, username, password);
return;
}

if(token != null){
processTokenAuthentication(token);
}
chain.doFilter(request, response);
} catch (InternalAuthenticationServiceException internalAuthenticationServiceException) {
SecurityContextHolder.clearContext();
logger.error("Internal authentication service exception", internalAuthenticationServiceException);
httpResponse.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
} catch (AuthenticationException authenticationException) {
SecurityContextHolder.clearContext();
httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, authenticationException.getMessage());
} finally {
}
}

private HttpServletRequest asHttp(ServletRequest request) {
return (HttpServletRequest) request;
}

private HttpServletResponse asHttp(ServletResponse response) {
return (HttpServletResponse) response;
}

private boolean postToAuthenticate(HttpServletRequest httpRequest, String resourcePath) {
return Constant.AUTHENTICATE_URL.equalsIgnoreCase(resourcePath) && httpRequest.getMethod().equals("POST");
}

private void processUsernamePasswordAuthentication(HttpServletResponse httpResponse,String username, String password) throws IOException {
Authentication resultOfAuthentication = tryToAuthenticateWithUsernameAndPassword(username, password);
SecurityContextHolder.getContext().setAuthentication(resultOfAuthentication);
httpResponse.setStatus(HttpServletResponse.SC_OK);
httpResponse.addHeader("Content-Type", "application/json");
httpResponse.addHeader("X-Auth-Token", resultOfAuthentication.getDetails().toString());
}

private Authentication tryToAuthenticateWithUsernameAndPassword(String username,String password) {
UsernamePasswordAuthenticationToken requestAuthentication = new UsernamePasswordAuthenticationToken(username, password);
return tryToAuthenticate(requestAuthentication);
}

private void processTokenAuthentication(String token) {
Authentication resultOfAuthentication = tryToAuthenticateWithToken(token);
SecurityContextHolder.getContext().setAuthentication(resultOfAuthentication);
}

private Authentication tryToAuthenticateWithToken(String token) {
PreAuthenticatedAuthenticationToken requestAuthentication = new PreAuthenticatedAuthenticationToken(token, null);
return tryToAuthenticate(requestAuthentication);
}

private Authentication tryToAuthenticate(Authentication requestAuthentication) {
Authentication responseAuthentication = authenticationManager.authenticate(requestAuthentication);
if (responseAuthentication == null || !responseAuthentication.isAuthenticated()) {
throw new InternalAuthenticationServiceException("Unable to authenticate Domain User for provided credentials");
}
logger.debug("User successfully authenticated");
return responseAuthentication;
}

我的 Controller 是

@RestController
public class UserController {

@Autowired
UserService userService;

/**
* to pass user info to service
*/
@RequestMapping(value = "api/v1/signup",method = RequestMethod.POST)
public String saveUser(@RequestBody User user) {
userService.saveUser(user);
return "User registerted successfully";
}
}

我对spring完全陌生,请帮助我怎么做?

最佳答案

当使用 permitAll 时,它意味着每个经过身份验证的用户,但是您禁用了匿名访问,因此这将不起作用。

您想要的是忽略某些 URL,因为它会覆盖采用 WebSecurity 对象和 ignore 模式的 configure 方法。

@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/api/v1/signup");
}

并从 HttpSecurity 部分中删除该行。这将告诉 Spring Security 忽略此 URL,并且不对它们应用任何过滤器。

关于java - 如何禁用特定网址的 Spring 安全性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30366405/

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