Java 401而不是403,带弹簧护套2
对于1.5.6.RELEASE,我可以通过以下方式发送HTTP状态代码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()
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
类
我刚刚升级到,发现不再有这样的类(至少在那个包中)
问题:
- 这个类(
)在Spring Boot中是否存在Http401AuthenticationEntryPoint
- 如果没有,那么在现有项目中保持相同的行为以保持与依赖此状态代码(
)而不是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
根据您的要求,您可以使用:
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
标题,该标题将告诉客户如何尝试进行身份验证