How to simulate session cookies for RESTful service (Grails, Shiro)?

I have an existing Grails application that uses the Nimble plugin (hence the Apache Shiro protection at the bottom).

I am adding RESTful JSON API to it.

My method login

allows me to get the session id from Shiro and return it to the client:

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
    }
}

      

It looks like this:

{"sessionId":"61FE89F60F94A4EF7B796783E7A326BC"}

      

This is quite reassuring, since this is the same thing I see being passed in the cookie when from the browser:

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

      

However, now I cannot figure out how to properly pass this JSESSIONID from the mobile app in such a way that the existing Nimble / Shiro / Grails / Servlet authentication filters (not sure which level) recognize it as the correct session ID and associate the request with the session.

I tried to manually pass the Cookie using JSESSIONID=<sessionId>

(using Dispatch on Android), but it doesn't seem to have an effect (although maybe my parameters for newValidCookie

not all are correct):

val cookie = com.ning.http.client.cookie.Cookie.newValidCookie("JSESSIONID", token, null, token, null, -1, -1, false, false)
val svc = host / "api" / "getData" addCookie cookie
Http(svc OK as.String) 

      

I also tried adding ;jsessionid=<sessionId>

to the url and did nothing.

I also tried to do new Subject.Builder().sessionId(sessionId).buildSubject();

in getData()

, but .sessionId()

didn't like it there String

.

I have not yet figured out exactly where the session cookie handling takes place.

How do I correctly collect the session cookie so that the mobile app can use the app in the same way as the web client?

PS My plan B is to just pass the username / password in the authentication headers on every request and ApiController

do it subject.login

every time, but I would rather do this using the session id that is already in use for the web app.

+3


source to share


1 answer


Something seems to be called Custom Custom Instances ( https://shiro.apache.org/subject.html#custom-subject-instances )

There are two steps:

  • Create a theme (with Builder)
  • Link a topic to a stream (many ways to do this)


Unconfirmed example:

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();
}

      

0


source







All Articles