Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/390.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 401而不是403,带弹簧护套2_Java_Spring_Spring Boot_Spring Security_Http Status Code 401 - Fatal编程技术网

Java 401而不是403,带弹簧护套2

Java 401而不是403,带弹簧护套2,java,spring,spring-boot,spring-security,http-status-code-401,Java,Spring,Spring Boot,Spring Security,Http Status Code 401,对于1.5.6.RELEASE,我可以通过以下方式发送HTTP状态代码401,而不是403,如中所述: public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { //... http.exceptionHandling()

对于1.5.6.RELEASE,我可以通过以下方式发送HTTP状态代码
401
,而不是
403
,如中所述:

public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //...
        http.exceptionHandling()
                .authenticationEntryPoint(new Http401AuthenticationEntryPoint("myHeader"));
        //...
    }
}
使用
org.springframework.boot.autoconfigure.security.Http401AuthenticationEntryPoint

我刚刚升级到,发现不再有这样的类(至少在那个包中)

问题:

  • 这个类(
    Http401AuthenticationEntryPoint
    )在Spring Boot中是否存在

  • 如果没有,那么在现有项目中保持相同的行为以保持与依赖此状态代码(
    401
    )而不是
    403
    )的其他实现的一致性,有什么好的替代方法

抬起头 默认情况下
Spring Boot starter security
被添加为依赖项并执行未经授权的请求时,Spring Boot 2将返回
401

如果放置一些自定义配置以修改安全机制行为,则可能会发生更改。如果是这种情况,并且你确实需要强制执行
401
状态,那么请阅读下面的原始帖子

原职 类
org.springframework.boot.autoconfigure.security.Http401AuthenticationEntryPoint
被删除,取而代之的是
org.springframework.security.web.authentication.HttpStatusEntryPoint

在我的例子中,代码如下所示:

public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //...
        http.exceptionHandling()
            .authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED));
        //...
    }
}
@Configuration
public class MyConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public Http401AuthenticationEntryPoint securityException401EntryPoint() {
      return new Http401AuthenticationEntryPoint("Bearer realm=\"webrealm\"");
    }

    @Autowired
    private Http401AuthenticationEntryPoint authEntrypoint;

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

      // some http configuration ...

      // Spring Boot 1.5.x style
      http.exceptionHandling().authenticationEntryPoint(authEntrypoint);
    }
//...
}
@Configuration
public class MyConfig extends WebSecurityConfigurerAdapter {

    //Bean configuration for Http401AuthenticationEntryPoint can be removed

    //Autowiring also removed

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

      // some http configuration ...

      // Spring Boot 2 style
      http.exceptionHandling().authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED));
    }
//...
}
奖金

如果您需要在响应正文中返回一些信息或以某种方式自定义响应,您可以执行以下操作:

public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //...
        http.exceptionHandling()
            .authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED));
        //...
    }
}
@Configuration
public class MyConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public Http401AuthenticationEntryPoint securityException401EntryPoint() {
      return new Http401AuthenticationEntryPoint("Bearer realm=\"webrealm\"");
    }

    @Autowired
    private Http401AuthenticationEntryPoint authEntrypoint;

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

      // some http configuration ...

      // Spring Boot 1.5.x style
      http.exceptionHandling().authenticationEntryPoint(authEntrypoint);
    }
//...
}
@Configuration
public class MyConfig extends WebSecurityConfigurerAdapter {

    //Bean configuration for Http401AuthenticationEntryPoint can be removed

    //Autowiring also removed

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

      // some http configuration ...

      // Spring Boot 2 style
      http.exceptionHandling().authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED));
    }
//...
}
1-扩展
AuthenticationEntryPoint

public class MyEntryPoint implements AuthenticationEntryPoint {
    private final HttpStatus httpStatus;
    private final Object responseBody;

    public MyEntryPoint(HttpStatus httpStatus, Object responseBody) {
        Assert.notNull(httpStatus, "httpStatus cannot be null");
        Assert.notNull(responseBody, "responseBody cannot be null");
        this.httpStatus = httpStatus;
        this.responseBody = responseBody;
    }

    @Override
    public final void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException {
        response.setStatus(httpStatus.value());

        try (PrintWriter writer = response.getWriter()) {
            writer.print(new ObjectMapper().writeValueAsString(responseBody));
        }
    }
}
2-向安全配置提供MyEntryPoint的实例

