Home > Software design >  Spring security with JWT when authorizing via telegram
Spring security with JWT when authorizing via telegram

Time:10-25

I can’t correctly authorize through the telegram token, I seem to have done everything, but when I request I get a 403 error, although the context is correct

I don’t understand what the problem is, the context is authorized and there are roles, everything is configured, but it returns 403

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

SecurityConfig:

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);
    }
}

JWTUtil:

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();
    }
}

here is full hardcoding, but according to the idea it should work, but I get a 403 error please help me fix

full code: https://github.com/Include5/gameTG

CodePudding user response:

I changed

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

to

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

and it worked

  • Related