I think a Principal is a set of roles.
You can think of a principal simply as a user of the system. The system's principals are independent from ejb's and therefore it's the system administrator's responsibility to define principals (in practise: users and user groups).
In "declarative security" ejb's are secured by roles (using @RolesAllowed).
The link between principals and roles is provided by the deployer: He assigns each principal that uses the bean a corresponding role. This is done in the runtime deployment descriptor (at least for glassfish) and is specific to the app server.
If role is not specified, then principal is propagated to role. if principal is not specified, then role is propagated to principal
Consider the following scenario:
- Client C calls methodA() on bean A, which calls methodB() on bean B (code as above).
- The user logs in on the client as "Amandeep" and there is defined a corresponding principal Amandeep_Principal on app server 1 where A resides. The deployer has assigned Amandeep_Principal the role "Guest".
- Normally, when methodB() is called, Amandeep_Principal would be propagated to app server 2 where B resides. But you can circumvent this propagation using, say, @RunAs("Admin").
For this to work there must be a principal with role "Admin" on app server 1, say Admin_Principal (if there are several principals with role "Admin" glassfish chooses one coincidentally). From the perspective of app server 2, now methodB() is called by principal Admin_Principal.
Of course, Admin_Principal must be defined on app server 2, too, and the assigned role of Admin_Principal on bean B has to be "Admin". Otherwise the call of methodB() will result in an EJBAccessException.