【问题标题】:Spring security 401 Unauthorized on unsecured endpointSpring security 401 Unauthorized 在不安全的端点上
【发布时间】:2017-04-26 10:35:21
【问题描述】:

我正在尝试在 Spring Boot 应用程序上配置 Spring Security,如下所示:

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

@Autowired
private RestAuthenticationEntryPoint unauthorizedHandler;

@Bean
public JwtAuthenticationFilter authenticationTokenFilterBean() throws Exception {
    JwtAuthenticationFilter authenticationTokenFilter = new JwtAuthenticationFilter();
    authenticationTokenFilter.setAuthenticationManager(authenticationManagerBean());
    return authenticationTokenFilter;
}

@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {

    //@formatter:off
     httpSecurity
      .csrf()
        .disable()
      .exceptionHandling()
        .authenticationEntryPoint(this.unauthorizedHandler)
        .and()
      .sessionManagement()
        .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and()
      .authorizeRequests()
        .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
        .antMatchers("/login", "/singup", "/subscribers").permitAll()
        .anyRequest().authenticated();

        // Custom JWT based security filter 
    httpSecurity            
        .addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);   

    //@formatter:on

}
}

我的未授权处理程序是:

public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint {

private static final Logger LOGGER = LoggerFactory.getLogger(RestAuthenticationEntryPoint.class);

@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
        AuthenticationException authException) throws IOException, ServletException {
    response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
}

}

最后,/subscribers 的 REST 控制器是:

@RestController
public class SubscriberRestController {

@Autowired
ISubscribersService subscribersService;

@RequestMapping(value = RequestMappingConstants.SUBSCRIBERS, method = RequestMethod.GET)
@ResponseBody
public Number subscriberCount() {

    return subscribersService.subscribersCount();
}

@RequestMapping(value = RequestMappingConstants.SUBSCRIBERS, method = RequestMethod.POST)
public String subscriberPost(@RequestBody SubscriberDocument subscriberDocument) {

    return subscribersService.subscribersInsert(subscriberDocument);
}

@RequestMapping(value = "/test", method = RequestMethod.GET)
public String test() {

    return "This is a test";
}

}

我使用邮递员测试端点,当我对“localhost:8080/subscribers”进行 POST 时,我得到:

我希望在没有任何安全控制或凭据检查的情况下打开端点(/订阅者)、用于登录和登录的端点以及用于经过身份验证的用户的安全端点。

谢谢! :)

【问题讨论】:

  • 如果我这样做,它允许我访问 /subscribers,但也允许我访问安全的 REST 端点。 @索比克
  • 这就是您通过覆盖requiresAuthentication 自己编写的内容。它现在总是会返回这个。你为什么要自己实现 JWT 支持? Spring Security 已经有一个扩展。
  • 我正在学习 Spring Security,我对 Spring Security 的了解很差。如何使用 Spring Security 默认的 JWT 支持? @M.Deinum
  • 非常感谢@dur 的帮助!日志可以找到here。我只做了 bootRun 和之后,对 /subscribers 的 POST 请求。
  • @dur 非常感谢!!!!!!!现在它正在工作。 Spring没有进行配置,因为配置包不在@ComponentScan(basePackages="...")

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


【解决方案1】:

Spring Boot 没有应用配置,因为找不到它。在 Application.java 上,配置包未包含在 @ComponentScan 注释中。

【讨论】:

  • 在默认的 Spring 应用注解中,@Configuration 应该创建配置 bean。
【解决方案2】:

经过一番研究,解决方法如下:

@SpringBootApplication(exclude = {SecurityAutoConfiguration.class })
@ComponentScan(basePackages = { PackageConstants.PACKAGE_CONTROLLERS_REST, PackageConstants.PACKAGE_SERVICES,
        PackageConstants.PACKAGE_SERVICES_IMPL, PackageConstants.PACKAGE_MONGO_REPOSITORIES,
        PackageConstants.PACKAGE_MONGO_REPOSITORIES_IMPL, PackageConstants.PACKAGE_UTILS })
public class Application {

    // Clase principal que se ejecuta en el bootrun

    public static void main(String[] args) {

        SpringApplication.run(Application.class, args);
    }
}

主线是@SpringBootApplication(exclude = {SecurityAutoConfiguration.class }),它告诉不要使用 Spring Boot Security AutoConfiguration 配置。这不是完整的答案,因为现在您必须告诉 Spring 用户您的 Spring Security 配置类。我还建议您使用 init Root Config Classes 创建 Initializer 类,使用 ApplicationConfiguration 并拒绝使用 SpringBoot 应用程序。像这样的:

应用配置:

@Configuration
@EnableWebMvc
@ComponentScan("com.trueport.*")
@PropertySource("classpath:app.properties")
public class ApplicationConfig extends WebMvcConfigurerAdapter {
    ....
}

应用安全配置:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class ApplicationSecurityConfig extends WebSecurityConfigurerAdapter {
    ....
}

初始化器:

public class Initializer implements WebApplicationInitializer {

    private static final String DISPATCHER_SERVLET_NAME = "dispatcher";

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        ....
        DispatcherServlet dispatcherServlet = new DispatcherServlet(ctx);
        dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);
        ctx.register(ApplicationConfig.class);
        ServletRegistration.Dynamic servlet =     servletContext.addServlet(DISPATCHER_SERVLET_NAME,
            dispatcherServlet);
        servlet.addMapping("/");
        servlet.setLoadOnStartup(1);
        servlet.setAsyncSupported(true);
    }
}

【讨论】:

  • 嗨@dikkini!这对我不起作用,我不明白我的错误在哪里。
  • 我有 .antMatchers("/login/**", "/signup/**", "/subscribers").anonymous() 并且我收到 401 Unauthorized on postman response to localhost:8080/subscribers @dikkini
  • 它也不起作用。也许某些自动 Spring 引导配置使其失败?
  • 完整代码可以在here找到。我非常感谢您的帮助:)
  • 这里不仅有拒绝 Spring Boot 的建议,还有针对您使用 Spring Boot 的问题的解决方案。我建议拒绝 Spring Boot,因为它添加了很多你不知道的代码,并且总是有几个解决方案: 1. 学习 Spring Boot 并深入阅读它是如何工作的。 2.不要使用Spring Boot,自己控制spring应用。
【解决方案3】:

您需要在您的配置方法中添加以下内容

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 异常以及详细信息

【讨论】:

    猜你喜欢
    • 2019-02-21
    • 2019-07-12
    • 2017-06-25
    • 1970-01-01
    • 1970-01-01
    • 2016-10-16
    • 2020-09-10
    • 2019-03-25
    • 2020-07-25
    相关资源
    最近更新 更多