身份validation后以编程方式添加角色

我有以下JSF 2.1登录表单,在Glassfish 3.1中运行

          

以及支持bean。

 public String login() throws IOException, LoginException { log.debug("Trying to login with username " + username); HttpSession session = getRequest().getSession(true); try { getRequest().login(username, password); // if OK, add Roles ???????? ................... } catch (ServletException e) { // TODO Auto-generated catch block e.printStackTrace(); } log.debug("USER principal === " + getRequest().getUserPrincipal()); return "home"; } 

问题是,如何在成功登录后以编程方式将角色添加到UserPrincipal?

更新1:我试图通过使用以下代码获取主题但主题== null。

 Subject thisSubject = Subject.getSubject(AccessController .getContext()); 

谢谢,科恩

我想出了以下解决方案,在登录后以编程方式添加角色,至少在GlassFish 3.1.2 build 23上有效。

 import com.sun.enterprise.security.SecurityContext; import com.sun.enterprise.security.web.integration.PrincipalGroupFactory; import java.security.Principal; import java.util.Set; import javax.security.auth.Subject; import org.glassfish.security.common.Group; public class GlassFishUtils { public static void addGroupToCurrentUser(String groupName, String realmName) { Subject subject = SecurityContext.getCurrent().getSubject(); Set principals = subject.getPrincipals(); Group group = PrincipalGroupFactory.getGroupInstance(groupName, realmName); if (!principals.contains(group)) principals.add(group); } } 

您需要将GlassFish中的security.jarcommon-util.jar添加到项目库中。

并且不要忘记在web.xml中为要添加的角色创建部分。

请注意,我使用的function似乎不是已发布的稳定API的一部分,因此无法保证这将在以后的GlassFish版本中继续使用。

我从GlassFish的sun.appserv.security.AppservPasswordLoginModule.commit()的源代码中获取了有关如何添加角色的信息。 如果未来的GlassFish版本破坏了我的代码,那么这个函数将是一个很好的起点,以便找到解决方法。

好的,我已经找到了一个解决方法,在我看来这不是100%正确但欢迎提出建议:)

 public void login() throws IOException, LoginException { log.debug("Trying to login with username " + username); try { getRequest().login(username, password); HttpSession session = getRequest().getSession(true); Subject subject = (Subject) session .getAttribute("javax.security.auth.subject"); if (subject == null) { log.debug("Subject is null, creating new one"); subject = new Subject(); subject.getPrincipals().add(new PlainRolePrincipal("USER")); subject.getPrincipals().add(new PlainRolePrincipal("ADMIN")); } log.debug("HAS USER " + getRequest().isUserInRole("USER")); log.debug("HAS ADMIN " + getRequest().isUserInRole("ADMIN")); log.debug("HAS REPORT " + getRequest().isUserInRole("REPORT")); session.setAttribute("javax.security.auth.subject", subject); log.debug("USER principal === " + getRequest().getUserPrincipal()); FacesContext.getCurrentInstance().getExternalContext() .redirect("pages/home.jsf"); } catch (ServletException e) { FacesContext.getCurrentInstance().addMessage("Login", new FacesMessage("Invalid Username/Password combination")); e.printStackTrace(); } } 

我还使用以下信息bean来检索主题并检查主体。

  @ManagedBean(name = "userInfo") @SessionScoped public class UserInformation { /** * Fetches current logged in username. * * @return */ public String getUsername() { return FacesContext.getCurrentInstance().getExternalContext() .getRemoteUser(); } public boolean isUserInRole(String roleName) { Subject subject = (Subject) getRequest().getSession().getAttribute( "javax.security.auth.subject"); for (Principal p : subject.getPrincipals()) { if (p.getName().equals(roleName)) { return true; } } return false; } public static HttpServletRequest getRequest() { Object request = FacesContext.getCurrentInstance().getExternalContext() .getRequest(); return request instanceof HttpServletRequest ? (HttpServletRequest) request : null; } 

}

所以我解决了isUserInRole机制,真正的isUserInRole方法在USER上只返回true,因为在validation时设置了该角色。

从JSF页面我现在可以做

  

希望这有助于其他用户,欢迎任何改进建议!