【问题标题】:How to get a header value in a RestController and pass it to the parent controller如何在 RestController 中获取标头值并将其传递给父控制器
【发布时间】:2020-09-21 14:55:21
【问题描述】:

我是 spring-boot 新手,对 web 服务很陌生。

我想在(抽象的)通用 RestController 中实现一个授权过程,它应该获取基本身份验证的内容。来自扩展控制器的标头,然后执行授权。

类似的东西:

public class GenericController
{
  // Constructor 
  protected GenericController(String basicAuth) throws MalformedURLException, ProtocolException, IOException
  {
    // check user can execute action
  }
}


@RestController
@RequestMapping( "/users" )
public class UserController extends GenericController
{
  private static final Logger logger = LoggerFactory.getLogger(UserController.class);
  
  // Constructor
  protected UserController() throws MalformedURLException, ProtocolException, IOException
  {
    // somehow get the basic auth information from header and pass it to the parent's constructor
    basicAuth = ???
    
    super(basicAuth);
  }

  @GetMapping( "/user/{cn}" )
  public String getUser( @PathVariable String cn )
  {
    logger.error("Start getUser(...): cn=" + cn);

  }

我该怎么做? (这可能吗?)

补充信息: 我的网络服务本身就是其他网络服务的消费者。

一旦调用用户被授权“使用”我的网络服务,我必须将基本身份验证转发/设置到我调用的网络服务的请求中。

那么,当我的服务被调用时,我如何/在哪里“拦截”并获取标头?

【问题讨论】:

  • 在您构造Controller 时,您不在请求上下文中。没有要获取的标头(除非您在每个请求上都创建一个新实例,而您当前的注释设置并非如此,并且通常是一个可怕的想法)。您究竟想用这些信息做什么,为什么它必须在施工时而不是在请求到来时发生?

标签: java spring-boot web-services


【解决方案1】:

我建议看一下Spring Security 框架。有很多教程展示了如何配置它以执行基本身份验证,例如:here

主要思想是将身份验证/授权问题与控制器和业务逻辑代码分离。为了实现此过滤器,使用拦截每个请求并针对不同条件对其进行验证。在实现无状态 REST 服务(每个请求独立于其他请求)时,这并不难。在处理会话时,逻辑会变得更加复杂。 Spring Security 实现了过滤器链,由多个过滤器组成,每个过滤器执行自己的检查。

Spring Security 经常在基于 Spring 的项目中使用,绝对值得一看,尽管第一次接触它可能看起来有点困难。

【讨论】:

    【解决方案2】:

    您可以使用 HttpServletRequest 从请求中获取标头。

     protected UserController(HttpServletRequest httpServletRequest) throws MalformedURLException, ProtocolException, IOException
        {
    
            System.out.println( httpServletRequest.getHeaders("key name"));
            // somehow get the basic auth information from header and pass it to the parent's constructor
            basicAuth = ???
    
            super(basicAuth);
        }
    

    【讨论】:

    • 我收到错误:错误...创建文件中定义的名称为“userController”的 bean [...] 时出错:通过构造函数进行 Bean 实例化失败;...未找到线程绑定请求:您是指实际 Web 请求之外的请求属性,还是在原始接收线程之外处理请求?如果您实际上是在 Web 请求中操作并且仍然收到此消息,则您的代码可能在 DispatcherServlet 之外运行:在这种情况下,请使用 RequestContextListener 或 RequestContextFilter 来公开当前请求。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-22
    • 1970-01-01
    • 2012-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多