Webflux onAthenticationFailure wird in der API nicht ausgelöstJava

Java-Forum
Anonymous
 Webflux onAthenticationFailure wird in der API nicht ausgelöst

Post by Anonymous »

Ich habe eine Webflux-API, die angepasste Daten an Endpunkte sendet, wenn der Benutzer falsche Anmeldeinformationen angibt. Dementsprechend habe ich unten einen angepassten serverAuthenticationFailureHandler codiert.

Code: Select all

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.server.WebFilterExchange;
import org.springframework.security.web.server.authentication.ServerAuthenticationFailureHandler;
import org.springframework.stereotype.Component;

import reactor.core.publisher.Mono;

import java.util.HashMap;
import java.util.Map;
@Component
/*
In Spring WebFlux security, you use the ServerAuthenticationFailureHandler interface to handle authentication failures.  This is the reactive equivalent of the servlet-based AuthenticationFailureHandler.
*   */

public class Authentication_Failure_Handler implements ServerAuthenticationFailureHandler {

private final ObjectMapper objectMapper = new ObjectMapper();

@Override
public Mono onAuthenticationFailure(WebFilterExchange webFilterExchange, AuthenticationException exception) {
return Mono.defer(() -> {
webFilterExchange.getExchange().getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
webFilterExchange.getExchange().getResponse().getHeaders().setContentType(MediaType.APPLICATION_JSON);

Map errorDetails = new HashMap();
errorDetails.put("timestamp", System.currentTimeMillis());
errorDetails.put("status", HttpStatus.UNAUTHORIZED.value());
errorDetails.put("error", "Unauthorized");
errorDetails.put("message", exception.getMessage());

try {
byte[] bytes = objectMapper.writeValueAsBytes(errorDetails);
DataBuffer buffer = webFilterExchange.getExchange().getResponse().bufferFactory().wrap(bytes);
return webFilterExchange.getExchange().getResponse().writeWith(Mono.just(buffer));
} catch (Exception e) {
return Mono.error(e);
}
});
}

}
Außerdem lautet die SecurityWebfilterchain wie folgt:

Code: Select all

import Housing_Rest_Web_API.security.Handler.Authentication_Failure_Handler;
import Housing_Rest_Web_API.security.jwt.JwtFilter;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableReactiveMethodSecurity;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;

@Configuration
@EnableWebFluxSecurity
@EnableReactiveMethodSecurity
@RequiredArgsConstructor
public class MainSecurity {

private final Authentication_Failure_Handler  authenticationfailurehandler;
// private final SecurityContextRepository securityContextRepository;

@Bean
public SecurityWebFilterChain filterChain( ServerHttpSecurity http, JwtFilter jwtFilter)
{
return http
.csrf(csrf -> csrf.disable())// Disable CSRF for API endpoints, if applicable
.formLogin(formLogin ->formLogin
.authenticationFailureHandler(authenticationfailurehandler)) // Set the custom handler
.authorizeExchange(exchanges -> exchanges
.pathMatchers("/auth/**").permitAll()
.anyExchange().authenticated())
.build();
}

}
Und schließlich

Code: Select all

import Housing_Rest_Web_API.Exception.ResourceNotFoundException;
import Housing_Rest_Web_API.security.Dto.CreateUserDto;
import Housing_Rest_Web_API.security.Dto.LoginDto;
import Housing_Rest_Web_API.security.Dto.TokenDto;
import Housing_Rest_Web_API.security.entity.user;
import Housing_Rest_Web_API.security.enums.Role;
import Housing_Rest_Web_API.security.jwt.JwtProvider;
import Housing_Rest_Web_API.security.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;

@Service
@Slf4j
@RequiredArgsConstructor

public class UserService {

private final UserRepository userRepository;
private final JwtProvider jwtProvider ;
private final PasswordEncoder passwordEncoder;

public MonoLogin(LoginDto dto)
{

return userRepository.findByUsernameOrEmail(dto.getUsername(), dto.getUsername())
.filter(user-> passwordEncoder.matches(dto.getPassword(), user.getPassword()))
.map(user->  new TokenDto( jwtProvider.generateToken(user)));

}
public Monocreate (CreateUserDto dto) {
try {
user user = Housing_Rest_Web_API.security.entity.user.builder()
.username(dto.getUsername())
.email(dto.getEmail())
.password(passwordEncoder.encode(dto.getPassword()))
// .roles(Role.ROLE_ADMIN.name() + "," + Role.ROLE_USER.name())
.roles( Role.ROLE_USER.name())
.build();
Mono userExists = userRepository.findByUsernameOrEmail(user.getUsername(), user.getEmail()).hasElement();
return userExists
.flatMap(exists -> exists ? Mono.error(new ResourceNotFoundException("User not found for this id :: " + dto.getUsername()))
: userRepository.save(user));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
Mein Verständnis ist, dass, wenn der Benutzer an den Endpunkten die falschen Anmeldeinformationen eingibt, die im serverAuthenticationFailureHandler eingebettete benutzerdefinierte Nachricht aktiviert wird, was nicht der Fall ist. Wenn ich die richtigen Anmeldeinformationen eingebe, wird ein Token ausgestellt, das ich codiert habe. Wenn die Anmeldeinformationen jedoch falsch sind, wird auf Postman der Status 200 angezeigt.
Was fehlt in der obigen Logik?

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post