calloc_org
calloc_org

Reputation: 584

Play Framework request attributes with typed key

I seem to have issues accessing the attributes of the request attributes map in Play. Following the explanation offered by Play (Link), I should get the correct data from the attributes, but the Option is returned as None.

My structure is as follows. One controller (later injected named as "sec") has the typed attribute for shared access to it:

val AuthenticatedAsAttr: TypedKey[AuthenticatedEmail] = TypedKey("AuthenticatedAs")

The type AuthenticatedEmail is defined in the companion object of this controller as a case class:

case class AuthenticatedEmail(email: String)

The filter passes the attribute to the next request:

val attrs = requestHeader.attrs + TypedEntry[AuthenticatedEmail](sec.AuthenticatedAsAttr, AuthenticatedEmail(email))
nextFilter(requestHeader.withAttrs(attrs))

When trying to then access this attribute in another controller, the returned Option is None:

val auth = request.attrs.get(sec.AuthenticatedAsAttr)

I confirmed via println that the value is definitely in request.attrs but run out of options to debug the issue successfully. A fraction of the println output below.

(Request attrs,{HandlerDef -> HandlerDef(sun.misc .... ,POST, ... Cookies -> Container<Cookies(Cookie ... , AuthenticatedAs -> AuthenticatedEmail([email protected]), ... })

My Scala version is 2.12.6, Play Framework version 2.6.18. Any help is highly appreciated.

Upvotes: 2

Views: 1757

Answers (1)

calloc_org
calloc_org

Reputation: 584

It turns out that the TypedKey must be within an object, not an inject-able controller. So moving it to an object like the following resolves the issue:

object Attrs {
    val AuthenticatedAsAttr: TypedKey[AuthenticatedEmail] = TypedKey("AuthenticatedAs")
}

The reason is the implementation of TypedKey (Link), which does not contain an equals method and therefore reverts to comparing memory references.

Upvotes: 3

Related Questions