You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by "Yakushev Mikhail (Jira)" <ji...@apache.org> on 2020/05/18 07:18:00 UTC

[jira] [Updated] (TOMEE-2763) Security Principal is lost after calling a method from ejb with @RunAs annotation

     [ https://issues.apache.org/jira/browse/TOMEE-2763?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Yakushev Mikhail updated TOMEE-2763:
------------------------------------
    Affects Version/s: 8.0.1

> Security Principal is lost after calling a method from ejb with @RunAs annotation
> ---------------------------------------------------------------------------------
>
>                 Key: TOMEE-2763
>                 URL: https://issues.apache.org/jira/browse/TOMEE-2763
>             Project: TomEE
>          Issue Type: Bug
>    Affects Versions: 8.0.1
>            Reporter: Yakushev Mikhail
>            Priority: Major
>         Attachments: tomee-runas.zip
>
>
> Sample application: [^tomee-runas.zip]
>  
> EJB 1
> {code:java}
> @LocalBean
> @Stateless(name = "MyStateless")
> public class MyStatelessBean {
>     @Resource
>     private SessionContext sessionContext;
>     @EJB
>     private UserBean userBean;    
>     
>     public MyStatelessBean() {
>     }    
>     
>     public void test() {
>         System.out.println("ejb WITHOUT @RunAs, username from sessionContext 1: " + sessionContext.getCallerPrincipal().getName());
>         System.out.println("ejb WITHOUT @RunAs, username from another ejb: " + userBean.currentUserName());
>         System.out.println("ejb WITHOUT @RunAs, username from sessionContext 2: " + sessionContext.getCallerPrincipal().getName());
>     }
> }{code}
> EJB 2
> {code:java}
> @LocalBean
> @RunAs("admin")
> @Stateless(name = "MyStatelessRunAsBean")
> public class MyStatelessRunAsBean {
>     @Resource
>     private SessionContext sessionContext;
>     @EJB
>     private UserBean userBean;
>     public MyStatelessRunAsBean() {
>     }
>     public void test() {
>         System.out.println("ejb WITH @RunAs, username from sessionContext 1: " + sessionContext.getCallerPrincipal().getName());
>         System.out.println("ejb WITH @RunAs, username from another ejb: " + userBean.currentUserName());
>         System.out.println("ejb WITH @RunAs, username from sessionContext 2: " + sessionContext.getCallerPrincipal().getName());
>     }
> }{code}
>  EJB 3
> {code:java}
> @LocalBean
> @Stateless(name = "UserBean")
> public class UserBean {
>     @Resource
>     private SessionContext sessionContext;
>     public UserBean() {
>     }
>     public String currentUserName() {
>         return sessionContext.getCallerPrincipal().getName();
>     }
> }{code}
> Backing bean for jsf page
> {code:java}
> @Model
> public class IndexMB {
>     @EJB
>     private MyStatelessBean myStatelessBean;
>     @EJB
>     private MyStatelessRunAsBean myStatelessRunAsBean;
>     public void test(ActionEvent event) {
>         myStatelessBean.test();
>         myStatelessRunAsBean.test();
>         myStatelessBean.test();
>     }
> }
> {code}
> Expected output:
>  ejb WITHOUT @RunAs, username from sessionContext 1: *ymn*
>  ejb WITHOUT @RunAs, username from another ejb: *ymn*
>  ejb WITHOUT @RunAs, username from sessionContext 2: *ymn*
>  ejb WITH @RunAs, username from sessionContext 1: *ymn*
>  ejb WITH @RunAs, username from another ejb: *admin*
>  ejb WITH @RunAs, username from sessionContext 2: *ymn*
>  ejb WITHOUT @RunAs, username from sessionContext 1: *ymn*
>  ejb WITHOUT @RunAs, username from another ejb: *ymn*
>  ejb WITHOUT @RunAs, username from sessionContext 2: *ymn*
>   
>  Real output:
>  ejb WITHOUT @RunAs, username from sessionContext 1: *ymn*
>  ejb WITHOUT @RunAs, username from another ejb: *ymn*
>  ejb WITHOUT @RunAs, username from sessionContext 2: *ymn*
>  ejb WITH @RunAs, username from sessionContext 1: *ymn*
>  ejb WITH @RunAs, username from another ejb: *admin*
>  ejb WITH @RunAs, username from sessionContext 2: *ymn*
>  ejb WITHOUT @RunAs, username from sessionContext 1: *guest*
>  ejb WITHOUT @RunAs, username from another ejb: *guest*
>  ejb WITHOUT @RunAs, username from sessionContext 2: *guest*
> In method *enterWebApp* of class *TomcatSecurityService* token is null:
> {code:java}
> newIdentity = new Identity(newSubject, null);{code}
> Because of this block of code in *StatelessContainer* class do nothing (runAs is null)
> {code:java}
>         } finally {
>             if (runAs != null) {
>                 try {
>                     securityService.associate(runAs);
>                 } catch (final LoginException e) {
>                     // no-op
>                 }
>             }
> {code}
> I fixed it for my app in that way:
> {code:java}
>     public Object enterWebApp(final Realm realm, final Principal principal, final String runAs) {
>         final Identity oldIdentity = clientIdentity.get();
>         if (principal != null) {
>             final Subject newSubject = createSubject(realm, principal);
>             try {
>                 associate(registerSubject(newSubject));
>             } catch (LoginException e) {
>             }
>         }
>         final WebAppState webAppState = new WebAppState(oldIdentity, runAs != null);
>         if (runAs != null) {
>             final Subject runAsSubject = createRunAsSubject(runAs);
>             RUN_AS_STACK.get().addFirst(runAsSubject);
>         }
>         return webAppState;
>     }
> {code}



--
This message was sent by Atlassian Jira
(v8.3.4#803005)