【问题标题】:Custom OAuth2 /oauth/authorize Endpoint自定义 OAuth2 /oauth/authorize 端点
【发布时间】:2015-03-20 06:19:18
【问题描述】:

我正在努力让我的 RESTful 后端完全不了解 HTML。我希望它只与我的 HTML/CSS/JS 前端和其他连接客户端说 JSON。 OAuth2 提供AuthorizationEndpoint 服务/oauth/authorize。在其默认行为中,用户批准页面旨在成为 ModelAndView 生成的 HTML 结果。

我宁愿我的 HTML/CSS/JS 前端处理确认页面的显示(可能还有登录),然后将用户的批准发布到 /oauth/authorize。 POST /oauth/authorize 的结果将是一个 JSON 结果,其中包含令牌和要重定向到的 URL。然后前端代码将处理浏览器重定向回客户端。其余过程将照常进行。

我想错了吗?是否有任何我可能没有考虑到的安全问题?

谢谢!

【问题讨论】:

  • 在实现这一点时,我发现我复制了很多 AuthorizationEndpoint 代码。虽然我很想继承AuthorizationEndpoint 类,但看起来AuthorizationServerEndpointsConfigurer 硬编码了对AuthorizationEndpoint 的引用。能够连接到 authorizationEndpoint() 并更改创建的类将使这项工作变得更加容易。有没有我看不到的机制?
  • 似乎完成这样简单的任务的最短路径是要求AuthorizationServerEndpointsConfigurer 提供AuthorizationEndpoint。通过这种方式,我可以提供自己的实现,并且仍然可以连接到所有现有的机器。现在我正处于复制/粘贴的世界中。
  • 鉴于我还不能提供 AuthorizationEndpoint 替换 AuthorizationServerEndpointsConfigurer,我只想将配置的对象(TokenGranter、ClientDetailsS​​ervice、AuthorizationCodeServices、OAuth2RequestFactory、OAuth2RequestValidator 和 UserApprovalHandler)公开为 bean .如果我可以将它们作为 bean 公开,那么我可以允许框架将 @Autowire 它们放入我的替换 AuthorizationEndpoint。对此有什么想法吗?

标签: spring-security-oauth2


【解决方案1】:

我认为你走错了方向。 LoginApproval页面必须由授权服务器提供并使用HTTP标准(例如:使用Location头重定向)。

如果你想DIY任何东西,推荐授权类型是Resource Owner Password。但它可能不适合纯粹的客户端 Web 应用程序。因为它不能(或很难)保证secret key 的安全!

我也有一个类似于你的应用程序,用 AngularJS 编写并使用implicit 流。我的应用程序完全使用 RESTful 与服务器通信。除了登录/授权应用程序外,它由不同域的另一个 Web 应用程序(Spring MVC - 默认为 Sparkl)完成。

【讨论】:

  • 为什么必须由认证服务器提供呢?我没有在规范中读到它,这似乎是我美丽的 REST/JSON 服务器的变态。一旦我确保它按预期工作,我将发布我为此提出的解决方案。但它使用 pathMapping() 将“oauth/confirm_access”更改为“redirect:(url)”。我认为这毕竟是我一直在寻找的解决方案。
  • 因为只有trusted client可以接受用户的凭证并用它来换取access token。没有client_secret,你如何证明你的应用是可信的?
【解决方案2】:

是的,我遇到了类似的问题,我在客户端回发页面上进行身份验证,然后我才将用户踢到 SPA - 所以因为用户已经经过身份验证,我只想要一种转换他们的 cookie 的方法成令牌。我最终写了这样的东西,它基本上绕过了大多数 oauth 的东西。我的想法是,只有当用户在请求中有一个有效的 .NET auth cookie 时它才会起作用,所以它必须至少和那个一样安全,对吧?

    [AllowAnonymous]
    public ActionResult GetToken()
    {
        if (!User.Identity.IsAuthenticated)
        {
            Response.StatusCode = 403;
            return Json(new {message = "Forbidden - user not logged in."}, JsonRequestBehavior.AllowGet);
        }

        var claims = new ClaimsPrincipal(User).Claims.ToArray();
        var identity = new ClaimsIdentity(claims, "Bearer");
        AuthenticationManager.SignIn(identity);
        var ticket = new AuthenticationTicket(identity, new AuthenticationProperties());
        var token = Startup.OAuthOptions.AccessTokenFormat.Protect(ticket);
        return Json(new { token }, JsonRequestBehavior.AllowGet);
    }

【讨论】:

    猜你喜欢
    • 2015-06-03
    • 2017-05-16
    • 1970-01-01
    • 2021-09-06
    • 2011-08-09
    • 2015-08-26
    • 2018-02-08
    • 1970-01-01
    • 2014-03-08
    相关资源
    最近更新 更多