Spring Security 结合 Spring 存储库来保护和验证网站的各个部分 [英] Spring Security in conjuction with Spring repositories to secure and authenticate various parts of a website

查看:39
本文介绍了Spring Security 结合 Spring 存储库来保护和验证网站的各个部分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一个具体、严肃和完整的示例,说明如何在使用 Spring 数据存储库 来访问数据库,从而查询注册用户.

I was looking for a concrete, serious and complete example on how to use Spring security in a Spring Boot application that uses Spring data repositories to access the database and therefore to query about registered users.

我已经看到,通过覆盖 configure 方法,它可以使用 Spring 安全性轻松保护一系列网页,例如使用以下选项:

I've seen that it's easily protected a range of webpages using Spring security by overriding the configure method, for example with the following options:

http.authorizeRequests()
    .antMatchers("/", "/css/**", "/js/**", "/vendor/**", "/templates/**")
    .permitAll()
    .anyRequest()
    .authenticated()
    .and()
    .formLogin()
    .loginPage("/login")
    .permitAll()
    .and()
    .logout()
    .permitAll();

此代码保护用户,例如访问 http://localhost:3000/home/users/,但允许随后访问 http://localhost:3000/login 或简单地 http://localhost:3000.

This code protects users for example from accessing http://localhost:3000/home/users/, but allows then to access http://localhost:3000/login or simply http://localhost:3000.

我一直在阅读有关 Spring 安全性的信息,但我不知道如何保护应用程序的不同部分,例如,当用户登录网站时,并禁止他从示例中访问http://localhost:3000/home/users/another_user,通常用于控制登录用户对网站所有部分的访问.

I've been reading around about Spring security, but I can't get how can I protect the different parts of an application, for example, when a user has logged in to the website, and prohibit him from accessing from example http://localhost:3000/home/users/another_user, and in general to control the access of a logged user to all parts of the website.

我正在使用 Spring 数据存储库 通过实体操作数据库的数据.

I'm using Spring data repositories to manipulate data of the database through the entities.

您是否知道将 Spring 安全性与 Spring 存储库(以及必要时的其他工具)结合使用来保护(和验证)网站的不同部分的示例?(视频)教程也可能有用.

Do you know about an example that uses Spring security in conjunction with Spring repositories (and if necessary other tools) to protect (and authenticate) different parts of a website? A (video-)tutorial may also be useful.

感谢您的帮助.

注意:我查看了 sagan 网站的存储库,但要理解发生了什么非常复杂......

Note: I've looked at the sagan website's repository, but it's quite complex to understand what's going on...

推荐答案

如上所述,ACL 是一种选择,但另一种可能更简单的解决方案可能是在方法级别应用安全性.

As noted above ACLs are one option however an alternative and possibly simpler solution may to be to apply security at the method level.

请参阅第 15.3 节.

See section 15.3.

https://docs.spring.io/spring-security/site/docs/3.0.x/reference/el-access.html

所以假设你有一个 URL/users/123 ,其中 123 是当前用户,它委托给服务层方法来加载用户,那么我该如何防止用户篡改 URL 并查看例如返回的数据./users/456.

So supposing you have an URL /users/123 where 123 is the current user and which delegates to a service layer method to load the user then how do I prevent the user from tampering with the URL and seeing data returned by e.g. /users/456.

一种方法是通过@PostAuthorize 注解应用方法级安全性:

One approach is to apply method level security via the @PostAuthorize annotation:

@PostAuthorize("hasPermission(returnObject, null)")
public User findById(Long id) {
    return repository.findOne(id);
}

安全检查委托给 org.springframework.security.access.PermissionEvaluator 的实现

The security checks are delegated to an implementation of org.springframework.security.access.PermissionEvaluator

实现可能如下所示:

public class BasePermissionsEvaluator implements PermissionEvaluator {

    public boolean hasPermission(Authentication authentication, Object domainObject) {
        return hasPermission(authentication, domainObject, null);
    }

    @Override
    public boolean hasPermission(Authentication authentication, Object domainObject, Object permission) {
        boolean hasPermission = true;

        //User is my custom class representing a logged in user
        //UserEntity is my custom interface implemented by entities associated with specific user
        //If user is an Admin allow access
        //Otherwise allow access if logged in user 'owns' the DomainObject instance
        User user = (User) authentication.getPrincipal();

        if(! user.isAdmin()){
            if (domainObject instanceof UserEntity) {
                User owner = ((UserEntity) domainObject).getOwner();
                hasPermission = user.equals(owner);
            }
        }

        return hasPermission;
    }

    @Override
    public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType,
            Object permission) {
        return false;
    }
}

PermissionEvaluator 的配置在 XML 中如下所示,因此您需要转换为 Java 配置:

Configuration of the PermissionEvaluator looks like the following in XML so you would need to convert to Java config:

<security:global-method-security
    pre-post-annotations="enabled">
        <security:expression-handler ref="expressionHandler"/>
</security:global-method-security>

<bean id="expressionHandler"
    class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">
    <property name="permissionEvaluator" ref="permissionEvaluator" />
</bean>

<bean id="permissionEvaluator" class="com.mycompany.BasePermissionsEvaluator" />

以下概述了将 XML 配置转换为 Java 配置:

The following outlines converting the XML config to Java config:

https://spring.io/blog/2013/07/04/spring-security-java-config-preview-method-security/#custom-method-security

因此,在您现有的安全配置类中,您应该添加:

So in your existing security configuration class it looks like you would add:

@EnableGlobalMethodSecurity(prePostEnabled=true) //ADD THIS
public class MySecurityConfig{

  @Override
  protected MethodSecurityExpressionHandler expressionHandler() {
    DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();

    //SET TO OUR CUSTOM PERMISSIONS HANDLER DETAILED ABOVE
    expressionHandler.setPermissionEvaluator(new BasePermissionsEvaluator());

    return expressionHandler;
  }
}

这篇关于Spring Security 结合 Spring 存储库来保护和验证网站的各个部分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