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 
<http://www.dropwizard.io/0.9.3/docs/manual/auth.html>:

"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

-- 
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 [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to