如何在 Spring Security 中为所有请求添加 jwt 身份验证标头?

Posted

技术标签:

【中文标题】如何在 Spring Security 中为所有请求添加 jwt 身份验证标头?【英文标题】:How to add jwt authendication header with all requests in spring security? 【发布时间】:2017-01-02 23:18:45 【问题描述】:

我按照link 设置了 jwt 身份验证。它工作正常。所有请求都是通过附加身份验证标头从 java 脚本发出的,如下所示。

    $.ajax(
        url: "/user",
        type: "GET",
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        headers: "Authorization": token,
        success: function (data, textStatus, jqXHR) 
            var $userInfoBody = $userInfo.find("#userInfoBody");

            $userInfoBody.append($("<div>").text("Username: " + data.username));
            $userInfoBody.append($("<div>").text("Email: " + data.email));

            var $authorityList = $("<ul>");
            data.authorities.forEach(function (authorityItem) 
                $authorityList.append($("<li>").text(authorityItem.authority));
            );
            var $authorities = $("<div>").text("Authorities:");
            $authorities.append($authorityList);
            $userInfoBody.append($authorities);
            $userInfo.show();
        
    );

但我希望将其附加到所有后续请求,而不是通过 javascript

这是我的安全配置

httpSecurity
            // we don't need CSRF because our token is invulnerable
            .csrf()
            .disable()
            .exceptionHandling()
            .authenticationEntryPoint(unauthorizedHandler)
            .and()
            // don't create session
            .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
            .authorizeRequests()
            // .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
            // allow anonymous resource requests
            .antMatchers(HttpMethod.GET, "/*.html", "/favicon.ico", "/**/*.html", "/**/*.css", "/**/*.js")
            .permitAll().antMatchers("/auth/**").permitAll().antMatchers("/vendors/**").permitAll()
            .antMatchers("/production/images/**").permitAll().anyRequest().authenticated().and().formLogin()
            .loginPage("/login").loginProcessingUrl("/loginprocess").failureUrl("/?loginFailure=true").permitAll();

这是我的身份验证过滤器

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
        ServletException 
    HttpServletRequest httpRequest = (HttpServletRequest) request;
    String authToken = httpRequest.getHeader(this.tokenHeader);
    // authToken.startsWith("Bearer ")
    // String authToken = header.substring(7);
    String username = jwtTokenUtil.getUsernameFromToken(authToken);
    System.out.println("Token is " + authToken);
    System.out.println("Username is " + username);
    System.out.println("Audience is from " + jwtTokenUtil.getAudienceFromToken(authToken));
    if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) 
        UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
        System.out.println(userDetails.getAuthorities());
        if (jwtTokenUtil.validateToken(authToken, userDetails)) 
            UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
                    userDetails, null, userDetails.getAuthorities());
            authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpRequest));
            SecurityContextHolder.getContext().setAuthentication(authentication);
         else 
            System.out.println("Token is invalid ");
        
    
    chain.doFilter(request, response);

如何在身份验证后将身份验证标头附加到服务器的响应中。这样所有后续请求都将自动使用该身份验证标头。

我认为的方法是否正确?或者还有其他最好的方法吗?

【问题讨论】:

【参考方案1】:

前端负责为每个请求添加标头,而不是后端。如果您不想使用 JS 执行此操作,则可以使用安全的 httponly cookie。当您从后端设置 cookie 时,它​​将包含在对发出它的域的每个后续请求中。

但是,使用 cookie 存在一些安全问题。 This article 很好地解释了安全注意事项。

【讨论】:

以上是关于如何在 Spring Security 中为所有请求添加 jwt 身份验证标头?的主要内容,如果未能解决你的问题,请参考以下文章

如何避免自定义过滤器在spring-security中为不安全的url运行

如何在 Spring Security 中为所有请求添加 jwt 身份验证标头?

如何在spring security中为来自两个不同表的不同用户配置身份验证?

Spring:HttpSession在集群Tomcat故障转移中为SPRING_SECURITY_CONTEXT返回了空对象

无法在 Spring Security 中为 oauth/token 端点启用 CORS

如何使用 Spring Security 保护 Vaadin 流应用程序