当前位置: 首页 > 知识库问答 >
问题:

为spring boot制作黑名单JWT令牌

潘璞瑜
2023-03-14
@PutMapping(value = "/destroy", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public JwtBlacklist logout(@RequestBody Map<String,String> json, HttpSession httpSession) throws UnsupportedEncodingException {

    String token = json.get("token");

    JwtBlacklist jwtBlacklist = new JwtBlacklist();
    jwtBlacklist.setToken(token);
    jwtBlacklistRepository.save(jwtBlacklist);

    return jwtBlacklistRepository.save(jwtBlacklist);
}   

现在最大的问题是,当我尝试将用户在连接期间必须使用的令牌列入黑名单时,当它断开连接时,这个令牌不再有效,这里的代码I jwtfilter.java

public class JWTFilter extends GenericFilterBean {
    @Value("${app.jwtSecret}")
    public String jwtsecret;
    @Autowired
    public JwtBlacklistRepository jwtBlacklistRepository;

    @Override
    public void doFilter(final ServletRequest req,
                         final ServletResponse res,
                         final FilterChain chain) throws IOException, ServletException {

        final HttpServletRequest request = (HttpServletRequest) req;
        final HttpServletResponse response = (HttpServletResponse) res;
        final String authHeader = request.getHeader("authorization");

        if ("OPTIONS".equals(request.getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);

            chain.doFilter(req, res);
        } else {

            if (authHeader == null || !authHeader.startsWith("Bearer ")) {
                throw new ServletException("Missing or invalid Authorization header");
            }

            final String token = authHeader.substring(7);
            JwtBlacklist blacklist = this.jwtBlacklistRepository.findByTokenEquals(token);

                    if(blacklist == null) {
                        final Claims claims = Jwts.parser().setSigningKey("topsecretjwtpass".getBytes(StandardCharsets.UTF_8)).parseClaimsJws(token).getBody();
                        request.setAttribute("claims", claims);
                    } else {
                        throw new ServletException("Invalid token." + "");

                    }

            chain.doFilter(req, res);
        }

    }
} 

现在,当我尝试使用黑名单令牌或不使用黑名单令牌进行查询时,我会出现以下错误

这是模型

public class JwtBlacklist {
    @Id
    private String _id;
    @Indexed(direction = IndexDirection.ASCENDING)
    private String token;

    public String get_id() {
        return _id;
    }

    public void set_id(String _id) {
        this._id = _id;
    }

    public String getToken() {
        return token;
    }

    public void setToken(String token) {
        this.token = token;
    }

    @Override
    public String toString() {
        return "JwtBlacklist{" +
                "_id='" + _id + '\'' +
                ", token='" + token + '\'' +
                '}';
    }
}

这是JwtBlacklist的存储库


import com.monarque.bank.monarque.dao.models.JwtBlacklist;
import org.springframework.data.mongodb.repository.MongoRepository;


public interface JwtBlacklistRepository extends MongoRepository<JwtBlacklist,String> {


JwtBlacklist findByTokenEquals(String token);

}

共有1个答案

池宸
2023-03-14

总之,问题的发生是因为您的JWTFilter不是由Spring管理的,所以您不能仅仅要求他为您注入bean和属性。

幸运的是,有一个简单的方法使事情工作!

试着看看添加以下init方法是否适合您:

public class JWTFilter extends GenericFilterBean {
  @Value("${app.jwtSecret}")
  public String jwtsecret;
  @Autowired
  public JwtBlacklistRepository jwtBlacklistRepository;

  //ask spring to inject the values based on current context
  @PostConstruct
  public void init() {
    SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
  }

  @Override
  public void doFilter(final ServletRequest req,
                       final ServletResponse res,
                       final FilterChain chain) throws IOException, 
  ServletException {

  ....
  }
}
 类似资料:
  • 很多时候,我们需要根据调用来源来判断该次请求是否允许放行,这时候可以使用 Sentinel 的来源访问控制(黑白名单控制)的功能。来源访问控制根据资源的请求来源(origin)限制资源是否通过,若配置白名单则只有请求来源位于白名单内时才可通过;若配置黑名单则请求来源位于黑名单时不通过,其余的请求通过。 调用方信息通过 ContextUtil.enter(resourceName, origin)

  • 我目前在Spring上有一个RESTful后端。由于RESTful是无状态的,所以我决定使用JWT,因为在我的整个研究过程中,这是每个人都推荐的(至少对于基于REST的应用程序)。 考虑到身份验证阶段的正常流程: 现在看看上面的流程,我们需要一个表来存储访问令牌和刷新令牌的黑名单JWT令牌。由于我们不希望用户经常重新登录,因此刷新令牌可能具有多年的有效期。 因此,我的问题是:恶意用户是否能够通过多

  • 我已经验证了JWT令牌,它在会话存储中。 计算机1以普通用户身份登录计算机2以管理员身份登录 如果我在会话存储中将机器1 jwt令牌替换为机器2,并且如果我进一步调用api,服务器应该说未经授权的访问。

  • 我目前正在使用Vapor开发Swift后端。我的iOS客户端使用新的iOS 13功能“使用Apple登录”。当用户登录时,我会得到一个身份令牌(访问令牌),这是一个由Apple签名的有效JWT令牌。这将在所有正在进行的通信中发送到服务器,以验证服务器提供的某些路由。 在服务器上,我想通过验证令牌签名来验证发送的令牌是否确实由Apple签名,并且不是由某些恶意用户专门创建的。Apple提供了一个HT

  • 问题内容: 是否有一种方法(例如,Maven插件)可以获取不需要的/黑名单的依赖项列表(直接和传递),并且如果检测到列出的依赖项之一,则构建失败? 在我的项目中,我们严格地希望摆脱Apache Commons Logging并将其替换为SLF4J JCL Bridge。我知道我们必须排除自己的不必要的部门,但是如果有人添加了一个依赖项并将其列入黑名单,那么我希望构建失败。 问题答案: 您可以使用禁

  • 我正在制作一个javascript客户端,它使用JWT令牌连接到Api。在服务器端没有问题,我可以创建令牌对其进行签名,然后验证签名,从而确保没有人篡改令牌。 但我如何在客户端做到这一点。我可以解码JWT令牌并查看头、负载和签名。但是如何在客户端验证签名?是否有用于此的库,如何将公钥传输到客户端? 如果我不验证签名,我怎么知道令牌没有被篡改?