结合使用httpBasic和AuthenticationEntryPoint

时间:2019-01-10 05:56:07

标签: java spring-boot authentication spring-security

我正在遵循this tutorial并结合使用JWT身份验证和Spring Boot。如本教程所示,我可以从邮递员登录并访问api。但是,当我尝试通过浏览器在localhost:8080进行相同操作时,出现401未经授权错误。

本教程中使用的configure方法是

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.cors().and().csrf().disable()
      .authorizeRequests().antMatchers("/api/auth/**").permitAll().anyRequest()
      .authenticated().and().exceptionHandling()
      .authenticationEntryPoint(unauthorizedHandler).and()
      .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

    http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
}

当我删除authenticationEntryPoint并添加httpbasic时,访问localhost:8080时,浏览器中会显示登录对话框。

@Override
protected void configure(HttpSecurity http) throws Exception { 
    http.cors().and().csrf().disable()
      .authorizeRequests().antMatchers("/api/auth/**").permitAll().anyRequest()
      .authenticated().and().exceptionHandling()
      .and().httpBasic().and().sessionManagement()
      .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}

但是当我尝试添加带有authenticationEntryPoint的httpBasic时,没有显示登录对话框。

@Override
protected void configure(HttpSecurity http) throws Exception {
      http.cors().and().csrf().disable()
        .authorizeRequests().antMatchers("/api/auth/**").permitAll().anyRequest()
        .authenticated().and().exceptionHandling()
        .authenticationEntryPoint(unauthorizedHandler)
        .and().httpBasic().and().sessionManagement()
        .sessionCreationPolicy(SessionCreationPolicy.STATELESS);

  http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
}

已更新

unauthorizedHandler是AuthenticationEntryPoint的实现。

@Component
public class UnauthorizedHandler implements AuthenticationEntryPoint {

    private static final Logger logger = LoggerFactory.getLogger(UnauthorizedHandler.class);

    @Override
    public void commence(HttpServletRequest request,
                     HttpServletResponse response,
                     AuthenticationException e) 
                             throws IOException, ServletException {

        logger.error("Unauthorized error. Message - {}", e.getMessage());
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Error -> Unauthorized");
}

}

使用AuthenticationEntryPoint时如何显示登录对话框?

2 个答案:

答案 0 :(得分:1)

这有点旧,但我希望我的回答对某人有所帮助。

我遇到了完全相同的问题,因为我试图为 swagger 获取身份验证对话框,但我想在不显示对话框的情况下处理未经授权的请求,所以我所做的是:

@Component
public class AuthEntryPointJwt implements AuthenticationEntryPoint {

    private static final Logger logger = LoggerFactory.getLogger(AuthEntryPointJwt.class);

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response,
                         AuthenticationException authException) throws IOException {
        // Requested URL contains "swagger" since it is the only page where I wanted to display login dialog when set header to display dialog and send back the response
        if (request.getRequestURL().toString().contains("swagger")) {
            response.setHeader("WWW-Authenticate", "BASIC");
            response.sendError(response.SC_UNAUTHORIZED);
        } else {
            // if not, just send unauthorized error
            logger.error("Unauthorized error: {}", authException.getMessage());
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Error: Unauthorized");
        }

    }
}

答案 1 :(得分:0)

默认情况下,启用// Declaration Data model var sections = [Date]() var datas = [Date:[String]]() // Some test values to show how the processing could be let date = Date() let value = "Test" // This would be inside your processing loop // Check, if section already exists if !sections.contains(date) { // Add date to sections array sections.append(date) // Insert empty array in datas dictionary datas[date] = [String]() } // Add value to array datas[date]?.append(value) // This could be inside cellForRowAtIndexPath // Fetch value let indexPath = IndexPath(row: 0, section: 0) let value2 = datas[sections[indexPath.section]]?[indexPath.row] 并使用默认入口点exceptionHandling设置Http403ForbiddenEntryPoint时,它会在httpBasic()中设置新的默认入口点{{ 1}}-当定义了非显式入口点时,这一切都是关于默认值的。

当您明确定义新的入口点exceptionHandling时,将不再使用所有默认配置,而将使用BasicAuthenticationEntryPoint

请注意,.exceptionHandling().authenticationEntryPoint(some entry point)仍在工作,但是它应该以某种方式告诉您的浏览器身份验证失败,并告诉浏览器向用户询问http basic的凭据,这是some entry point在做什么设置appropriate header WWW-Authenticate: Basic realm="User Visible Realm"

在您的httpBasic的{​​{1}}中,添加行BasicAuthenticationEntryPointUnauthorizedHandler

PS。我尚未分析您的情况,只是告诉您出了什么问题(为什么不按预期工作)以及如何使其起作用-因此从安全角度来看,此解决方案可能不好。