Hi,

Let me take another stab on this. Was a bit confused with Guice/Sisu/Karaf 
binding in our app, that’s why I gave up on replacing SubjectFactory the other 
day, but now I took an experiment with simpler Shiro Examples project as Brian 
did.

So, here is the result:
https://github.com/cstamas/shiro/compare/cstamas:1.2.x...cstamas:1.2.x-anon-examples

Is lacking WebSubject support, but is trivial to add it.

Despite using custom subject implementation, casting it is needed at one single 
place: the servlet filter (not on branch, TBD), that would just call 
subject.setAnonymous() on enter, and subject.unsetAnonymous() on exit 
(preHandle/afterCompletion if using Shiro AdviceFilter as basis). Ordering of 
that filter is completely irrelevant (could be first, or could be after some 
permissive authc filter), as even if subject set as anonymous, real logins will 
still work, and subject will become authenticated.

- enable/disable anonymous support completely (no need to change anything in 
above mentioned servlet filter)
- allows to override session creation for anonymous users
- allows to customise principal used for anonymous, it can be “anonymous”, 
“Guest”, “brian” or even “lonestar” ;)
- allows to set “originating realm”, in which case, the anonymous user 
authorization will be delegated to that realm, basically “mapping” anonymous 
user permission to some existing user in some realm
- allows to explicitly set roles/perms anonymous user has, if not mapped, TBD. 
In our case, App does have RolePermissionResolver, but here I did “hardwire” it 
just for sake of example.

The branch above enables anonymous user, and just for fun uses principal 
“darkhelmet” and maps anonymous user to “iniRealm” realm. This way, when 
anonymous user permissions are evaluated, it actually receives same set of 
permissions than darkhelmet has. Also, QuickStart modified by adding logs where 
you can see is user anonymous, which principal it uses, and does it have some 
needed perm.

As I am aware of, this solution completely fits into Shiro concepts of “guest” 
and rememberMe just fine, and anon user still have subject.principal == null, 
and all the filters and annotations should just work with it.

I do find this interesting, and have to agree with Jason, that I feel like 
Shiro should support this kind of use case. And it would just add new flag to 
subject, along to existing:
- isAuthenticated (have principal and authenticated = true)
- isRemembered (have principal and authenticated = false)
- isAnonymous (have anonPrincipal and authenticated = false)
- isGuest (have nothing)

Have fun!

-- 
Thanks,
~t~

On 13 Feb 2015 at 06:14:15, Jason Dillon ([email protected]) wrote:

Tamas tossed up this as an example:

https://github.com/sonatype/nexus-oss/commit/ad1d703125ec1be1d0eae00492939d60de38a701#diff-c82a898a4ce4094080b2cb98d3567affR38

That should work, but it seems like a long way to go for something that 
_should_ just work.
Another idea to consider, is just setting the default principal to 'anonymous' 
via a SubjectFactory

https://github.com/bdemers/shiro/compare/bdemers:anonymous-user-roles...anon-take-2#diff-c592bbcd955d97db3e51216509533851R10

and then injecting that component: 
https://github.com/bdemers/shiro/compare/bdemers:anonymous-user-roles...anon-take-2#diff-0d740ecf6abf4b36742a10db24b7b8c7R28

(i'm not sure how this plays with the rememberMe functionality, but adding just 
adding this as a thought)
FTR I had no idea there was a DefaultSubjectFactory.  I think however since 
that might be global, that a filter in this case may be better, but have to 
think about it more now that I realize there is a feature to set the default 
subject via factory.



Will this work and property get the anonymous subject managed so that the rest 
of Shiros systems behave properly?  Tamas had another example below it that 
does a login() but I don't think that is proper, as well as its much more 
expensive as it dives into shiro frameworks, not something we want to do on 
each request w/o authentication.

This branch also has a special realm, but I'm not sure if that is actually 
needed or something like "n/a" for realm-name as you have in your example w/o a 
realm bound to that name is sufficient?

Yeah, the anonymous realm would be a better way to deal with that, that way you 
could force this user to the anonymous realm (by making it first in your realm 
list) which means you would not need to worry about the odd case of a person 
trying to login with the 'anonymous' user and becoming authenticated.
Anonymous realm seems to also provide easy way to shut off anonymous, another 
requirement/use-case we have.



And yes, generally we'd like to be able to have a way to grant _guest_ a set of 
roles/permissions but presently the shiro frameworks only can do this if a 
subject has a principal and a _guest_ is a subject w/o a principal.

I'd like to hear other thoughts on this, because I've banged my head on this 
before.  I feel you should be able to assign roles/permissions to the _guest_ 
user, currently the only way to do this is to force a fake principal into the 
mix (and then you are no longer really a _guest_)
Ya, it would be nice if the default delegating impl had some means to say give 
me the permissions for _guest_ user.  I think we could build that ourselves, 
but it seems like something missing from the core framework.  Would be easier 
if the delegating took the subject instead of the the subject.principal, and 
left that detail up to the securitymanager impl.



It may not matter however for our case, if you remember, we have to be able to 
allow the _anonymous_ username to be changed for some crazy reason, so we can 
not really use the _guest_ concept at all, but have to continue using an 
_anonymous_ (non-authenticated, non-remembered, non-logged-in) user.

Yeah, in your case, that dated back to an old odd requirement (the idea was to 
allow the anonymous user's info to be pulled from an external source i.e. LDAP)
Yar, we can’t even fully remember the details except for something like “if you 
use active-directory the _anonymous_ user is called _guest_.  But I think we 
are on a path now to make this work in a simpler fashion, removing the 
subject.login() should really help.

I think though that shiro could really do with some proper api around is 
subject.Guest() or subject.isAnonymous()  (pick one they mean basically the 
same thing), vs. assuming subject.principal=null implies this and has no 
permissions.  Many use-cases I think to want to use the permission system to 
allow folks who are anonymous/guest to have access.  Certainly we have these 
use-cases.  Needing to force in a fake non-authenticated user complicates 
things, and voids some of the use of @RequireGuest apis.

ATM if we progress we can’t use Shiro concept of _guest_ at all.  And would 
have to re-implement @RequiresGuest and @RequiresUser to be aware of this 
special subject.principal=<anonymous>.   Its do able, and we’ll likely move 
forward to to this.  But the framework itself IMO should cope with this 
edge-case, which isn’t limited to use if you ask google.

 * * *

FTR, shiro is very simple if you use it as explained in the limited examples, 
but as soon as you get off the path, its vastly complex and hard to comprehend.

Anyways, we may need more input from you guys and I appreciate the response 
with details.  If there is anything we can contribute back, of course, we’ll be 
more than happy to do so… but I think this specific issues is a core design 
limitation to the framework/api that can as-is only be worked around at present.

—jason

Reply via email to