|
|
@@ -0,0 +1,69 @@
|
|
|
+package cn.seecoder.devmanage.security;
|
|
|
+
|
|
|
+import cn.seecoder.devmanage.model.vo.Response;
|
|
|
+import com.auth0.jwt.JWT;
|
|
|
+import com.auth0.jwt.JWTVerifier;
|
|
|
+import com.auth0.jwt.algorithms.Algorithm;
|
|
|
+import com.auth0.jwt.interfaces.DecodedJWT;
|
|
|
+import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
+import lombok.RequiredArgsConstructor;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
|
|
+import org.springframework.security.core.GrantedAuthority;
|
|
|
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
|
|
+import org.springframework.security.core.context.SecurityContextHolder;
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
+import org.springframework.web.filter.OncePerRequestFilter;
|
|
|
+
|
|
|
+import javax.servlet.FilterChain;
|
|
|
+import javax.servlet.ServletException;
|
|
|
+import javax.servlet.http.HttpServletRequest;
|
|
|
+import javax.servlet.http.HttpServletResponse;
|
|
|
+import java.io.IOException;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.Collection;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.Map;
|
|
|
+
|
|
|
+import static org.springframework.http.HttpHeaders.AUTHORIZATION;
|
|
|
+import static org.springframework.http.HttpStatus.FORBIDDEN;
|
|
|
+import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
|
|
|
+
|
|
|
+@Component
|
|
|
+@RequiredArgsConstructor
|
|
|
+@Slf4j
|
|
|
+public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
|
|
+ private final JwtHelper jwtHelper;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
|
|
|
+ String authorizationHeader = request.getHeader(AUTHORIZATION);
|
|
|
+ if (authorizationHeader != null) {
|
|
|
+ try {
|
|
|
+ Algorithm algorithm = jwtHelper.getAlgorithm();
|
|
|
+ JWTVerifier verifier = JWT.require(algorithm).build();
|
|
|
+ DecodedJWT decodedJWT = verifier.verify(authorizationHeader);
|
|
|
+ String username = decodedJWT.getSubject(); // also phone number
|
|
|
+ String authority = decodedJWT.getClaim("auth").asString();
|
|
|
+ Collection<GrantedAuthority> authorities = new ArrayList<>();
|
|
|
+ authorities.add(new SimpleGrantedAuthority(authority));
|
|
|
+ UsernamePasswordAuthenticationToken authenticationToken =
|
|
|
+ new UsernamePasswordAuthenticationToken(username, null, authorities);
|
|
|
+ SecurityContextHolder.getContext().setAuthentication(authenticationToken);
|
|
|
+ filterChain.doFilter(request, response);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("Error JWT parsing or verifying: {}", e.getMessage());
|
|
|
+ response.setStatus(FORBIDDEN.value());
|
|
|
+ response.setContentType(APPLICATION_JSON_VALUE);
|
|
|
+ new ObjectMapper().writeValue(response.getOutputStream(),
|
|
|
+ Response.buildFailure(FORBIDDEN.value(), e.getMessage()));
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ log.error("Request lacks Authorization header.");
|
|
|
+ response.setStatus(FORBIDDEN.value());
|
|
|
+ response.setContentType(APPLICATION_JSON_VALUE);
|
|
|
+ new ObjectMapper().writeValue(response.getOutputStream(),
|
|
|
+ Response.buildFailure(FORBIDDEN.value(), "Lack of Authorization header."));
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|