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.

On Fri, Jul 8, 2016 at 8:56 AM, <[email protected]> wrote:

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



-- 
Evan Meagher

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