2017-10-07 119 views
1

我想从之前部署在bea weblogic中的Web应用程序转换现有的api。我现在需要到JBoss EAP 7为什么Subject.doAs会根据登录用户而不是交换主题返回主体?

在我的用户登录代码部署该应用程序时,我做的,像这样的servlet认证:

HttpServletRequest request = ServletActionContext.getRequest(); 
request.login("user1", "password"); 

testEJB= (TestEJB) LookupUtil.lookup("TestEJB"); 
System.out.println("logged in user: " + testEJB.getName()); //returns user1 

现在sessionContext在每一个EJB抬头由容器返回登录用户,这是完美的,除了一些应用程序功能需要切换用户和做一些特权行动,例如上传文件。

我交换用户以及执行像这样的特权行动:

LoginContext loginContext = new LoginContext("TestLoginContext", new UsernamePasswordHandler("user2", "password")); 
loginContext.login(); 
String newUser = (String) Subject.doAs(loginContext.getSubject(), new TestPrivilegedAction()); 
System.out.println("privileged User: " + newUser); //still returns user1 

以我TestPrivilegedAction它实现的PrivilegedAction,我有以下代码:

@Override 
public Object run() { 
    return this.getSwitchedUser(); 
} 

private Object getSwitchedUser() { 
    testEJB= (TestEJB) LookupUtil.lookup("TestEJB"); 
    System.out.println("logged in user: " + testEJB.getName()); 
} 

基本上,使用的原始API时该应用程序部署在weblogic中:

Authenticate.authenticate 
Security.runAs 

LoginContext.login 
Subject.doAs 

那么,为什么现在它仍返回登录的用户(用户1),即使认证成功,并且主题已被设置为:...然后我有以下使它在JBoss的工作取代了它user2的?我一直在寻找网络,并试图看看我是否只是缺少一些配置,但我现在真的坚持下去。我很欣赏任何反馈或建议。

回答

0

经过一段时间的可用API试验后,我终于能够解决我的问题。我只是想把它放在这里,以防其他人遇到同样的问题。

基本上,我彻底改造用于WebLogic Server中现有的API:

Authenticate.authenticate 
Security.runAs 

这里是我的身份验证类:

public class Authenticate { 

    private static Subject originalSubject = null; 

    public static void authenticate(Hashtable env, Subject subject) throws LoginException { 
     try {   
      //retrieve the security context that contains the current subject (logged in user) 
      SecurityContext securityContext = SecurityContextAssociation.getSecurityContext(); 
      SubjectInfo subjectInfo = securityContext.getSubjectInfo(); 

      //set the current subject as the original subject 
      originalSubject = subjectInfo.getAuthenticatedSubject(); 

      //start authentication of the new subject 
      CallbackHandler callbackHandler = new UsernamePasswordHandler((String) env.get(Context.SECURITY_PRINCIPAL), env.get(Context.SECURITY_CREDENTIALS)); 
      LoginContext loginContext = new LoginContext("JbossLoginContext", callbackHandler); 
      loginContext.login(); 

      //set the new subject information to perform the privileged action 
      subject.getPrincipals().addAll(loginContext.getSubject().getPrincipals()); 
      subjectInfo.setAuthenticatedSubject(loginContext.getSubject()); 
     } catch (LoginException e) { 
      throw new LoginException(); 
     } catch (Exception e) { 
      throw new Exception(); 
     } 
    } 

    public static void setOriginalSubject() { 
     try { 
      //if the login method is already invoked, replace the current subject with the original subject 
      if(originalSubject != null) { 
       SecurityContextAssociation.getSecurityContext().getSubjectInfo().setAuthenticatedSubject(originalSubject); 
      } 
     } catch (Exception e) { 
      throw new Exception(); 
     } 
    } 
} 

我创建了一个包装类这是不是就与Subject.doAs具有切换原始主题的功能。这是我如何做的:

public class Security { 

    public static Object runAs(Subject subject, PrivilegedAction privilegedAction) { 
     try { 
      Object object = Subject.doAs(subject, privilegedAction); 
      Authenticate.setOriginalSubject(); 
      return object; 
     } catch (Exception e) { 
      throw new Exception(); 
     } 
    } 
} 

现在,我仍然使用与Subject.doAs方法的通知,然后我打电话Authenticate.setOriginalSubject设置原始主题回来。

一切正常,我几乎只需要在使用它的类文件中更新软件包导入。