在Spring Security中实现Basic Auth后总是出现401错误

Sai*_*Sai 8 spring spring-security spring-boot

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

\n\n

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

\n\n
@RequestMapping("/foo/")\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n

接下来,我正在配置Spring Security,如下所示:

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

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

\n\n

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

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

我尝试使用 Postman 进行测试,我使用具有正确凭据的基本身份验证,但总是收到 401 错误。我错过了什么步骤吗?

\n\n

请参阅下面来自 Postman 的屏幕截图。我是否缺少任何标头?\n在此输入图像描述

\n\n

这是标题部分\n在此输入图像描述\n(我在上面的屏幕截图中隐藏了基本 URL)

\n

cha*_*luo 2

编辑

别忘了做作业SecurityConfiguration

喜欢@Import({ SecurityConfiguration.class })ComponentScan("<packageName>")