Optional Auth in newer dropwizard-auth

650 views
Skip to first unread message

pme...@reonomy.com

unread,
Jul 8, 2016, 11:56:36 AM7/8/16
to dropwizard-user
Hi friends!

I'm enjoying Dropwizard, but scratching my head about how to go about Optionally protecting resources. The older Auth model had `@Auth(required = false)`, and after upgrading, I've more or less got what I'd like, but having trouble fully understanding the line in the documentation:

"you need to implement a custom filter which injects a security context containing the principal if it exists, without performing authentication."

Maybe some code would help. I have an Auth filter that reads cookie values to check a session ID (this is Kotlin, so please excuse any differences with Java):

```
override fun filter(requestContext: ContainerRequestContext?) {
    val cookieValue : String? = getCookie(requestContext)
    try {
        if (cookieValue != null) {
            val credentials : MyCredentials = MyCredentials.fromCookie(cookieValue)
            val result : Optional<User> = authenticator.authenticate(credentials)
            if (result.isPresent) {
                requestContext?.securityContext = object: SecurityContext {
                    override fun isUserInRole(role: String?): Boolean {
                        return authorizer.authorize(result.get(), role)
                    }
                    override fun getAuthenticationScheme(): String {
                        return SecurityContext.FORM_AUTH
                    }
                    override fun getUserPrincipal(): Principal { return result.get() }
                    override fun isSecure(): Boolean { return requestContext?.securityContext?.isSecure ?: false }
            }
            return
        }
    }
    return
    } catch (e : IllegalArgumentException) {
        LOGGER.warn("Error decoding credentials:", e)
    } catch (e : AuthenticationException) {
        LOGGER.warn("Error authenticating credentials", e)
        throw InternalServerErrorException()
    }
    throw WebApplicationException(unauthorizedHandler.buildResponse(prefix, realm))
}
```

Which then I register with my app using:

```
env.jersey().register(AuthDynamicFeature(MyAuthFilter.Builder()
    .setAuthenticator(MyAuthenticator(sessions, userDao))
    .setAuthorizer(PermitAllAuthorizer())
    .setPrefix("MyApp")
    .setRealm("myRealm")
    .buildAuthFilter()))
env.jersey().register(AuthValueFactoryProvider.Binder(User::class.java))
```

This works fine for ensuring anything annotated with `@Auth` is mandatory protection. But for optional protection, how do I alter the filter above? If you return null in `getUserPrincipal`, the app fails with "Cannot inject a custom principal into unauthenticated request".

The closes thing I can think of is creating a static `OPTIONAL_AUTH` instance of my Principal to return in a SecurityContext when the session/cookie doesn't work out,  and checking against it in my resources, subsequently throwing 401s for anything I deem "mandatory protection" but this feels extremely hacky and I'm sure there's a Better Way.

Any help would be appreciated. Thanks so much for your time :D

-Pablo

Evan Meagher

unread,
Jul 11, 2016, 10:18:23 PM7/11/16
to dropwiz...@googlegroups.com
I think that your suggested "closest thing" isn't too far off the mark of what the quoted documentation snippet is referring to. For each request, dropwizard-auth sniffs the SecurityContext for any in-context Principals. If it doesn't find a Principal, then it throws the "Cannot inject a custom principal" exception that you're observing.

In your `filter` method, you need to manually inject a "shim" Principal into the current ContainerRequestContext in the case where one doesn't already exist for the user you've extracted from the cookie.

--
You received this message because you are subscribed to the Google Groups "dropwizard-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dropwizard-us...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Evan Meagher

Evan Meagher

unread,
Feb 21, 2017, 8:01:17 PM2/21/17
to dropwiz...@googlegroups.com
To follow up on this, a change recently merged which adds the ability to optionally protect resources using `Optional` resource method arguments in conjunction with the `@Auth` annotation.


This change is slotted for inclusion in the upcoming 1.1.0 release.

To unsubscribe from this group and stop receiving emails from it, send an email to dropwizard-user+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
Evan Meagher



--
Evan Meagher
Reply all
Reply to author
Forward
0 new messages