Spring Boot:根据用户角色自定义 API 响应

Tar*_*Ali 3 java spring json spring-security spring-boot

我想Authorizations在我的控制器\xe2\x80\x99s 上应用一些逻辑Methods\n我有一个名为的端点,该端点Interview 具有 findInterviewById(id)返回对象的方法Interview

\n

该应用程序拥有不同的用户[所有者招聘人员候选人访客]

\n

每个人都可以访问 findInterviewById(id) 来读取 Interview 对象,并使用 createInterview(Interview) 方法来创建采访,但每个人都必须根据自己的角色以限制模式读取或写入该对象

\n

例子

\n
    \n
  • 招聘人员:可以读取招聘人员返回的整个面试对象findInterviewById(id)
  • \n
  • Guest:应该只读取由访问者返回的采访对象中的一些字段findInterviewById(id)
  • \n
\n

方法也是一样createInterview(Interview),招聘人员可以触及面试的所有领域,但候选人可以触及某些领域

\n

一些解决方案表示您可以复制端点,但它\xe2\x80\x99对于大型应用程序来说不是最佳实践

\n

我如何实现这个特定的授权逻辑来实现这种行为

\n

Pat*_*mil 6

您可以@JsonSerialize根据用户的权限使用和实现所需的 JSON 响应serialize(Interview interview, JsonGenerator jgen, SerializerProvider provider)

例子

考虑负责显示用户列表的 UserDTO 类。你必须使用@JsonSerialize(using = CustomSerializer.class)在 DTO 或域的类级别使用。

DTO/模态

@JsonSerialize(using = UserDTOSerializer.class)
public class UserDTO {

    private Long id;

    @NotBlank
    @Pattern(regexp = Constants.LOGIN_REGEX)
    @Size(min = 1, max = 50)
    private String login;

    @Size(max = 50)
    private String firstName;

    @Size(max = 50)
    private String lastName;

    @Email
    @Size(min = 5, max = 254)
    private String email;

    @Size(max = 256)
    private String imageUrl;

    private boolean activated = false;

    //getter-setters and constructors
}
Run Code Online (Sandbox Code Playgroud)

自定义序列化器

现在让我们通过serialize()方法实现自定义序列化器@Override它内部您可以从安全上下文获取权限并自定义响应,如下所示

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import com.learning.jhipster.security.AuthoritiesConstants;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

import java.io.IOException;

@Component
public class UserDTOSerializer extends StdSerializer<UserDTO> {

    public UserDTOSerializer() {
        this(null);
    }

    public UserDTOSerializer(Class<UserDTO> t) {
        super(t);
    }

    @Override
    public void serialize(UserDTO user, JsonGenerator jgen, SerializerProvider provider) throws IOException {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        jgen.writeStartObject();
        if(authentication.getAuthorities().toString().contains(AuthoritiesConstants.ADMIN)) {
            jgen.writeNumberField("id", user.getId());
            jgen.writeStringField("login", user.getLogin());
            jgen.writeBooleanField("activated", user.isActivated());
            jgen.writeStringField("imageUrl", user.getImageUrl());
        }
        jgen.writeStringField("firstName", user.getFirstName());
        jgen.writeStringField("lastName", user.getLastName());
        jgen.writeStringField("email", user.getEmail());
        jgen.writeEndObject();
    }
}
Run Code Online (Sandbox Code Playgroud)

回复

以ROLE_USER权限登录的用户将得到以下响应

[
    {
        "firstName": "User",
        "lastName": "User",
        "email": "user@localhost"
    }
]
Run Code Online (Sandbox Code Playgroud)

以ROLE_ADMIN身份登录的用户将收到以下响应

[
    {
        "id": 1,
        "login": "system",
        "activated": true,
        "imageUrl": "",
        "firstName": "System",
        "lastName": "System",
        "email": "system@localhost"
    }
]
Run Code Online (Sandbox Code Playgroud)