简体   繁体   English

如何使用Spring安全保护URL?

[英]How to secure URLs using Spring security?

I'm developing a web application using Spring MVC + Spring Security, and I have the following URLs: 我正在使用Spring MVC + Spring Security开发一个Web应用程序,我有以下URL:

/*this URL should be accessible by any User, i.e. users should be able to see other users' profiles*/
/users/someUserId/profile

/* all the following URLs should be accessed only by the current authenticated user */
/users/someUserId/profile/edit
/users/someUserId/picture/edit
/users/someUserId/notifications
/users/someUserId/friends

and I need them to be secured as previously described. 我需要它们如前所述得到保护。

My configure method goes as follows: 我的配置方法如下:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .authorizeRequests()
                .antMatchers("/resources/**").permitAll()
                .regexMatchers("/users/[\\w]+/profile").authenticated()
                .antMatchers("/users/[\\w]/**").access("principal.name == regexGroupMatch")
                .anyRequest().authenticated()               
            .and()
                .jee().mappableRoles("Admin", "User");
    }

I want to know if it's possible to achieve something like that: 我想知道是否有可能实现这样的目标:

.antMatchers("/heroes/[\\w]/**").access("principal.name == regexGroupMatch")

By doing this, I'm willing only the user user1 to be able to access the URLs: 通过这样做,我只愿用户user1能够访问URL:

/users/user1/profile/edit
/users/user1/picture/edit
/users/user1/notifications

So, user2 must not be able to access the previously mentioned URLs, but must be able to access: /users/user1/profile/edit /users/user1/picture/edit /users/user1/notifications 因此, user2必须无法访问之前提到的URL,但必须能够访问:/ users / user1 / profile / edit / users / user1 / picture / edit / users / user1 / notifications

As well as: 以及:

/users/user1/profile
/users/user2/profile
/users/user3/profile
etc...

Is it possible to achieve that using Spring Security? 是否可以使用Spring Security实现这一目标?

No, there's no functionality to extract matching groups in a regex and compare them to the username. 不,没有功能可以在正则表达式中提取匹配组并将它们与用户名进行比较。 Also, note that ant patterns don't support regex expressions at all. 另请注意,ant模式根本不支持regex表达式。

It's not a good idea to rely on complicated URL patterns in any case. 在任何情况下依赖复杂​​的URL模式都不是一个好主意。 For something like this you're best to use method security at the controller level or on some service interface, where you can refer to method parameters by name. 对于类似这样的事情,您最好在控制器级别或某些服务接口上使用方法安全性,您可以在其中按名称引用方法参数。 For example, with method security expressions enabled, you could write 例如,启用方法安全表达式后,您可以编写

@PreAuthorize("#user.name == authentication.name")
public void editUser(User user) {
  ....
}

Alternatively, as Misha says, you can just code the rule directly, which is preferable if things get more complicated than simple expressions. 或者,正如Misha所说,你可以直接编写规则,如果事情变得比简单表达式更复杂,那么这是更好的选择。

Spring Security will ensure that clients accessing those endpoints are authenticated, but it's up to you to make sure the endpoint only returns data that user is allowed to see. Spring Security将确保访问这些端点的客户端经过身份验证,但您需要确保端点仅返回允许用户查看的数据。 Think about it - how could Spring Security know what data in your application is permitted to be seen by each user? 想一想 - Spring Security如何知道每个用户可以看到应用程序中的哪些数据?

You probably already have a controller method that looks like this: 您可能已经有一个如下所示的控制器方法:

@RequestMapping(value = "/users/{user}/profile/edit", method = RequestMethod.GET)
public ModelAndView edit(
    HttpServletRequest request, 
    @PathVariable("user") String,
    EditRequest edit) {

    // Accept or reject the request if the user variable and authenticated
    // user match up as required.
}

Here, you need to programmatically distinguish the authenticated user (retrievable from the request object), and the user stated by the context. 在这里,您需要以编程方式区分经过身份验证的用户(可从请求对象检索)和上下文所声明的用户。 If the user in the context is the authenticated user, you might accept the request, since users are likely permitted to modify their own profiles. 如果上下文中的用户是经过身份验证的用户,则您可以接受该请求,因为可能允许用户修改他们自己的配置文件。 Otherwise, you can throw some sort of authorization exception - or better yet, return a nice view explaining why that page is inaccessible. 否则,您可以抛出某种授权异常 - 或者更好的是,返回一个很好的视图,解释为什么该页面不可访问。

Note that this can also be rewritten as a filter, since you aren't using any information in the body of the request. 请注意,这也可以重写为过滤器,因为您没有在请求正文中使用任何信息。 That filter would indeed plug into Spring Security. 该过滤器确实会插入Spring Security。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM