如何在春季启动中从未经授权的响应中删除变量

Posted

技术标签:

【中文标题】如何在春季启动中从未经授权的响应中删除变量【英文标题】:How to remove a variable from Unauthorized response in springboot 【发布时间】:2021-06-15 16:16:34 【问题描述】:

在检查用户未授权时,我有此响应。

我有没有可能从未经授权的响应中删除路径?因为它没有为用户提供有价值的信息


"timestamp": "2021-03-18T09:16:09.699+0000",
"status": 401,
"error": "Unauthorized",
"message": "Unauthorized",
"path": "/test/v1/api/test.com/config/settings"

这就是我的配置的样子

public class ResourceConfig extends ResourceServerConfigurerAdapter 


@Override
public void configure(HttpSecurity httpSecurity) throws Exception 
    httpSecurity
        .csrf().disable()
        .cors();

    httpSecurity
        .anonymous().disable()
        .requestMatchers().antMatchers("/api/**")
        .and()
        .authorizeRequests()
        .antMatchers("/api/**")
        .authenticated()
        .and()
        .exceptionHandling()
        .accessDeniedHandler(new OAuth2AccessDeniedHandler());


【问题讨论】:

您可以覆盖默认的身份验证入口点。 ***.com/questions/66630963/… 我建议创建具有所需属性的通用响应 bean 类并关注 ***.com/a/52661992/5404976 【参考方案1】:

在@linhx 使用自定义AuthenricationEntryPoint 的想法的基础上,您可以使用HandlerExceptionResolver 解析为页面

您可以得到不同方法的详细比较here。

@Component
public class ABAuthenticationEntryPoint implements AuthenticationEntryPoint 

    protected final Logger logger = LoggerFactory.getLogger(ABAuthenticationEntryPoint.class);

    private final String realmName = "CustomRealm";

     @Autowired
     @Qualifier("handlerExceptionResolver")
     private HandlerExceptionResolver resolver;
     
    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException 
        resolver.resolveException(request, response, null, authException);
    

HandlerExceptionResolver 使用处理程序 (HandlerMethod) 获取 Controller 类并扫描它以查找带有 @ExceptionHandler 注释的方法。如果其中一种方法与异常(ex)匹配,则调用此方法以处理异常。 (否则返回 null 表示此异常解析器认为没有责任)。

所以,用@ControllerAdvice添加一个类:

@ExceptionHandler(value = InsufficientAuthenticationException.class)
public ResponseEntity<Object> handleInsufficientAuthenticationException(InsufficientAuthenticationException ex) 
    String methodName = "handleInsufficientAuthenticationException()";
    return buildResponseEntity(HttpStatus.UNAUTHORIZED, null, null, ex.getMessage(), null);


private ResponseEntity<Object> buildResponseEntity(HttpStatus status, HttpHeaders headers, Integer internalCode, String message, List<Object> errors) 
        ResponseBase response = new ResponseBase()
                .success(false)
                .message(message)
                .resultCode(internalCode != null ? internalCode : status.value())
                .errors(errors != null
                        ? errors.stream().filter(Objects::nonNull).map(Objects::toString).collect(Collectors.toList())
                        : null);
        
        return new ResponseEntity<>((Object) response, headers, status);
    

SecurityConfig类:

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter 
protected final Logger logger = LoggerFactory.getLogger(SecurityConfig.class);
    
    @Autowired
    private ABAuthenticationEntryPoint authenticationEntryPoint;
    
    @Override
    protected void configure(HttpSecurity http) throws Exception 
        http.
        .....
        .and()
        .exceptionHandling().authenticationEntryPoint(authenticationEntryPoint); //AuthenticationEntryPoint has to be the last
    

根据你buildResponseEntity的方式,最后你会得到类似下面的东西


    "success": false,
    "resultCode": 401,
    "message": "Full authentication is required to access this resource"

【讨论】:

ResponseBase 和 .resolveException( 未定义 ResponseBase 是我用作通用响应 obj 的类。如果它就是这样:public class ResponseBase private Boolean success; private Integer resultCode; private String message = null; private List&lt;String&gt; errors; private String transactionId; 我有最后一个问题,如何在响应中添加时间戳 为什么错误是空的?我该如何设置它们? 在响应 obj 中添加一个字段并将其映射到 @ControllerAdvice 中就足够了。比如上面的代码,你只是在buildResponseEntity方法中添加...new ResponseBase() .success(false).timestamp(OffsetDateTime.now(ZoneOffset.UTC))....,希望你使用java >= 8

以上是关于如何在春季启动中从未经授权的响应中删除变量的主要内容,如果未能解决你的问题,请参考以下文章

如何在春季授权服务器中允许端点?

如何在 Ocelot 和 .Net WebApi 中覆盖 AuthorizationMiddleware 时返回未经授权的响应

如何在 Spring WebFlux 上自定义未经授权的响应

如何在邮递员中从环境变量设置基本授权?

如何在 Lumen 中使用身份验证进行用户登录?为啥我在启动时看到“未经授权”?

删除和选项请求获得 401 未授权响应