public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // customize your response body as needed
        Map<String, String> responseBody = new HashMap<>();
        responseBody.put("error", "unauthorized");

        //...
        http.exceptionHandling()
            .authenticationEntryPoint(new MyEntryPoint(HttpStatus.UNAUTHORIZED, responseBody));
        //...
    }
}
公共类SecurityConfig扩展了WebSecurity配置适配器{
@凌驾
受保护的无效配置(HttpSecurity http)引发异常{
//根据需要定制您的响应主体
Map responseBody=newhashmap();
responseBody.put(“错误”、“未经授权”);
//...
http.exceptionHandling()
.authenticationEntryPoint(新的MyEntryPoint(HttpStatus.UNAUTHORIZED,responseBy));
//...
}
}
已删除

请参阅Spring Boot Github Repo>问题(删除Http401AuthenticationEntryPoint):

删除Http401AuthenticationEntryPoint

rwinch于2017年10月20日发表评论
据我所知,Spring引导代码库中没有使用它,因此最好删除
Http401AuthenticationEntryPoint

根据您的要求,您可以使用:


请详细说明@Lealcelderio的答案:

在Spring Boot 2之前,我的安全配置类如下所示:

public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //...
        http.exceptionHandling()
            .authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED));
        //...
    }
}
@Configuration
public class MyConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public Http401AuthenticationEntryPoint securityException401EntryPoint() {
      return new Http401AuthenticationEntryPoint("Bearer realm=\"webrealm\"");
    }

    @Autowired
    private Http401AuthenticationEntryPoint authEntrypoint;

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

      // some http configuration ...

      // Spring Boot 1.5.x style
      http.exceptionHandling().authenticationEntryPoint(authEntrypoint);
    }
//...
}
@Configuration
public class MyConfig extends WebSecurityConfigurerAdapter {

    //Bean configuration for Http401AuthenticationEntryPoint can be removed

    //Autowiring also removed

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

      // some http configuration ...

      // Spring Boot 2 style
      http.exceptionHandling().authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED));
    }
//...
}
现在在Spring Boot 2中,它看起来是这样的:

public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //...
        http.exceptionHandling()
            .authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED));
        //...
    }
}
@Configuration
public class MyConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public Http401AuthenticationEntryPoint securityException401EntryPoint() {
      return new Http401AuthenticationEntryPoint("Bearer realm=\"webrealm\"");
    }

    @Autowired
    private Http401AuthenticationEntryPoint authEntrypoint;

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

      // some http configuration ...

      // Spring Boot 1.5.x style
      http.exceptionHandling().authenticationEntryPoint(authEntrypoint);
    }
//...
}
@Configuration
public class MyConfig extends WebSecurityConfigurerAdapter {

    //Bean configuration for Http401AuthenticationEntryPoint can be removed

    //Autowiring also removed

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

      // some http configuration ...

      // Spring Boot 2 style
      http.exceptionHandling().authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED));
    }
//...
}

在Spring Boot Github Repo>PR Remove Http401AuthenticationEntryPoint中也可以看到这一点。

您可以通过重写类AuthenticationEntryPoint来自定义逻辑 这应该是有效的:

@Component public class AuthEntryPointException implements AuthenticationEntryPoint, Serializable {

    private static final long serialVersionUID = -8970718410437077606L;

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response,
        AuthenticationException authException) throws IOException {
        response.setStatus(HttpStatus.SC_UNAUTHORIZED);
        response.setContentType("application/json");
        response.getWriter().write("{\"result\":\"UNAUTHORIZED\",\"message\":\"UNAUTHORIZED or Invalid Token\"}");
    }
}

现在,坏凭证请求返回401,但返回空正文响应。另外,未经授权的请求(应该返回403)也返回401,返回的是空正文响应。这返回401,没有正文。这对js来说很好,但在Firefox中查看时,它是一个空白页面,在Chrome中查看时,它会显示“此页面不工作”。不过,您可以轻松地自行替换HTP401 AuthenticationEntryPoint并使用它。只需实现AuthenticationEntryPoint并设置您想要的任何状态和消息。@非常感谢您指出这一点!根据你的评论,我只是提出了一个其他人可能会遵循的方法:)谢谢,来自SpringBootGitRepo的非常有用的链接。在我提供给未来读者的答案中,他们可以看到我是如何根据自己的要求使用
HttpStatusEntryPoint
的。解决方案看起来很好,很干净,但它缺少必需的
WWW-Authenticate
标题,该标题将告诉客户如何尝试进行身份验证