当前位置: 首页 > 知识库问答 >
问题:

Spring Security MVC:相同的@请求映射,不同的@安全

东方琪
2023-03-14

假设我们有一个使用Spring MVC和Spring Security配置的APIendpoint。我们希望能够处理@RequestMapping和@Secured注释对,其中仅有的@Secured注释值因对而异。这样,我们就可以根据相同请求的安全规则返回不同的响应主体。

这可以避免在方法体中直接检查安全规则,从而使代码更易于维护。

有一个不起作用的例子,下面是我们想要做的:

@Controller
@RequestMapping("/api")
public class Controller {

    @Secured ({"ROLE_A"})
    @RequestMapping(value="{uid}", method=RequestMethod.GET)
    @ResponseBody
    public Response getSomething(@PathVariable("uid") String uid) {
        // Returns something for users having ROLE_A
    }

    @Secured ({"ROLE_B"})
    @RequestMapping(value="{uid}", method=RequestMethod.GET)
    @ResponseBody
    public Response getSomethingDifferent(@PathVariable("uid") String uid) {
        // Returns something different for users having ROLE_B
    }
}

我们如何才能做到这一点?如果可以做到这一点:对于一个既有ROLE_A又有ROLE_B的用户,应该如何管理优先级?

共有2个答案

微生青青
2023-03-14

我认为您不能在spring-mvc中做到这一点,因为两个路由具有完全相同的@Request estMap@Secure)没有被spring-mvc的路由引擎考虑在内。最简单的解决方案是这样做:

@Secured ({"ROLE_A", "ROLE_B"})
@RequestMapping(value="{uid}", method=RequestMethod.GET)
@ResponseBody
public Response getSomething(@PathVariable("uid") String uid, Principal p) {
    // Principal p gets injected by spring
    // and you need to cast it to check access roles.
    if (/* p.hasRole("ROLE_A") */) {
        return "responseForA";
    } else if (/* p.hasRole("ROLE_B") */) {
        return "responseForB";
    } else {
        // This is not really needed since @Secured guarantees that you don't get other role.
        return 403;
    }
}

但是,我会更改您的设计,因为每个角色的响应不同,为什么不使用两个不同URL的单独请求映射呢?如果在某个时候,您的用户同时具有角色A和角色B,则您不能让用户选择要获得的响应(例如,想想LinkedIn的公共和私人配置文件)

司寇苗宣
2023-03-14

假设您将Spring 3.1(或更高版本)与RequestMappingHandlerMapping(和RequestMappingHandlerAdapter)一起使用,您可以扩展请求映射机制。您可以通过创建自己的RequestCondition接口实现来实现这一点,并扩展RequestMappingHandlerMapping,以基于方法上的@安全注释来构建它。

您需要重写RequestMappingHandlerMapping上的“getCustomMethodCondition”方法,并基于该方法和@Secured注释的存在,构建RequestCondition的自定义实现。然后,在将传入请求与方法匹配时,会考虑所有这些信息。

相关答案(虽然不特定于@安全注释,但机制是相同的)也可以在这里或这里找到

 类似资料:
  • 我会从我想达到的目标开始 意图 该软件在for循环中解析XML数据。处理数据的 for 循环将持续到 50(因为我得到了 50 个不同的结果)。我最初所做的是,-方法解析整个XML数据并将其保存到TextViews中并显示它。但现在我想添加一个启动画面,只要数据加载就会显示。 XML文件像任何其他普通XML文件一样构建,因此当我通过for循环时,键总是相同的,但值不同。 方法 我已经做的是创建一个

  • 我的应用程序中有两个方法,它们使用相同的请求映射和不同的(http)方法 是否有可能在不同的控制器中定义它们,或者我应该考虑一些(可怕的)变通方法(比如重命名一个URL)?

  • 我正在微服务中做一些更改,它有一个像以下这样的对象: } 我将从Json中获取我将要使用的信息。Json有一个名为的键,我想在两个不同的变量中使用这个速率,一个int-rate和一个Float-ratePPR。这里的问题是,我知道在同一个对象中不能有来自同一个Json的两个变量,但我有义务这样做,因为我不能触摸变量,所以我创建了变量,以便在需要时使用。 当我进行测试时,会出现以下错误: 属性“ra

  • 问题内容: 我的table1和table2具有相同的架构…,我只想拥有一个实体,而不是两个(因为字段将是相同的)。在XML映射的hibernate状态下,我将如何实现这一点。所以我的目标是当我在DAO中进行查询时,如果两个表都映射到同一实体,它将如何知道要从哪个表中提取。 我试图不创建父类,然后再创建两个子类。 谢谢 问题答案: 抱歉回复晚了。我已经在stackoverflow上回答了几次这个问题

  • 当我测试一个控制器时,我发现下面的代码可以正常工作。但我不明白为什么模型在映射后返回后包含“PasspProperty”属性。PasspProperty类仅使用验证约束进行注释。在控制器中,它只在方法中使用@Valid annotation进行注释,如下面的代码所示。 我在控制器中有以下映射: 获取: 帖子: 我添加了以下测试和输出。如您所见,返回的ModelAndView包含未添加到@PostM