Безопасность Spring с JWT при авторизации через телеграмму

Не могу корректно авторизоваться через телеграмм токен, вроде все сделал, но при запросе получаю ошибку 403, хотя контекст правильный

Не пойму в чем проблема, контекст авторизован и роли есть, все настроено, но возвращает 403

SecurityContextImpl [Authentication=UsernamePasswordAuthenticationToken [Principal=ru.alishev.springcourse.FirstSecurityApp.security.TelegramUserDetails@3e264c5e, Credentials=[PROTECTED], Authenticated=true, Details=null, Granted Authorities=[Include0]]]

Конфигурация безопасности:

package ru.alishev.springcourse.FirstSecurityApp.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import ru.alishev.springcourse.FirstSecurityApp.services.TelegramDetailService;

/**
 * @author Neil Alishev
 */
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private final TelegramDetailService telegramDetailService;
    private final JWTFilter jwtFilter;


    @Autowired
    public SecurityConfig(TelegramDetailService telegramDetailService, JWTFilter jwtFilter) {
        this.telegramDetailService = telegramDetailService;
        this.jwtFilter = jwtFilter;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // конфигурируем сам Spring Security
        // конфигурируем авторизацию
        http
                .csrf().disable()
                .authorizeRequests()
                .antMatchers("/api/tg_users/auth/telegram").hasRole("Include0")
                .antMatchers("/authh/login", "/authh/registration", "/error", "/api/tg_users", "api/tg_users/auth/telegram").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin().loginPage("/api/tg_users")
                .loginProcessingUrl("/process_login")
                .defaultSuccessUrl("/hello", true)
                .failureUrl("/auth/login?error")
                .and()
                .logout()
                .logoutUrl("/logout")
                .logoutSuccessUrl("/auth/login")
                .and()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        http.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);
    }


    // Настраиваем аутентификацию
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(telegramDetailService)
                .passwordEncoder(getPasswordEncoder());
    }

    @Bean
    public PasswordEncoder getPasswordEncoder() {
        return new BCryptPasswordEncoder();

    }

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

JWTFilter:

package ru.alishev.springcourse.FirstSecurityApp.config;

import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.JWTVerifier;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import ru.alishev.springcourse.FirstSecurityApp.security.JWTUtil;
import ru.alishev.springcourse.FirstSecurityApp.security.TelegramUserDetails;
import ru.alishev.springcourse.FirstSecurityApp.services.TelegramDetailService;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
public class JWTFilter extends OncePerRequestFilter {

    private final JWTUtil jwtUtil;
    private final TelegramDetailService telegramDetailService;

    @Autowired
    public JWTFilter(JWTUtil jwtUtil, TelegramDetailService telegramDetailService) {
        this.jwtUtil = jwtUtil;
        this.telegramDetailService = telegramDetailService;
    }


    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String authHeader = request.getHeader("Authorization");

        if (authHeader != null && !authHeader.isEmpty() && authHeader.startsWith("Bearer ")) {
            String jwt = authHeader.substring(7);
//            System.out.println(jwt);

            if (jwt.isEmpty()) {
                response.sendError(HttpServletResponse.SC_BAD_REQUEST,
                        "Invalid JWT Token in Bearer Header");
            } else {
                try {
                String username = jwtUtil.validateTokenAndRetrieveClaim(jwt);
//                System.out.println(username);
                TelegramUserDetails telegramUserDetails = telegramDetailService.loadUserByUsername(username);

//                System.out.println("tut");

                UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(telegramUserDetails,
                        telegramUserDetails.getPassword(),
                        telegramUserDetails.getAuthorities());


                if (SecurityContextHolder.getContext().getAuthentication() == null) {
                    SecurityContextHolder.getContext().setAuthentication(auth);
                    System.out.println(SecurityContextHolder.getContext());
                    }
                } catch (JWTVerificationException ex) {
                    System.out.println("ne proshlo");
                }
            }
        }
        filterChain.doFilter(request, response);
    }
}

JWTUтил:

package ru.alishev.springcourse.FirstSecurityApp.security;


import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.time.ZonedDateTime;

@Component
public class JWTUtil {

    public String generateToken(String username) {
        Date expirationDate = Date.from(ZonedDateTime.now().plusMinutes(60).toInstant());
        // 60 минут действиe токена

        return JWT.create()
                .withSubject("Telegram user details")
                .withClaim("username", username)
                .withIssuedAt(new Date())
                .withIssuer("Quiz game")
                .withExpiresAt(expirationDate)
                .sign(Algorithm.HMAC256("secret"));
    }

    public String validateTokenAndRetrieveClaim(String token) throws JWTVerificationException {
        JWTVerifier verifier = JWT.require(Algorithm.HMAC256("secret"))
                .withSubject("Telegram user details")
                .withIssuer("Quiz game")
                .build();

        DecodedJWT jwt = verifier.verify(token);
        return jwt.getClaim("username").asString();
    }
}

вот полный хардкод, но по идее должно работать, но получаю ошибку 403 пожалуйста, помогите мне исправить

полный код: https://github.com/Include5/gameTG

Пожалуйста, обрежьте свой код, чтобы было легче найти вашу проблему. Следуйте этим рекомендациям, чтобы создать минимально воспроизводимый пример.

Community 20.10.2022 07:59
0
1
58
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я изменился

.antMatchers("/api/tg_users/auth/telegram").hasRole("Include0")

к

.antMatchers("/api/tg_users/auth/telegram").hasAuthority("Include0")

и это сработало

Другие вопросы по теме