How can I handle Api Gateway JWT Authentication&Authorization Approach in " Spring Boot " - Stack Over

I wanted to develop a small microservice application. My service projects:1-Monolithic application (he

I wanted to develop a small microservice application. My service projects:

1-Monolithic application (here are the APIs)

2-Auth service(register, login operations & generates JWT token)

3-Api gateway

I specified which endpoints are secure and require roles in the api gateway.

@Configuration
@EnableWebSecurity
public class SecurityConfig{

    private final JwtAuthenticationFilter jwtAuthenticationFilter;

    public SecurityConfig(JwtAuthenticationFilter jwtAuthenticationFilter) {
        this.jwtAuthenticationFilter = jwtAuthenticationFilter;
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .csrf(AbstractHttpConfigurer::disable)
                .authorizeHttpRequests(auth -> auth

                        // Auth service
                        .requestMatchers("/auth/login", "/auth/register", "/auth/register/admin").permitAll()

                        .requestMatchers("/auth/role", "/auth/role/{id}").hasAnyAuthority("PROJECT GROUP MANAGER", "PROJECT MANAGER")

                        // Core app
                        .requestMatchers("/api/departments", "/api/projects", "/api/users").hasAuthority("PROJECT GROUP MANAGER")

                        .requestMatchers("/api/projectmembers").hasAnyAuthority("PROJECT GROUP MANAGER", "PROJECT MANAGER")

                        .requestMatchers("/api/fileinfos", "/api/taskcomments", "/api/tasks").authenticated()

                        .anyRequest().authenticated()
                )
                .addFilterBefore(jwtAuthenticationFilter, SecurityContextHolderFilter.class);

        return http.build();
    }
}

Then I wrote a JWT token verification class. Only the secret key is verified and the expiration time is checked.

@Component
public class JwtUtil {

    @Value("${jwt.secret}")
    private String SECRET_KEY;

    // Token validation
    public boolean isTokenValid(String token) {
        try {
            Claims claims = extractAllClaims(token);
            return !isTokenExpired(token);
        } catch (Exception e) {
            return false;
        }
    }

    // Get roles
    public Map<String, String> extractRoles(String token) {
        Claims claims = extractAllClaims(token);
        Object rolesClaim = claims.get("roles");

        if (rolesClaim instanceof Map) {
            return (Map<String, String>) rolesClaim;
        }
        return Collections.emptyMap();
    }

    /* ------------------------ Helper Methods ------------------------ */

    // Get All Claims
    private Claims extractAllClaims(String token) {
        return Jwts.parser()
                .verifyWith(getSignInKey())
                .build()
                .parseSignedClaims(token)
                .getPayload();
    }

    // Check Token Expiration
    private boolean isTokenExpired(String token) {
        Date expiration = extractClaim(token, Claims::getExpiration);
        return expiration != null && expiration.before(new Date());
    }

    // Get Specific Claim
    private <T> T extractClaim(String token, Function<Claims, T> claimsResolver) {
        final Claims claims = extractAllClaims(token);
        return claimsResolver.apply(claims);
    }

    // Get Sign Key
    private SecretKey getSignInKey() {
        byte[] keyBytes = Decoders.BASE64.decode(SECRET_KEY);
        return Keys.hmacShaKeyFor(keyBytes);
    }
}

Finally, I wrote the JwtAuthenticationFilter class. Here, the token is taken from the incoming HTTP request header. My JwtUtil class checks the token. Then the request is forwarded to the next stage.

@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {

    private final JwtUtil jwtUtil;

    @Autowired
    public JwtAuthenticationFilter(JwtUtil jwtUtil) {
        this.jwtUtil = jwtUtil;
    }

    @Override
    protected void doFilterInternal(
            @NonNull HttpServletRequest request,
            @NonNull HttpServletResponse response,
            @NonNull FilterChain filterChain)
            throws ServletException, IOException {

        final String authHeader = request.getHeader("Authorization");

        if (authHeader == null || !authHeader.startsWith("Bearer ")) {
            filterChain.doFilter(request, response);
            return;
        }

        String token = authHeader.substring(7);

        if (jwtUtil.isTokenValid(token)) {
            Map<String, String> roles = jwtUtil.extractRoles(token);
            
            List<SimpleGrantedAuthority> authorities = roles.values().stream()
                    .map(SimpleGrantedAuthority::new)
                    .collect(Collectors.toList());

            UsernamePasswordAuthenticationToken authToken =
                    new UsernamePasswordAuthenticationToken(null, null, authorities);

            SecurityContextHolder.getContext().setAuthentication(authToken);
        }

        filterChain.doFilter(request, response);
    }
}

My question is, is this security approach sufficient? I think that sending an http request for auth service jwt verification would not be a good approach. What are your recommendations? Thank you for your time. Best regards.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744406081a4572638.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信