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.
https://github.com/dropwizard/dropwizard/pull/1931 This change is slotted for inclusion in the upcoming 1.1.0 release. On Mon, Jul 11, 2016 at 7:18 PM, Evan Meagher <[email protected]> wrote: > 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 > -- 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.
