【问题标题】:Spring Boot 403 forbidden with POST request in Tomcat 9Tomcat 9中的POST请求禁止Spring Boot 403
【发布时间】:2018-09-11 08:18:08
【问题描述】:

我是 Spring Boot 的新手,我正在创建一个 Web 应用程序。我在没有 JWT 令牌身份验证的情况下绕过“/auth/login” URL。

我创建了一个控制器来处理登录请求并给出响应。

当我在本地使用 URL 调用我的 Web 服务时 http://localhost:9505/auth/login 带正文参数

{
    "username":"abcd@g.l",
    "password" : "newPassword"
}

它工作正常,不检查令牌,但是当我导出它并创建 WAR 文件并部署在服务器上时,它给了我 403 Forbidden 错误。

下面是我在tomcat 9服务器上部署后调用API的URL

http://localhost:9505/myapplicationame/auth/login

你能指导我会是什么问题吗?

以下是我的安全配置方法。

@Override
    protected void configure(HttpSecurity http) throws Exception {
    logger.info("SecurityConfig => configure : Configure in SecurityConfig");
    logger.info("http Request Path : ");

    logger.info("servletContext.getContextPath()) : " + servletContext.getContextPath());
    http
    .csrf()
        .disable()
   .exceptionHandling()
       .authenticationEntryPoint(unauthorizedHandler)
       .and()
   .sessionManagement()
       .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
       .and()
   .authorizeRequests()
       .antMatchers("/",
           "/favicon.ico",
           "/**/*.png",
           "/**/*.gif",
           "/**/*.svg",
           "/**/*.jpg",
           "/**/*.html",
           "/**/*.css",
           "/**/*.js")
           .permitAll()
        .antMatchers("/auth/**")
           .permitAll()
        .antMatchers("/auth/login")
           .permitAll()
       .antMatchers("/permissions")
           .permitAll()
       .anyRequest()
           .authenticated();

    // Add our custom JWT security filter
    http.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
}

下面是我的过滤器类

@Configuration
@CrossOrigin
@EnableWebSecurity
@EnableMBeanExport(registration=RegistrationPolicy.IGNORE_EXISTING)
@EnableGlobalMethodSecurity(securedEnabled = true, jsr250Enabled = true, prePostEnabled = true)
@Order(SecurityProperties.IGNORED_ORDER)

    public class JwtAuthenticationFilter extends OncePerRequestFilter {

    @Autowired
    JwtTokenProvider tokenProvider;

    @Autowired
    CustomUserDetailsService customUserDetailsService;

    @Autowired
    AdminPermissionRepository adminPermissionRepository;

    @Autowired
    PermissionMasterRepository permissionMasterRepository;

    @Autowired
    private ServletContext servletContext;

    @Override
    protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
            FilterChain filterChain) throws IOException, ServletException {
                if (StringUtils.hasText(jwt) && isValidToken) {

                    // Check user email and password
                    UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
                            adminDetails, null, adminDetails.getAuthorities());
                    authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpServletRequest));
                    SecurityContextHolder.getContext().setAuthentication(authentication);
                    logger.info("Before finish doFilterInternal");
                    filterChain.doFilter(httpServletRequest, httpServletResponse);

                }
                filterChain.doFilter(httpServletRequest, httpServletResponse);

            }


    /**
     * To get JWT token from the request
     * 
     * @param httpServletRequest
     * @return String
     */
    private String getJwtFromRequest(HttpServletRequest httpServletRequest) {
        logger.info("JwtAuthenticationFilter => getJwtFromRequest");
        String bearerToken = httpServletRequest.getHeader("Authorization");
        if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) {
            logger.info("Have token");
            return bearerToken.substring(7, bearerToken.length());
        }
        logger.info("Does not have token");
        return null;
    }

    }

下面是我的控制器

@RestController
@Transactional(rollbackFor=Exception.class)
public class AuthController {
        @PostMapping("/auth/login")
        ResponseEntity login(@Valid @RequestBody LoginRequest request)
                throws DisabledException, InternalAuthenticationServiceException, BadCredentialsException {

                // My logic
        return ResponseEntity.ok();
        }
    }

【问题讨论】:

  • 引发此异常的一点是 filterChain.doFilter()。我认为您在发出请求时错过了 jwt 有效负载中的一些信息,请仔细检查它们是否存在,用户名,子,到期时间,范围。
  • 我已经全局处理异常,所以我认为它不会产生异常。

标签: java spring spring-boot spring-security spring-security-rest


【解决方案1】:

问题在于我的 tomcat 服务器中的 CORS。

我在下面的代码中添加了注释,它可以工作。

<filter>
  <filter-name>CorsFilter</filter-name>
  <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
  <init-param>
            <param-name>cors.allowed.origins</param-name>
            <param-value>http://localhost:9505, http://localhost, www.mydomain.io, http://mydomain.io, mydomain.io</param-value>
    </init-param>

</filter>
<filter-mapping>
  <filter-name>CorsFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

谢谢

【讨论】:

  • 我还必须为 FF 添加corsConfiguration.setAllowedOrigins("*");。即使从同一个域访问,对 js.maps 的请求也会返回 403。
【解决方案2】:

尝试在您的课程中添加以下提及的注释。

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired
private ServletContext servletContext;

@Override
    protected void configure(HttpSecurity http) throws Exception {
    logger.info("SecurityConfig => configure : Configure in SecurityConfig");
    logger.info("http Request Path : ");

    logger.info("servletContext.getContextPath()) : " + servletContext.getContextPath());
    http
    .csrf()
        .disable()
   .exceptionHandling()
       .authenticationEntryPoint(unauthorizedHandler)
       .and()
   .sessionManagement()
       .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
       .and()
   .authorizeRequests()
       .antMatchers("/",
           "/favicon.ico",
           "/**/*.png",
           "/**/*.gif",
           "/**/*.svg",
           "/**/*.jpg",
           "/**/*.html",
           "/**/*.css",
           "/**/*.js")
           .permitAll()
        .antMatchers("/auth/**")
           .permitAll()
        .antMatchers("/auth/login")
           .permitAll()
       .antMatchers("/permissions")
           .permitAll()
       .anyRequest()
           .authenticated();

    // Add our custom JWT security filter
    http.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
    }
}

【讨论】:

  • 是的,我也尝试过这种方式,但仍然无法正常工作。我在我的问题中添加了 serverlet 上下文路径。感谢回复
  • 请尝试将注释添加到您的安全类中。
  • 我也尝试过使用注释,但仍然遇到同样的错误。我也更新了代码
猜你喜欢
  • 1970-01-01
  • 2019-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-27
  • 2020-07-19
  • 1970-01-01
  • 2021-09-26
相关资源
最近更新 更多