Spring Security, logowanie z użyciem tokena

Spring Security, logowanie z użyciem tokena
K7
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 43
0

Cześć, napisałem system do logowania z uzyciem JWT w Spring-Boot,
po wysłaniu POST w postmanie z credentialsami email i password, zamiast w odpowiedzi zwrotnej dostac token by go używać w kolejnych rządaniach dostaję zamiast tego 401 Unathorization

kod:

controller do logowania, w dto do tego znajduje sie tylko pole na email i password

Kopiuj
@RestController
@RequestMapping("/api/auth")
public class AuthController {

    @Autowired
    AuthenticationManager authenticationManager;

    @Autowired
    JwtTokenProvider tokenProvider;

    @PostMapping
    public ResponseEntity<?> authenticateUser(@Valid @RequestBody AuthRequest request){
        Object principal;
        Object credentials;
        Authentication authentication = authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(
                        request.getEmail(),
                        request.getPassword()
                ));
        SecurityContextHolder.getContext().setAuthentication(authentication);

        String jwt = tokenProvider.generateToken(authentication);
        return ResponseEntity.ok(new JwtAuthenticationResponse(jwt));
    }
}

SecurityConfig

Kopiuj
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    SecurityUserDetailsService securityUserDetailsService;

    @Autowired
    private JwtAuthenticationEntryPoint unauthorizedHandler;

    @Bean
    public JwtAuthenticationFilter jwtAuthenticationFilter(){
        return new JwtAuthenticationFilter();
    }

    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    @Bean(BeanIds.AUTHENTICATION_MANAGER)
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception{
        return super.authenticationManagerBean();
    }

    @Override
    public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception{
        authenticationManagerBuilder
                .userDetailsService(securityUserDetailsService)
                .passwordEncoder(passwordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception{
        http
                .cors()
                .and()
                .csrf()
                .disable()
                .exceptionHandling()
                .authenticationEntryPoint(unauthorizedHandler)
                .and()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                .antMatchers("/",
                        "/favicon.ico",
                        "/**/*.png",
                        "/**/*.gif",
                        "/**/*.svg",
                        "/**/*.jpg",
                        "/**/*.html",
                        "/**/*.css",
                        "/**/*.js")
                .permitAll();
//                .antMatchers("/api/auth/**", "/api/user/register/**", "/api/user/namecheck/**", "/api/password/**")
//                .permitAll()
//                .antMatchers("/api/user/checkUsernameAvailability", "/api/user/checkEmailAvailability")
//                .permitAll()
//                .anyRequest()
//                .authenticated();

        http.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
        http.headers().cacheControl();

    }
}

CorsConfig

Kopiuj
@Configuration
public class CorsConfig {

    @Bean
    public CorsFilter corsFilter(){
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();

        config.setAllowCredentials(true);
        config.addAllowedOrigin("*"); 
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");

        source.registerCorsConfiguration("/api/**", config);
        return new CorsFilter(source);
    }
}

JwtAuthenticationEntryPoint

Kopiuj
@Component
public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint, Serializable {
    private static final long serialVersionUID = 3798723588865329956L;


    @Override
    public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, org.springframework.security.core.AuthenticationException e) throws IOException, ServletException {
        httpServletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
    }
}

JwtAuthenticationFilter

Kopiuj
public class JwtAuthenticationFilter extends OncePerRequestFilter {

    @Autowired
    private JwtTokenProvider tokenProvider;

    @Autowired
    private SecurityUserDetailsService securityUserDetailsService;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        try {
            String jwt = getJwtFromRequest(request);

            if (StringUtils.hasText(jwt) && tokenProvider.validateToken(jwt)) {
                UUID userId = tokenProvider.getUserIdFromJWT(jwt);
                UserDetails userDetails = securityUserDetailsService.loadUserById(userId);

                UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));

                SecurityContextHolder.getContext().setAuthentication(authentication);
            }
        } catch (Exception ex) {
            logger.error("Could not set user authentication in security context", ex);
        }

        filterChain.doFilter(request, response);
    }

    private String getJwtFromRequest(HttpServletRequest request) {
        String bearerToken = request.getHeader("Authorization");
        if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) {
            return bearerToken.substring(7);
        }
        return null;
    }
}

JwtTokenProvider

Kopiuj
@Component
public class JwtTokenProvider {

    @Value("${jwt.salt}")
    private String jwtSalt;

    @Value("${jwt.expiry}")
    private int jwtExpiry;

    public String generateToken(Authentication authentication) {
        AuthenticatedUser userEntity = (AuthenticatedUser) authentication.getPrincipal();

        Date now = new Date();
        Date expiryDate = new Date(now.getTime() + jwtExpiry);

        return Jwts.builder()
                .setSubject(userEntity.getId().toString())
                .setIssuedAt(new Date())
                .setExpiration(expiryDate)
                .signWith(SignatureAlgorithm.HS512, jwtSalt)
                .compact();
    }

    public UUID getUserIdFromJWT(String token) {
        Claims claims = Jwts.parser()
                .setSigningKey(jwtSalt)
                .parseClaimsJws(token)
                .getBody();

        return UUID.fromString(claims.getSubject());
    }

    public boolean validateToken(String authToken) {
        try {
            Jwts.parser().setSigningKey(jwtSalt).parseClaimsJws(authToken);
VA
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 127
0

Hej, antMatchers("/api/auth masz zakomentowane

PI
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 2787
0

Do tych resourców, którym dajesz .permitAll(), musisz dodać też endpoint do logowania - bo w momencie dostania się do tego endpointu, na logikę, nie jesteś jeszcze zalogowany.

Shalom
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Space: the final frontier
  • Postów: 26433
1

Ale tak generalnie to gdzie jest problem? (poza tym że kod ukradłeś skadś i go w ogóle nie rozumiesz...)
Odkomentuj permit dla endpointu który ma zwrócić tokena, bo inaczej zawsze dostaniesz tam 401. Jak już to zrobisz to co się dzieje? Powinno puszczać cię do kontrolera. Dostajesz z tego kontrolera token? Nie? Postaw tam breakpoint i zobacz co się dzieje.
Nie wiem czemu robisz tam jakis dziwne filtry zamiast użyć jwt() z SpringSecurity, ale pewnie ty też nie wiesz, ot ukradłeś akurat taki kod gdzie tak było xD

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.