Mat*_*ati 19 java spring spring-security spring-boot
我在Spring安全性中的默认行为存在问题,并且Java Config提供了授权请求.
http
....
.authorizeRequests()
.antMatchers("/api/test/secured/*").authenticated()
Run Code Online (Sandbox Code Playgroud)
当我在/api/test/secured/user没有登录(使用匿名用户)的情况下进行呼叫时,它返回403 Forbidden.当匿名用户想要获得安全保护authenticated()或@PreAuthorize资源时,是否有一种简单的方法可以将状态更改为401 Unauthorized ?
le0*_*iaz 15
有了spring security 4.x,已经有了一个类
org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint
Run Code Online (Sandbox Code Playgroud)
Spring boot还包括一个
org.springframework.boot.autoconfigure.security.Http401AuthenticationEntryPoint
Run Code Online (Sandbox Code Playgroud)
并且它们需要开发人员使用符合规范的401响应的两个好处要求必须设置头WWW-Authenticate,示例401响应可以是:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="example",
error="invalid_token",
error_description="The access token expired"
Run Code Online (Sandbox Code Playgroud)
因此,在您的安全配置中,您可以定义并自动装配类的bean
所以例如使用spring boot app:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
@Bean
public Http401AuthenticationEntryPoint securityException401EntryPoint(){
return new Http401AuthenticationEntryPoint("Bearer realm=\"webrealm\"");
}
...
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/login").anonymous()
.antMatchers("/").anonymous()
.antMatchers("/api/**").authenticated()
.and()
.csrf()
.disable()
.headers()
.frameOptions().disable()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.logout()
.permitAll()
.exceptionHandling().authenticationEntryPoint(securityException401EntryPoint());
}
Run Code Online (Sandbox Code Playgroud)
相关的是:
.exceptionHandling().authenticationEntryPoint(securityException401EntryPoint());
Run Code Online (Sandbox Code Playgroud)
Mei*_*orn 13
我在这里有解决方案:
http
.authenticationEntryPoint(authenticationEntryPoint)
Run Code Online (Sandbox Code Playgroud)
AuthenticationEntryPoint源代码:
@Component
public class Http401UnauthorizedEntryPoint implements AuthenticationEntryPoint {
private final Logger log = LoggerFactory.getLogger(Http401UnauthorizedEntryPoint.class);
/**
* Always returns a 401 error code to the client.
*/
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException arg2) throws IOException,
ServletException {
log.debug("Pre-authenticated entry point called. Rejecting access");
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Access Denied");
}
}
Run Code Online (Sandbox Code Playgroud)
Tai*_*ong 10
从Spring Boot 2开始,类Http401AuthenticationEntryPoint已被删除(参见Spring Boot Issue 10725).
而不是Http401AuthenticationEntryPoint使用带HttpStatus.UNAUTHORIZED的HttpStatusEntryPoint:
http.exceptionHandling()
.authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED));
Run Code Online (Sandbox Code Playgroud)
Spring Boot 2 中使用 lambda 表达式的简单方法:
@Override
public void configure(HttpSecurity http) throws Exception {
http.
...
.exceptionHandling()
.authenticationEntryPoint((request, response, e) -> {
response.setStatus(HttpStatus.UNAUTHORIZED.value());
response.setContentType("application/json");
response.getWriter().write("{ \"error\": \"You are not authenticated.\" }");
})
...
}
Run Code Online (Sandbox Code Playgroud)
您需要AuthenticationEntryPoint根据异常情况进行扩展以进行定制。
@ControllerAdvice
public class MyAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException)
throws IOException, ServletException {
// 401
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Authentication Failed");
}
@ExceptionHandler (value = {AccessDeniedException.class})
public void commence(HttpServletRequest request, HttpServletResponse response,
AccessDeniedException accessDeniedException) throws IOException {
// 401
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Authorization Failed : " + accessDeniedException.getMessage());
}
}
Run Code Online (Sandbox Code Playgroud)
在您的 SecurityConfig 中指定上述自定义 AuthenticationEntryPoint,如下所示:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity (prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.exceptionHandling()
.authenticationEntryPoint(new MyAuthenticationEntryPoint());
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11169 次 |
| 最近记录: |