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条)