I have similar requirements. I'd be happy to share with you how I go about
it. To start with, I use JAX-RS (1.0) for my REST API.
In my shiro.ini (or, in my case, Guice module), I have the filter setup:
/** = authcBasic[permissive]
Then, I use @RequiresPermission on my JAX-RS http methods.
@GET
@Produces("application/json")
public List<Item> listItems();
@POST
@Produces("application/json")
@Consumes("application/json")
@RequiresPermissions("item:create")
public Item createItem(Item item);
@GET
@Produces("application/json")
@Path("/{id}")
public Item getItem(@PathParam("id") String itemId);
This works fine for anonymous users - the two @GET methods don't require a
login, but the @POST method does. The "permissive" is the key to anonymous
users here - and I'm not sure if that's documented. If not, that's
primarily because it sort of smells. The BasicHttpAuthenticationFilter
extends AuthenticatingFilter, which says "An AuthenticationFilter that is
capable of automatically performing an authentication attempt based on the
incoming request.". That's cool, that's what we want. Unfortunately,
AuthenticatingFilter extends AuthenticationFilter, which says "Base class
for all Filters that require the current user to be authenticated.". We
don't want this for your (and my) usecase, and permissive basically removes
that guarantee.
Hope that helps.
Thanks,
Jared
On Sep 25, 2013 6:45 PM, "davison" <[email protected]> wrote:
> Hi everyone,
>
> I've been struggling with what I think should be a trivial security issue
> for
> well over a week (which is almost as long as it took me to write this
> simple app in its entireity!) Having spent quite a long time now going
> through
> the source code for Shiro and the docs, I think I've concluded that what I
> want to do isn't possible without re-implementing core parts of the
> framework.
>
> So I hope someone can prove me wrong :)
>
> My app is basically a simple server-side API for some REST clients,
> principally
> an HMTL5 front end. I need some of the resources to be accessible to an
> anonymous user for reading, but not for create/update/delete.
>
> For example;
>
> GET /api/foo (ok for UNauthenticated/anonymous user)
> PUT /api/foo (requires admin role)
>
> There are some secondary requirements which are also problematic, but they
> are
> moot if this one can't be solved easily.
>
> Should be simple, but here's why I think this looks impossible..
>
> To base my permissions on the HTTP method, I need to use the 'rest' filter
> (HttpMethodPermissionFilter). However, this has no way to specify that
> some
> permissions are accessible for the anonymous user - because ANY set of
> permissions requires an authenticated subject (see the various
> DelegatingSubject.isPermitted() methods that all start with a requirement
> that
> current principals exist).
>
> I even created my own filter that would programatically "login" a user
> named
> "anonymous" (defined in my realm) that could be given suitable permissions,
> and
> this works in isolation;
>
> public class AnonymousRoleAuthenticationFilter extends OncePerRequestFilter
> {
> @Override
> public void doFilterInternal(
> ServletRequest request,
> ServletResponse response,
> FilterChain chain) throws IOException, ServletException
> {
> Subject subject = SecurityUtils.getSubject();
> if (subject.getPrincipals() == null ||
> subject.getPrincipals().isEmpty())
> {
> subject.login(new UsernamePasswordToken("anonymous",
> "anonymous"));
> }
> chain.doFilter(request, response);
> }
> }
>
>
> // realm config below...
> user.admin=s3cr3t,admin
> user.anonymous=anonymous,anonymous
> role.admin=*
> role.anonymous=*:read
>
>
> But if this filter sits before any other (like authcBasic) that I use to
> gather
> credentials from an admin user, then the admin credentials will never be
> requested because there is already an authenticated subject.. he just
> doesn't have permission. If I reverse the order of those filters, then I
> will
> incorrectly be asked for credentials even for resources that anonymous
> should
> be able to read - because without the subject, the framework can't decide
> if
> permissions apply or not. It's this that seems like a fundamental use case
> is
> not being catered for and which would need a lot of core framework
> changes/overrides.
>
> Can anyone help me out?
>
> Best wishes,
> Darren.
>
>
>
>
> --
> View this message in context:
> http://shiro-user.582556.n2.nabble.com/REST-API-permissions-with-anonymous-usage-tp7579176.html
> Sent from the Shiro User mailing list archive at Nabble.com.
>