【问题标题】:Spring security 401 Unauthorized even with permitAllSpring security 401 Unauthorized 即使使用 permitAll
【发布时间】:2019-03-25 01:06:06
【问题描述】:

我正在使用 Spring 安全性来保护我的 REST 服务中的一些端点。

这是安全配置类:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, jsr250Enabled = true, prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    // Other methods

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .cors()
                .and()
                .csrf()
                .disable()
                .exceptionHandling()
                .authenticationEntryPoint(this.jwtAuthenticationEntryPoint)
                .and()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                .antMatchers("/",
                        "/favicon.ico",
                        "/**/*.png",
                        "/**/*.gif",
                        "/**/*.svg",
                        "/**/*.jpg",
                        "/**/*.html",
                        "/**/*.css",
                        "/**/*.js")
                .permitAll()
                .antMatchers(HttpMethod.POST, "/api/auth/**")
                .permitAll()
                .anyRequest()
                .authenticated();

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

    }
}

如您所见,我通过以下方式获得了对 /api/auth/signup/api/auth/signin 的完全访问权限:@987654322 @

由于某种原因,当我在邮递员中尝试这些请求时,"signup" 请求运行良好,但 "signin" 不起作用并给了我 “401 未经授权”
我也试过 .antMatchers("/**").permitAll()

这是我的控制器:

@RestController
public class UserController {

    private UserService userService;

    @Autowired
    public UserController(UserService userService) {
        this.userService = userService;
    }

    @PostMapping("/api/auth/signup")
    public ResponseEntity<RestResponse> registerUser(@Valid @RequestBody SignUpRequest signUpRequest,
                                                     UriComponentsBuilder uriComponentsBuilder)  {
        RestResponse restResponse = this.userService.register(signUpRequest);
        UriComponents uriComponents = uriComponentsBuilder.path("/users").buildAndExpand();
        return ResponseEntity.created(uriComponents.toUri()).body(restResponse);
    }

    @PostMapping("/api/auth/signin")
    public ResponseEntity<JwtAuthenticationResponse> authenticateUser(@Valid @RequestBody LoginRequest loginRequest) {
        return ResponseEntity.ok(this.userService.login(loginRequest));
    }
}

【问题讨论】:

  • 您可以尝试禁用.authenticationEntryPoint(this.jwtAuthenticationEntryPoint) 行吗?通常入口点方法也会返回 401 状态。
  • 它给了我 403 禁止
  • 展示你对JwtAuthenticationFilter的实现。
  • @Ayoubk 您的配置看起来不错 - 您可以尝试删除 HttpMethod.POST 并使其 antMatchers("/api/auth/**") 仅用于测试目的。您能否确认在调用 REST 端点时从 Postman 发送了正确的 HTTP 请求类型?
  • 请将signin 请求添加到问题中。

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


【解决方案1】:

我有同样的问题,不确定,但我认为你需要这个订单:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .authorizeRequests()
            .antMatchers(HttpMethod.POST, "/api/auth/**")
            .permitAll()
            .antMatchers("/",
                    "/favicon.ico",
                    "/**/*.png",
                    "/**/*.gif",
                    "/**/*.svg",
                    "/**/*.jpg",
                    "/**/*.html",
                    "/**/*.css",
                    "/**/*.js")
            .permitAll()                   
            .anyRequest()
            .authenticated()
            .and()
            .cors()
            .and()
            .exceptionHandling()
            .authenticationEntryPoint(this.jwtAuthenticationEntryPoint)
            .and()
            .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
            .csrf()
            .disable();

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

}

【讨论】:

  • 我的问题是什么:http.authorizeRequests().antMatchers(HttpMethod.GET, "/get/**").permitAll();我仍然收到未经授权的错误。
  • 我完全按照您上面指出的那样尝试了,什么都没有,仍然给出 401 状态码。
【解决方案2】:

由于评估 antMatcher 的顺序,您的配置无法正常工作

 .and()
 .authorizeRequests()
 .antMatchers("/",
    "/favicon.ico",
    "/**/*.png",
    "/**/*.gif",
    "/**/*.svg",
    "/**/*.jpg",
    "/**/*.html",
    "/**/*.css",
    "/**/*.js")
 .permitAll()
 .antMatchers(HttpMethod.POST, "/api/auth/**")
 .permitAll()
 .anyRequest()
 .authenticated();

请求匹配规则的顺序很重要,更具体的规则应该放在第一位。 antMatcher 规则之间存在一些冲突,因此第二个规则即 .antMatchers(HttpMethod.POST, "/api/auth/")** 被忽略。

因此顺序应该如下:-

 .antMatchers(HttpMethod.POST, "/api/auth/**")
 .permitAll()
 .antMatchers("/",
    "/favicon.ico",
    "/**/*.png",
    "/**/*.gif",
    "/**/*.svg",
    "/**/*.jpg",
    "/**/*.html",
    "/**/*.css",
    "/**/*.js")
 .permitAll()

【讨论】:

    【解决方案3】:

    我记得上次做的时候顺序很重要。

    @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                    .cors()
                    .and()
                    .csrf()
                    .disable()
                    .exceptionHandling()
                    .authenticationEntryPoint(this.jwtAuthenticationEntryPoint)
                    .and()
                    .sessionManagement()
                    .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                    .and()
                    .authorizeRequests()
                    .antMatchers(HttpMethod.POST, "/api/auth/**")
                    .permitAll()
                    .antMatchers("/",
                            "/favicon.ico",
                            "/**/*.png",
                            "/**/*.gif",
                            "/**/*.svg",
                            "/**/*.jpg",
                            "/**/*.html",
                            "/**/*.css",
                            "/**/*.js")
                    .permitAll()                   
                    .anyRequest()
                    .authenticated();
    
            // Add our custom JWT security filter
            http.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
    
        }
    

    【讨论】:

      【解决方案4】:

      您需要将以下内容添加到您的配置方法中 /error 是应用程序因任何异常而发生错误时的默认回退,默认情况下是安全的。

          protected void configure(HttpSecurity httpSecurity) throws Exception {
          //disable CRSF
          httpSecurity
                  //no authentication needed for these context paths
                  .authorizeRequests()
                  .antMatchers("/error").permitAll()
                  .antMatchers("/error/**").permitAll()
                  .antMatchers("/your Urls that dosen't need security/**").permitAll()
      

      还有下面的代码sn-p

       @Override
       public void configure(WebSecurity webSecurity) throws Exception
         {
           webSecurity
          .ignoring()
              // All of Spring Security will ignore the requests
              .antMatchers("/error/**")
           }  
      

      现在,当 permitAll Urls 发生异常时,您将不会得到 401 和 500 异常以及详细信息

      【讨论】:

        【解决方案5】:

        我遇到了同样的问题,这是因为 我没有使用默认的 jdbc 架构,所以我传递了默认 UserDetailsS​​ervice 和我的权限表所需的查询是空的,所以它没有得到用户名搜索的结果。

        【讨论】:

          猜你喜欢
          • 2019-03-10
          • 2020-07-24
          • 2017-10-11
          • 2019-07-12
          • 2017-06-25
          • 1970-01-01
          • 2020-09-10
          • 2018-09-09
          • 2017-08-09
          相关资源
          最近更新 更多