加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

如何让Shiro在Scala Akka Spray环境中工作

发布时间:2020-12-16 18:54:02 所属栏目:安全 来源:网络整理
导读:我想我不能正确理解工作流程.我正在使用Apache Shiro和Stormpath在 Scala中编写Web服务.我的用户身份验证过程如下所示: 1)从POST请求中获取用户数据,使用Stormpath进行检查,如果一切正常,请重定向到某个页面: pathPrefix("api") { path("login") { post {
我想我不能正确理解工作流程.我正在使用Apache Shiro和Stormpath在 Scala中编写Web服务.我的用户身份验证过程如下所示:

1)从POST请求中获取用户数据,使用Stormpath进行检查,如果一切正常,请重定向到某个页面:

pathPrefix("api") {
  path("login") {
    post {
      AuthToken.fromRequest { (token: AuthToken) =>
        stormpathAuth(token) { subj =>
          log.info("Subj {}",subj.getPrincipal.toString)
          redirect("/some/page",StatusCodes.Found)
        }
      }
    }
  }

在日志中没关系,Shiro用Stormpath帐户给我一个正确的主题.接下来我想提取主题,在代码中使用它:

pathPrefix("some") {
  loggedInUser { subject =>
    path("page") {
      get {
        complete {
          html.render(Page.model)
        }
      }
    } ..... other routes

loggedInUser指令应该提取主题并检查它是否经过身份验证,否则重定向到登录表单.问题是它总是将我重定向到登录表单,尽管在日志中SubjectUtils.getSubject.getPrincipal显示正确的帐户.

更新

实际上Spray是建立在Akka之上的.所以我认为问题出在getSubject实现背后,目前依赖于ThreadLocal环境.我搜索了Shiro Akka主题,但没有找到任何有用的信息.

解决方法

这绝对是可能的,但您必须确保在处理消息时,主题可供Akka组件(参与者)使用.

我熟悉Akka的架构(演员/消息传递模型),但我自己没有使用Akka,所以请将以下内容作为最佳猜测答案:

在传统的基于Shiro的应用程序和/或web-apps中,某些东西负责构建反映当前调用者和/或请求的Subject实例,然后将其绑定到当前正在执行的Thread.这可确保在Thread执行到SecurityUtils.getSubject()期间的任何后续调用都能正常运行.这些都记录在Shiro’s Subject documentation中(参见Subject.Builder和Thread Association部分).

例如,在Web应用程序中,ShiroFilter每个ServletRequest执行this setup/bind/unbind logic automatically.我怀疑基于Akka的应用程序中的某些东西(某些“框架式”代码或组件)也会执行相同的setup / bind / unbind逻辑.

现在有了Akka,我相当肯定你可以使用上面文档中介绍的传统基于线程的方法(我认为Play!用户已经成功完成了这项工作).但是Akka不可变消息可能有另一个有趣的方法:

>构建消息时,您可以将特定于主题的信息附加到消息(例如消息“标题”),其中包含Shiro PrincipalCollection和身份验证状态(是否经过身份验证)和其他任何内容(runAs状态,无论如何).
>然后,当收到消息时,该信息将用作Subject.Builder的输入以创建Subject实例,并且在消息处理期间使用该Subject实例. Shiro主题实例非常轻量级,预计会根据请求创建和销毁(如果需要,甚至可以在每个请求中多次),因此您无需担心Builder开销.
>构建Subject时,您可以绑定然后将其解除绑定到当前正在执行的线程,或者,处理消息的每个Actor都可以以“框架”的方式通过相同的逻辑.后一种方法根本不需要线程绑定,因为主题状态现在维持在消息级别,而不是线程级别.

作为替代(非基于线程)方法的证明,ActiveMQ即将发布的Shiro plugin使用连接状态来存储Shiro状态,而不是线程.同样,消息状态也可以轻松使用.

请注意,使用非基于线程的方法,下游调用方无法调用SecurityUtils.getSubject()来获取Subject实例.他们必须以另一种“框架”方式获得它.

再一次,这是我最好的分析,如果没有自己使用Akka,它在消息传递环境(如Akka)中如何工作.希望这能为您提供足够的信息,帮助您以与您的用例相关的方式解决此问题!

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读