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.