【问题标题】:Spring Boot JPA - the filter of the mapping is ignoredSpring Boot JPA - 映射的过滤器被忽略
【发布时间】:2018-07-12 22:56:54
【问题描述】:

我找不到我的问题的解决方案。

问题: 我有 2 张桌子。在第一个表中保存项目。 第二个表存储允许哪个用户访问项目。

我现在想要一份所有项目的清单。但仅限于那些在 api__us​​er_permissions_mn 至少存在一个条目。

在 SQL 中它看起来像这样:

从项目中选择 * INNER JOIN api__us​​er_permissions_mn 开启(api__us​​er_permissions_mn.user_id = 35 AND api__us​​er_permissions_mn.projekt_id = projekte.ID);

我的第一个问题是,必须从 OAuth 登录中读取 UserID (api__us​​er_permissions_mn.user_id = 35),过滤器指的是当前用户!

我的第二个问题似乎是我没有使项目和权限之间的联系正确。

在我的测试用例(用户 ID 35)中,我有 1 个具有 2 个权限的项目 我回到 1 Projekt 并拥有数据库的所有权限。

用户 ID 上的过滤器似乎不起作用,否则将被忽略!

"apiUserPermissions": [
            {
                "mappingId": {
                    "userID": 114,
                    "permissionID": 9,
                    "projectID": 0
                }
            },
            {
                "mappingId": {
                    "userID": 103,
                    "permissionID": 9,
                    "projectID": 0
                }
            },
            {
                "mappingId": {
                    "userID": 4,
                    "permissionID": 10,
                    "projectID": 0
                }
            },
            {
                "mappingId": {
                    "userID": 41,
                    "permissionID": 13,
                    "projectID": 0
                }
            },

项目模型:

package com.microservice.api.models;

import java.sql.Date;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;

import org.junit.Ignore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.repository.Query;
import org.springframework.security.core.annotation.AuthenticationPrincipal;

import com.microservice.api.repository.ApiUserPermissionsRepository;

import net.bytebuddy.implementation.bind.annotation.IgnoreForBinding;


@Entity
@Table(name = "projekte")
public class ProjectModel 
{

    private static final Logger logger = LoggerFactory.getLogger(ProjectModel.class);

    @Id
    @NotNull
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "ID",  nullable = false)
    private int projectID;

    @NotNull
    @Column(name = "name",  nullable = false)
    private String  name;


    @OneToMany(mappedBy = "mappingId.projectID" , cascade = CascadeType.ALL)
    private Set<ApiUserPermissionsModel> apiUserPermissions = new HashSet<ApiUserPermissionsModel>();

    public int getProjectID() 
    {
        return projectID;
    }

    /**
     * <b>set the project ID</b>
     * 
     * @param id
     */
    public void setProjectID(int id) 
    {
        this.projectID = id;
    }

    /**
     * <b>get the name of the project</b>
     * 
     * @return project name
     */
    public String getName() 
    {
        return name;
    }

    /**
     * <b>set the project name</b>
     * 
     * @param name
     */
    public void setName(String name) 
    {
        this.name = name;
    }

    public Set<ApiUserPermissionsModel> getApiUserPermissions() {
        return apiUserPermissions;
    }

    public void setApiUserPermissions(Set<ApiUserPermissionsModel> apiUserPermissions) {
        this.apiUserPermissions = apiUserPermissions;
    }

}

apiUserPermissions 模型

package com.microservice.api.models;

import java.io.Serializable;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.repository.query.Param;


@Entity
@Table(name = "api__user_permissions_mn")
public class ApiUserPermissionsModel
{
    private static final Logger logger = LoggerFactory.getLogger(ApiUserPermissionsModel.class);

    @EmbeddedId
    private PermissionMappingId mappingId;

    public PermissionMappingId getMappingId() {
        return mappingId;
    }

    public void setMappingId(PermissionMappingId mappingId) 
    {
        this.mappingId = mappingId;
    }

    @Embeddable
    public static class PermissionMappingId implements Serializable
    {
        //@Id
        @Column(name = "user_id",  nullable = false)
        private long userID ;
        //@Id
        @Column(name = "permission_id",  nullable = false)
        private long permissionID ;
        //@Id

