Session 如何为RESTful服务(Grails、Shiro)模拟会话cookie?

Session 如何为RESTful服务(Grails、Shiro)模拟会话cookie?,session,grails,cookies,session-cookies,shiro,Session,Grails,Cookies,Session Cookies,Shiro,我有一个现有的Grails应用程序,它使用灵活的插件(因此下面是ApacheShiro安全性) 我正在向它添加一个RESTful JSON API 我的login方法设法从Shiro获取会话ID并将其返回给客户端: class ApiController { def login(String username, String password) { def authToken = new UsernamePasswordToken(username, password)

我有一个现有的Grails应用程序,它使用灵活的插件(因此下面是ApacheShiro安全性)

我正在向它添加一个RESTful JSON API

我的
login
方法设法从Shiro获取会话ID并将其返回给客户端:

class ApiController {
    def login(String username, String password) {
        def authToken = new UsernamePasswordToken(username, password)
        SecurityUtils.subject.login(authToken)

        render(contentType:"text/json") {
            [
                sessionId: SecurityUtils.subject.getSession().getId()
            ]
        }
    }

    def getData() {
        SecurityUtils.subject... // either expect to already find a properly populated SecurityUtils.subject or a way to otherwise get it
    }
}
这看起来像:

{"sessionId":"61FE89F60F94A4EF7B796783E7A326BC"}
这是非常令人鼓舞的,因为这与我从浏览器中看到的在cookie中传递的相同:

Cookie:auth=Z3Vlc3Q6dGx1c2lz; m=2663:t|34e2:|47ba:t|4e99:t|6ef2:t|370d:t|3c0d:t|64b8:t|2a03:t|18c3:t|79d4:chart|640c:small|678e:3600%7C60|796a:t; OX_plg=swf|sl|wmp|shk|pm; _ga=GA1.1.441292120.1405856016; __atuvc=0%7C47%2C0%7C48%2C0%7C49%2C432%7C50%2C17%7C51; JSESSIONID=61FE89F60F94A4EF7B796783E7A326BC
但是,我现在无法完全弄清楚如何正确地从移动应用程序传递这个JSESSIONID,以便现有的Nimble/Shiro/Grails/Servlet(不确定级别)身份验证过滤器将其识别为正确的会话标识符,并将请求与会话相关联

我尝试手动传递带有
JSESSIONID=
的Cookie(在Android上使用Dispatch),但似乎没有效果(尽管我对
newValidCookie
的参数可能不完全正确):

我还尝试附加
;jsessionid=
到URL,这也没有任何作用

我还尝试了
新建Subject.Builder().sessionId(sessionId.buildSubject()
getData()
中,但是
.sessionId()
中不喜欢
字符串

到目前为止,我还没有弄清楚会话cookie的确切处理发生在哪里

如何正确地组装会话cookie,以便移动应用程序能够以与web客户端相同的方式使用该应用程序


另外,我的计划B是在每次请求时在身份验证头中传递用户名/密码,并让
ApiController
每次都执行
主题。登录
,但我更愿意使用已经用于web应用程序的会话ID来执行此操作。

似乎有一种称为自定义主题实例()

有两个步骤:

  • 创建主题(使用生成器)
  • 将主题与线程关联(有多种方法)
  • 未经测试的示例:

    Serializable sessionId = //acquired from somewhere 
    Subject subject = new Subject.Builder().sessionId(sessionId).buildSubject();
    
    ThreadState threadState = new SubjectThreadState(subject);
    threadState.bind();
    try {
        //execute work as the built Subject
    } finally {
        //ensure any state is cleaned so the thread won't be
        //corrupt in a reusable or pooled thread environment
        threadState.clear();
    }
    

    你找到什么了吗。我也面临同样的问题
    Serializable sessionId = //acquired from somewhere 
    Subject subject = new Subject.Builder().sessionId(sessionId).buildSubject();
    
    ThreadState threadState = new SubjectThreadState(subject);
    threadState.bind();
    try {
        //execute work as the built Subject
    } finally {
        //ensure any state is cleaned so the thread won't be
        //corrupt in a reusable or pooled thread environment
        threadState.clear();
    }