【问题标题】:Always getting 401 Error after implementing Basic Auth in Spring Security在 Spring Security 中实现基本身份验证后总是出现 401 错误
【发布时间】:2017-05-04 21:04:45
【问题描述】:

我正在尝试使用 Spring Security Annotations 实现 HTTP Basic Auth。

我有一个 REST 端点,定义如下:

@RequestMapping("/foo/")

我希望只有管理员角色的人才能访问 /foo/ 端点。

接下来,我在配置Spring Security,如下图:

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
 
    private static String REALM="MY_TEST_REALM";
     
    @Autowired
    public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().withUser("bill").password("abc123").roles("ADMIN");
        auth.inMemoryAuthentication().withUser("tom").password("abc123").roles("USER");
    }
     
    @Override
    protected void configure(HttpSecurity http) throws Exception {
  
      //http.csrf().disable()
      http  
      .authorizeRequests()
        .antMatchers("/foo/").hasRole("ADMIN")
        .and().httpBasic().realmName(REALM).authenticationEntryPoint(getBasicAuthEntryPoint())
        .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);//We don't need sessions to be created.
    }
     
    @Bean
    public CustomBasicAuthenticationEntryPoint getBasicAuthEntryPoint(){
        return new CustomBasicAuthenticationEntryPoint();
    }
     
    /* To allow Pre-flight [OPTIONS] request from browser */
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers(HttpMethod.OPTIONS, "/**");
    }
}

所以,我只希望账单用户名和密码 abc123 能够调用 REST 端点。

接下来,我定义应该返回的错误

public class CustomBasicAuthenticationEntryPoint extends BasicAuthenticationEntryPoint {
 
    @Override
    public void commence(final HttpServletRequest request, 
            final HttpServletResponse response, 
            final AuthenticationException authException) throws IOException, ServletException {
        //Authentication failed, send error response.
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        response.addHeader("WWW-Authenticate", "Basic realm=" + getRealmName() + "");
         
        PrintWriter writer = response.getWriter();
        writer.println("HTTP Status 401 : " + authException.getMessage());
    }
     
    @Override
    public void afterPropertiesSet() throws Exception {
        setRealmName("MY_TEST_REALM");
        super.afterPropertiesSet();
    }
}

我尝试使用 Postman 进行测试,我正在使用具有正确凭据的基本身份验证,但我总是收到 401 错误。我是否缺少任何步骤?

请看下面 Postman 的截图。我错过了任何标题吗?

还有,这是标题部分 (我在上面的截图中隐藏了基本 URL)

【问题讨论】:

    标签: spring spring-boot spring-security


    【解决方案1】:

    编辑

    别忘了让SecurityConfiguration 工作。

    点赞@Import({ SecurityConfiguration.class })ComponentScan("<packageName>")

    【讨论】:

    • 注释。我的问题是我将 @Import({ SecurityConfiguration.class }) 注释放在哪里(哪个 Java 类)?是 CustomBasicAuthenticationEntryPoint.java 还是 SecurityConfiguration.java 还是 Application.java?
    • 好的。我尝试了以下但没有成功 @Configuration @Import({ SecurityConfiguration.class }) public class AppConfig { }
    • 感谢您的帮助。你是对的。我在 Application.java 中添加了以下行,它现在可以工作了:ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
    • 可能是我的问题,但你能给出更详细的解决方案吗?您必须将这些注释放在哪里?
    猜你喜欢
    • 2018-12-15
    • 2018-04-18
    • 2017-12-24
    • 2012-03-24
    • 2015-04-18
    • 1970-01-01
    • 2016-07-24
    • 2011-02-11
    • 2016-03-20
    相关资源
    最近更新 更多