如何跳出 Spring Boot 的静态语境

kpbwa7wx  于 2023-02-04  发布在  Spring
关注(0)|答案(1)|浏览(107)

当在类“JWTEuthenticationFilter”和“JWTEAuthorizationFilter”中使用时,“createToken”和“getAuthentication”这两个方法都返回错误。错误为Non-static method 'getAuthentication(java.lang.String)' cannot be referenced from a static context
问题是我的代码中没有一个static字段,所以我不理解这个错误,我也不能把方法声明为static,因为我需要使用变量“jwt_secret”和in my previous post,有人解释了为什么我不应该把它设为static:
“Spring不会注入(自动连接)到静态字段中。即使可以,那也没有任何意义。Spring bean是类的示例,但静态字段不与任何一个示例相关联。有一些丑陋的变通办法,但最好是消除静态字段的使用。”
令牌实用程序

package com.XX.ZZ.security;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.stereotype.Component;

import java.util.*;

@Component
public class TokenUtils {

    @Autowired
    @Value("${custom.data.jwt.secret}")
    private final String jwt_secret;

    public TokenUtils(String jwtSecret) {
        jwt_secret = jwtSecret;
    }

    public String createToken(String name, String email){
        long expirationTime = 86400 * 1000;
        Date expirationDate = new Date(System.currentTimeMillis() + expirationTime);

        Map<String, Object> extra = new HashMap<>();
        extra.put("name", name);

        return Jwts.builder()
                .setSubject(email)
                .setExpiration(expirationDate)
                .addClaims(extra)
                .signWith(Keys.hmacShaKeyFor(jwt_secret.getBytes()))
                .compact();
    }

    public UsernamePasswordAuthenticationToken getAuthentication(String token){
        try {
            Claims claims = Jwts.parserBuilder()
                    .setSigningKey(jwt_secret.getBytes())
                    .build()
                    .parseClaimsJws(token)
                    .getBody();

            String email = claims.getSubject();

            return new UsernamePasswordAuthenticationToken(email, null, Collections.emptyList());
        } catch (JwtException e){
            return null;
        }
    }
}

JWTAuthorizationFilter,UsernamePasswordAuthenticationToken usernamePAT = TokenUtils.getAuthentication(token)中的错误

package com.XX.ZZ.security;

import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;

@Component
public class JWTAuthorizationFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException {

        String bearerToken = request.getHeader("Authorization");

        if(bearerToken != null && bearerToken.startsWith("Bearer ")){
            String token = bearerToken.replace("Bearer ", "");
            UsernamePasswordAuthenticationToken usernamePAT = TokenUtils.getAuthentication(token);
            SecurityContextHolder.getContext().setAuthentication(usernamePAT);
        }
        filterChain.doFilter(request, response);
    }
}

JwtAuthenticationFilter,String token = TokenUtils.createToken中的错误

package com.XX.ZZ.security;

import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import java.io.IOException;
import java.util.Collections;

public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request,
                                                HttpServletResponse response) throws AuthenticationException {

        AuthCredentials authCredentials = new AuthCredentials();

        try {
            authCredentials = new ObjectMapper().readValue(request.getReader(), AuthCredentials.class);
        } catch (IOException e){ }

        UsernamePasswordAuthenticationToken usernamePAT = new UsernamePasswordAuthenticationToken(
                authCredentials.getEmail(),
                authCredentials.getPassword(),
                Collections.emptyList()
        );

        return getAuthenticationManager().authenticate(usernamePAT);
    }

    @Override
    protected void successfulAuthentication(HttpServletRequest request,
                                            HttpServletResponse response,
                                            FilterChain chain,
                                            Authentication authResult) throws IOException, ServletException {

         UserDetailsImpl userDetails = (UserDetailsImpl) authResult.getPrincipal();
         String token = TokenUtils.createToken(userDetails.getName(), userDetails.getUsername());

         response.addHeader("Authorization", "Bearer " + token);

         response.getWriter().flush();

        super.successfulAuthentication(request, response, chain, authResult);
    }
}
qoefvg9y

qoefvg9y1#

通过调用TokenUtils.getAuthentication(token),你实际上就像调用static一样调用它。你需要一个JWTAuthenticationFilter中的示例:

TokenUtils tokenUtilsInstance = new TokenUtils("my secret");

tokenUtilsInstance.getAuthentication(token)

您可能需要删除构造函数TokenUtils(String jwtSecret)。这将允许在JWTAuthenticationFilter中执行以下操作。这是更好的Spring实践。

@Autowired
TokenUtils tokenUtilsInstance;

相关问题