2016-11-15 51 views
1

我们有一个需要用户登录的xpage应用程序(使用lotus notes id和密码)。如果用户成功登录,它会将用户重定向到指定页面(例如,home.xsp)。如果用户有多个角色,如何让用户选择一个角色来访问应用程序?

开始时,应用程序很简单,一个用户在应用程序中有一个角色。每个角色在程序中都有不同的功能和界面。 (这也与用户一致)。 请想象下面的表格是关于用户和用户角色的。

Username | Role 
Alan  | admin 
Ben  | user 
John  | leader 
Judy  | developver 
Sam  | manager 
Susan | senior 
Tom  | user 

最近,我们的用户改变了主意,他们希望在应用程序中拥有多个角色。请考虑以下情况。

Username | Role 
Alan  | admin,leader 
Ben  | user, admin 
John  | leader, manager 
Judy  | developver 
Sam  | manager, user 
Susan | senior,manager, user 
Tom  | user 

根据上表,一些用户在程序中有更多的一个角色。由于每个角色在程序中都有不同的功能和界面,我们注意到如果用户有多个角色,那么界面看起来不整洁,有些功能不能正常工作。因此,我们正在考虑强制用户选择一个角色进行登录。

在指定页面(例如home.xsp)中,该页面将在用户成功登录后显示。我们试图找出用户是否有多个角色,所以我们把下面的代码放在beforePageLoad事件中。

var roles = context.getUser().getRoles() 
//if the user has multiple roles, force them to other page 
if(roles.length > 1) 
{ 
    context.redirectToPage("chooserole.xsp"); 
} 
else 
{ 
    //do nothing 
} 

在chooserole.xsp中,页面会找到用户拥有的角色,然后要求用户选择一个来登录。所以页面看起来就像这样

<?xml version="1.0" encoding="UTF-8"?> 
<xp:view xmlns:xp="http://www.ibm.com/xsp/core"><xp:label value="Please select user role" id="label1" style="margin-left:200.0px"></xp:label> 
<xp:text escape="true" id="computedField2" rendered="false"> 
    <xp:this.value><![CDATA[#{javascript:context.getUser().getRoles() 
}]]></xp:this.value> 
</xp:text><xp:br></xp:br> 

<xp:radioGroup id="radioGroup1" layout="pageDirection" style="margin-left:100.0px" value="#{applicationScope.role}"> 
    <xp:selectItems> 
     <xp:this.value><![CDATA[#{javascript:getComponent("computedField2").getValue();}]]></xp:this.value> 
    </xp:selectItems> 
</xp:radioGroup> 

<xp:br></xp:br> 
<xp:button value="Login" id="button1" style="height:35.0px;margin-left:200.0px"> 
    <xp:eventHandler event="onclick" submit="true" refreshMode="complete"> 
     <xp:this.action><![CDATA[#{javascript:var rolevalue = getComponent("radioGroup1").getValue(); 
applicationScope.put(role,rolevalue); 
context.redirectToPage("Home.xsp");}]]></xp:this.action> 
    </xp:eventHandler></xp:button><xp:button value="Cancel" id="button2" style="height:35.0px;margin-left:30.0px"></xp:button><xp:br></xp:br> 

</xp:view> 

当我们使用多个角色帐户运行的程序,该程序可我们重定向到chooserole.xsp,然而,在该网页上,无论我们选择哪个角色,我们只是留在chooserole.xsp中。

我们猜测问题出在beforePageLoad部分,因为在那部分我们检查了多个角色,如果用户有多个角色,它会将用户重定向到指定的页面。

我们不明白的一件事是在chooserole.xsp中,我们要求用户选择一个登录角色,当用户选择一个角色时,该角色应该将用户引导到home.xsp。但是,home.xsp似乎认为用户具有多个角色,因此它将用户保留在chooserole.xsp中。

我们在编码方面做错了吗?我们尝试删除beforePageLoad中的代码并放入afterPageLoad中,但程序仍将用户保留在chooserole.xsp中。

感谢您的咨询。谢谢。

参考文献:

https://lostinxpages.com/2014/01/06/finding-user-roles-in-xpages/

Access Control with a multi database application

XPages: context.getUser().getRoles() working sporadically

http://flylib.com/books/en/2.348.1.172/1/

+1

我会去重温'需要选择角色'的方法。你可能会更好地扭转这个过程。设计一个适用于具有所有角色的虚拟“超级用户”的应用程序,然后在较少角色出现时开始限制选择。用户并不认为自己是“扮演角色”,而是“做他们的工作”。避免引入基于角色的模式 – stwissel

回答

1

你试验home.xsp的beforePageLoad事件,如果用户有一个以上的角色。

如果是,则重定向到chooserole.xsp。您让用户选择一个角色并将其放入applicationScope变量中。然后你重定向回到home.xsp。

用户还有更多的角色。它重定向到chooserole.xsp ...欢迎来到不定式循环。


解决方案:

使用sessionScope变量为用户的一个作用(而不是作为它的之间所有用户共享一个applicationScope变量)例如sessionScope.role。在home.xsp的beforePageLoad事件

测试是否sessionScope.role未定义与
if (!sessionScope.containsKey("role")) { ...
如果它是不确定的,然后将其设置为用户拥有一个角色或重定向到chooserole.xsp如果用户有一个以上的角色。

将chooserole.xsp中的sessionScope.role设置为用户选择并重定向回home.xsp的角色。

现在,sessionScope.role有一个值(一个角色),您可以继续使用home.xsp内容。

确保在你的菜单测试或任何你使用一个作用,为sessionScope.role,而不是context.getUser().getRoles()了。

+0

是的,你是对的。实际上,我们认为应用程序范围值会让程序“知道”用户想要登录的角色。但结果是我们犯了一个错误,程序只是保持循环。我们仍然需要弄清楚如何让用户选择一个角色来登录xpages,而不是更改访问控制列表中的角色。 – beginner

+0

@beginner你几乎在那里:你只需要检查applicationScope.role,然后使用applicationScope.role中的值作为角色 –

+0

applicationScope对于应用程序的_all_用户将是相同的值。正如Knut所说,你应该使用'sessionScope'。无论如何,正如Knut所说,您无法重写Domino的ACL角色设置。在整个应用程序的其他部分,您将无法依赖于您的代码。您必须将其更改为使用此sessionScope值。现在回过头来重新构建应用程序以避免使用ACL级角色,并在配置文档中为用户分配伪角色,这可能是合适的。 –

相关问题