1

我正在构建一个具有两种类型用户的应用程序:

  • 普通用户(具有角色“用户”)
  • 管理用户(具有“管理员”角色,但没有“用户”权限)

如何允许某人分别以用户和管理员身份登录/注销?

我使用两个 http 元素定义了两个领域(我有两个领域来允许单独的登录页面和用户数据库):

<security:http pattern="/admin/**" authentication-manager-ref="adminAuthManager"
    entry-point-ref="adminLoginUrlAuthEntryPoint" use-expressions="true">
    <security:intercept-url pattern="/admin/**" access="hasRole('admin')" />
    <security:access-denied-handler error-page="/admin/login" />
    <security:logout logout-url="/admin/logout" logout-success-url="/" />
    ...
</security:http>
<security:http pattern="/**" authentication-manager-ref="userAuthManager"
    entry-point-ref="userLoginUrlAuthEntryPoint" use-expressions="true">
    <security:intercept-url pattern="/**" access="permitAll" />
    <security:intercept-url pattern="/settings" access="hasRole('user')" />
    <security:access-denied-handler error-page="/login" />
    <security:logout logout-url="/logout" logout-success-url="/" />
    ...
</security:http>

使用当前设置,我无法允许单个会话同时成为经过身份验证的用户和经过身份验证的管理员。当某人在以管理员身份登录时以用户身份登录时,他/她的管理员身份验证将丢失(或被替换),反之亦然。

我曾考虑将这两个领域分成两个不同的网络应用程序,但如果可能的话,我不希望这样做。

编辑:这是我希望它如何工作的示例:

  1. 人员导航到站点,假设路径 / 对所有用户开放
  2. 人点击登录并在 /login 进行身份验证;人现在有角色“用户”
  3. 人员决定导航到 /admin/* 页面并显示 /admin/login 页面
  4. 个人在 /admin/login 处使用另一组凭据进行身份验证;人现在有角色“管理员”和“用户”
  5. 从服务器的角度来看,当用户在 /admin/** 页面时,用户的主体是他用于 /admin/login 的用户名;在 /** 页面上,用户的主体是他用于 /login 的用户名
  6. 人员完成管理活动并决定在 /admin/logout 退出他的管理会话;人失去了“管理员”角色,但留下了“用户”角色
  7. Person 最终决定退出用户角色并进入路径 /logout;这个人现在是匿名的

我希望这可以在不编写太多自定义功能的情况下实现。

4

1 回答 1

2

我不明白您为什么希望同一个人拥有两套凭据?这种情况通常使用递升式身份验证来实现,即用户始终相同,但在尝试访问应用程序的管理区域时会提示他重新进行身份验证。例如,您可能会提示他输入一些附加信息或使用双因素令牌进行身份验证。

过去,我使用自定义 AccessDecisionManager/Voter 实现了这一点,它检查用户是否试图访问站点的“更安全”区域,如果他没有正确的角色,则抛出InsufficientAuthenticationException 。然后入口点处理这个异常并提示用户重新认证和spring分配新角色

于 2012-04-19T20:07:02.000 回答