繁体   English   中英

Spring 安全在 memory 身份验证不起作用

[英]Spring Security In memory authentication not working

我正在尝试使用具有预定义用户 ID 和密码的 spring 安全性来实现 memory 身份验证。 我正在使用基本的 HTTP 身份验证并将用户 ID 和密码组合作为 Header 以“userId:password”的形式发送(为简单起见,我忽略了上述标头的编码)。

下面是我正在尝试实施 spring 安全性的 rest 端点之一。

@RequestMapping(value = "/course", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
 public ResponseEntity<ApiResponse> addCourse(@RequestBody Course course) {
   return new ResponseEntity<ApiResponse>(new ApiResponse(HttpStatus.OK.value(), null), HttpStatus.OK);
 }

下面是 junit 测试,我正在使用它来验证 spring 安全配置

@Test
  public void testAddCourse() throws Exception {
    String inputJsonRequest = JacksonMapperUtil.convertObjectToJsonString(course);
    mockMvc.perform(MockMvcRequestBuilders.post("/course")
        .contentType(MediaType.APPLICATION_JSON)
        .content(inputJsonRequest)
        .header("jane_doe", "admin_password"))
        .andExpect(MockMvcResultMatchers.status().isOk())
        .andExpect(MockMvcResultMatchers.jsonPath("$.statusCode").value(HttpStatus.OK.value()));
  }

下面是我配置的网络安全配置文件。

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

  @Override
  protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication()
        .withUser("john_doe")
        .password("student_password")
        .authorities("ROLE_STUDENT_USER")
        .and()
        .withUser("jane_doe")
        .password("admin_password")
        .authorities("ROLE_OFFICE_ADMIN");
  }

  @Autowired
  public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication()
        .withUser("john_doe")
        .password("student_password")
        .authorities("ROLE_STUDENT_USER")
        .and()
        .withUser("jane_doe")
        .password("admin_password")
        .authorities("ROLE_OFFICE_ADMIN");
  }

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.httpBasic()
        .and()
        .authorizeRequests()
        .antMatchers(HttpMethod.POST, "/course")
        .hasAuthority("ROLE_OFFICE_ADMIN")
        .antMatchers(HttpMethod.POST, "/student")
        .hasAnyAuthority("ROLE_OFFICE_ADMIN", "ROLE_STUDENT_USER")
        .antMatchers(HttpMethod.GET, "/**")
        .permitAll()
        .anyRequest()
        .authenticated()
        .and()
        .exceptionHandling()
        .accessDeniedHandler(accessDeniedHandler())
        .authenticationEntryPoint(authenticationEntryPoint());
  }

  @Bean
  RestAccessDeniedHandler accessDeniedHandler() {
    return new RestAccessDeniedHandler();
  }

  @Bean
  RestAuthenticationEntryPoint authenticationEntryPoint() {
    return new RestAuthenticationEntryPoint();
  }
}

AuthenticationEntryPoint 实现 class

@Component
public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint {

  @Override
  public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e)
      throws IOException, ServletException {
    ApiResponse response = new ApiResponse(HttpStatus.UNAUTHORIZED.value(),
        "Authentication Failure-The user name and password combination is incorrect");
    OutputStream out = httpServletResponse.getOutputStream();
    ObjectMapper mapper = new ObjectMapper();
    mapper.writeValue(out, response);
    out.flush();
  }

AccessDenied Handler 实现 class


@Component
public class RestAccessDeniedHandler implements AccessDeniedHandler {
  @Override
  public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e)
      throws IOException, ServletException {
    ApiResponse apiResponse = new ApiResponse(HttpStatus.FORBIDDEN.value(),
        "Authorization Failure-This user does not have the sufficient level of access");
    OutputStream out = httpServletResponse.getOutputStream();
    ObjectMapper mapper = new ObjectMapper();
    mapper.writeValue(out, apiResponse);
    out.flush();
  }

使用的 maven 依赖项:

Spring 启动版本 - 2.2.1.RELEASE

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
            <version>2.2.1.RELEASE</version>
        </dependency>

我注意到的上述配置的问题是,传入请求的身份验证未完成,即使请求包含正确/正确的 userId:password header 值。 有人能指出我做错了什么吗?

您应该提供一个密码编码器,或者定义 bean 之类的;

@Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

或在密码前输入 {noop},如下所示

.withUser("john_doe")
        .password("{noop}student_password")

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM