Cześć, próbuje ugryźć Spring Security i zrobić najprostszy system rejestracji i logowania.
Korzystałem z tego poradnika:
Wszystko pięknie działa w postman, jeśli sam skopiuję zwrócony jwt token i wkleję go do nagłówka Authorization.
Problem pojawia się podczas korzystanie ze strony internetowej. Jak mogę ustawić nagłówek Authorization i z niego pobierać token?
W funkcji doFilterInternal pole authHeader jest ciągle równe 0.
@Component
@RequiredArgsConstructor
public class JwtAuthenticationFilter extends OncePerRequestFilter {
private final JwtService jwtService;
private final UserDetailsService userDetailsService;
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
final String authHeader = request.getHeader("Authorization");
final String jwt;
final String userEmail;
if(authHeader == null || !authHeader.startsWith("Bearer ")){
filterChain.doFilter(request, response);
return;
}
jwt = authHeader.substring(7);
userEmail = jwtService.extractUsername(jwt);
if(userEmail != null && SecurityContextHolder.getContext().getAuthentication() == null){
UserDetails userDetails = this.userDetailsService.loadUserByUsername(userEmail);
if(jwtService.isTokenValid(jwt, userDetails)){
UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(
userDetails,
null,
userDetails.getAuthorities()
);
authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authToken);
}
}
filterChain.doFilter(request, response);
}
}
public AuthenticationResponse signIn(SignInRequestDto request, HttpServletResponse response) {
String identifier = request.getIdentifier();
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(
identifier,
request.getPassword()
));
var user = userRepository.findByEmailOrLogin(identifier, identifier)
.orElseThrow();
return getResponseWithToken(user, response);
}
private AuthenticationResponse getResponseWithToken(User user, HttpServletResponse response){
var jwtToken = jwtService.generateToken(user);
return AuthenticationResponse.builder()
.status(HttpStatus.OK)
.token(jwtToken)
.build();
}
Fetch:
fetch('http://localhost:8080/auth/signInPost', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(signInDto)
})
.then(function (response) {
if (!response.ok) {
if (response.status === 403) {
errorMessage.innerHTML = "Dane logowania nie są poprawne";
}
return;
}
return response.json();
}).then(function (response) {
if (!response) {
return;
}
if(response.status !== "OK"){
errorMessage.innerHTML = response.message;
return;
}
window.location.href = '/';
})
Mogę oczywiście zapisywać token w ciasteczkach i z ciasteczek go pobierać, ale to raczej nie jest najlepsze rozwiązanie i mnie nie satysfakcjonuje.