On the differences between doAs() and doAsPrivileged(), I found a good post of Sun Java Forums:
doAsPrivileged effectively means you are granting
the calling stack your [code's] privileges when executing the code in question. Whereas doAs only associates the subject with the current access control context, all the calling code still requires the permission to be assigned to it (under the subject in question).
Where it gets interesting, is that when implementing a custom policy, and assessing whether the caller is authorized to access the callee, in implies(ProtectionDomain protectionDomain, Permission permission) the protectionDomain does not contain the principals when performing a doAs check. As mentioned in this post on the Java Forum, when the permission check is concerned about the principals in the subject (call to protectionDomain.getPrincipals()) for the security check, the security check should be performed as:
doAsPrivileged(theSubject, anAction, null)
By passing in a null access control context, the caller is essentially saying: "I don't care who called me, the only important thing is whether I have permission when associated with the given subject".