【问题标题】:User Management for e-commerce电子商务用户管理
【发布时间】:2015-10-22 22:49:37
【问题描述】:

我目前正在开发一个电子商务应用程序。 该应用程序有不同的用户:

  1. 客户
  2. 商家
  3. 物流
  4. 管理员

当前的 db 结构对于这些用户类型中的每一个都有不同的表。我正在为基于 Java 的后端应用程序设置安全性。

我被困在如何实现这一点上。我创建了以下 spring-security 文件。

  1. 创建并注册了一个过滤器。(authenticationTokenProcessingFilter)
  2. 在过滤器类中,我检查请求 URL 以确定我应该使用哪个 DAO 来验证用户。

** spring-security.xml**

 <beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.2.xsd">
<security:http pattern="/rest/users/**" entry-point-ref="restAuthenticationEntryPoint"
    use-expressions="true" auto-config="false" create-session="stateless">
    <security:custom-filter ref="authenticationTokenProcessingFilter"
        position="PRE_AUTH_FILTER" />
    <security:intercept-url pattern="/rest/users/{userId}/orders/**"
        access="hasRole('ROLE_CUSTOMER','ROLE_ADMIN')" />
    <security:logout />
</security:http>

<security:http pattern="/rest/admin/**" entry-point-ref="restAuthenticationEntryPoint"
    use-expressions="true" auto-config="false" create-session="stateless">
    <security:custom-filter ref="authenticationAdminFilter"
        position="PRE_AUTH_FILTER" />
    <security:intercept-url pattern="/rest/admin/**"
        access="hasRole('ROLE_ADMIN')" />
    <security:logout />
</security:http>

<security:http pattern="/rest/business/**"
    entry-point-ref="restAuthenticationEntryPoint" use-expressions="true"
    auto-config="false" create-session="stateless">
    <security:custom-filter ref="authenticationTokenProcessingFilter"
        position="PRE_AUTH_FILTER" />
    <security:intercept-url pattern="/rest/business/{businessId}/orderItems**"
        access="hasRole('ROLE_MERCHANT')" />
    <security:logout />
</security:http>

<security:http pattern="/rest/merchant/**"
    entry-point-ref="restAuthenticationEntryPoint" use-expressions="true"
    auto-config="false" create-session="stateless">
    <security:custom-filter ref="authenticationTokenProcessingFilter"
        position="PRE_AUTH_FILTER" />
    <security:intercept-url pattern="/rest/merchant/**"
        access="hasRole('ROLE_MERCHANT_ADMIN')" />
    <security:logout />
</security:http>



<bean id="authenticationTokenProcessingFilter" class="com.resource.security.TokenAuthenticationFilter">
    <constructor-arg type="java.lang.String">
        <value>/rest/**</value>
    </constructor-arg>
</bean>


<bean id="restAuthenticationEntryPoint"
    class="com.resource.security.RestAuthenticationEntryPoint">
</bean>


<security:authentication-manager alias="authenticationManager" />

问题

  1. 如果一个特定的 URL 必须由两个角色调用,我不知道该怎么做,因为我只在过滤器中验证和分配一个角色。例如:管理员可以访问客户访问的任何网址。

【问题讨论】:

  • 只是一些建议:首先,我会考虑使用 java config 与 xml config,使用注释会让生活变得更轻松。您将在方法上放置这两种安全类型,并使用一些逻辑来确定哪个用户类型正在尝试访问系统的该部分,以便您的代码相应地采取行动。

标签: java spring authentication spring-security token


【解决方案1】:

与其使用多个表来管理多个用户,不如为所有人创建一个表,然后使用角色区分它们。使用 ROLE_CUSTOMER、ROLE_MERCHANT、ROLE_ADMIN 和 ROLE_LOGISTICS。然后你可以使用hasRole来定义谁可以访问什么URL。

如果我可以问,您为什么使用不同的表?除了重用用户名之外,我看不出有什么好处。

【讨论】:

  • 数据库结构是这样的,我无法将数据回填到单个表中。这就是我正在寻找解决这种情况的原因
  • 基于这 4 个表创建一个视图并在身份验证期间使用它进行查询是个好主意吗?
  • 尝试在表上使用联合来获得一个组合所有用户的表。您可以按照@user5118993 的建议将结果设为视图。然后对该表进行所有查询。这是我最想到的快速而肮脏的解决方案,但可能存在重复用户名之类的问题。