        @Column(name = "projekt_id",  nullable = false)
        private long projectID;

        public long getUserID() {
            return userID;
        }
        public void setUserID(long userID) {
            this.userID = userID;
        }
        public long getPermissionID() {
            return permissionID;
        }
        public void setPermissionID(long permissionID) {
            this.permissionID = permissionID;
        }
        @ManyToOne
        @JoinColumn(name = "projectID")
        public long getProjectID() {
            return projectID;
        }
        public void setProjectID(long projectID) {
            this.projectID = projectID;
        }
    }


}

**user.getId()**

这工作正常,但查询不起作用! 我已经调试过了,正确的 ID 正在传入 (35) !!!

项目负责人:

package com.microservice.api.controller;

import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.microservice.api.models.ApiUserModel;
import com.microservice.api.models.ProjectModel;
import com.microservice.api.repository.ProjectRepository;

import io.swagger.annotations.ApiOperation;

@RestController
@RequestMapping("/projects")
public class ProjectController 
{

    @Autowired
    private ProjectRepository projectDAO;

    @RequestMapping(value = "/", method = RequestMethod.GET)
    @ApiOperation(value = "finds all projects for the current user",
    notes = "Only those projects are returned for which the current user is "
          + "also activated. Returns an empty list for users without project "
          + "assignment.",
    response = ProjectModel.class,
    responseContainer = "List")
    public Set<ProjectModel> getPojectsForCurrentUser(@AuthenticationPrincipal ApiUserModel user)
    {
        Set<ProjectModel> projectM = projectDAO.findByApiUserPermissions_mappingid_UserID(user.getId());
        return projectM;
    }
}

最后, 项目存储库

package com.microservice.api.repository;

import java.util.Set;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Transactional;
import com.microservice.api.models.ProjectModel;

@Transactional
public interface ProjectRepository extends JpaRepository<ProjectModel, Long>
{
    @Query("SELECT p FROM ProjectModel p JOIN p.apiUserPermissions aup WHERE aup.mappingId.userID = :uid") 
    Set<ProjectModel> findByApiUserPermissions_mappingid_UserID(@Param("uid") long uid);
}

我真的尝试了很多东西。 我还阅读了很多关于 Hibernate、JPA 和 Spring Boot 的内容,但我没有找到解决问题的方法。 你能告诉我我做错了什么吗?

提前致谢

【问题讨论】:

    标签: java web-services jpa spring-boot hibernate-mapping


    【解决方案1】:

    您应该首先在您的自定义 UserDetailsS​​ervice 类中实现 UserDetailsS​​ervice 并覆盖

    public UserDetails loadUserByUsername(String username) 
    

    方法应该返回您保存用户对象的自定义用户类。

    之后你应该在你的配置实现类中注册这个 UserDetailsS​​ervice 实现,该类实现 AuthorizationServerConfigurerAdapter 为

     @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
            endpoints.authenticationManager(authenticationManager).userDetailsService(userDetailsService);
        }
    

    获取当前用户ID, 你可以从:

    Authentication authentication =SecurityContextHolder.getContext().getAuthentication());
    User currentUser=(User) authentication.getPrincipal()
    long id=currentUser.getId();
    

    另外你应该注意我这里使用的 User 类必须实现 UserDetails 接口,你应该把它放到你的主体

    我不明白第二个问题,但对于第一个问题,您可以通过添加启用事前授权 @EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true) 对您的配置和存储库中的方法的注释:

    这里我假设你的委托人有 id 属性来获取当前用户 ID:

    @PreAuthorize("#uid == authentication.principal.id")
    Set<ProjectModel> findByApiUserPermissions_mappingid_UserID(@Param("uid") long uid);
    

    【讨论】:

    • 很遗憾,我不能说我在映射模型时是否犯了错误,或者查询是否错误。
    猜你喜欢
    • 2021-11-04
    • 2017-09-30
    • 2014-10-06
    • 1970-01-01
    • 2021-11-28
    • 2018-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多