Spring Boot:考虑到用户角色,谁来编写自定义预过滤器?



我需要某种@preFilter(或者,如果不可能超过@postFilter(来过滤我的REST API的结果。我不能使用preFilter注释,因为我需要考虑用户角色。我有三个不同的角色:

  • user普通用户,他们应该只访问他拥有的数据

  • teamleader此角色应访问其团队的所有数据

  • admin谁可以访问所有数据。

因为我们的数据库结构非常复杂,所以在我决定用户是否可以访问请求的数据或部分请求数据之前,有必要访问一些其他数据。

该代码段仅适用于角色useradmin。对于组长来说,它会更复杂,然后会有一堆masterDataId必须与or连接。

这里有一些伪代码,希望它不会混淆:

public class RoleFilter {
DimensionAttributeValueRepository dimensionAttributeValueRepository;

public void doFilter(Collection<AllDatas> data) {
if (user.getRole() != "admin") {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
DimensionAttributeValue tmpValue = dimensionAttributeValueRepository.findByChrValue(auth.getUsername());
MasterData masterData = tmpValue.getMasterData();
data.filter(data.masterDataId == masterData.getMasterDataID());
}
}
}

更新:示例

假设我有两个用户,用户 A 是角色为"用户"的普通用户。用户 B 是具有"管理员"角色的管理员。

有一个数据库表,其中存储userData。该表如下所示。

| ID | username | name | email |

他们都在向/userData发送一个简单的经过身份验证的GET请求。

现在,我的后端根据authentication标头检测用户并添加角色。

Nwo 根据角色的不同,用户 A 应该只获得包含其个人数据的 ansare,用户 B 应该获取通过/userData可以访问的所有数据。

对用户 A 的响应:

{
"res":[
{
"id":1,
"username":"userA",
"name":"A",
"email":"userA@mail.com"
}
]
}

对用户 B 的响应:

{
"res":[
{
"id":1,
"username":"userA",
"name":"A",
"email":"userA@mail.com"
},
{
"id":2,
"username":"userB",
"name":"B",
"email":"userB@mail.com"
},
{
"id":3,
"username":"userC",
"name":"C",
"email":"userC@mail.com"
}
]
}

对于您的用例,我建议使用自定义过滤器并将其集成到spring-security过滤器链中。这是一个教程,一般解释它。您可以配置自定义筛选器,以便它根据数据库检查您的复杂角色,然后用新对象覆盖当前用户身份验证对象。

实现示例:

public class CustomFilter extends GenericFilterBean {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
throws IOException, ServletException {
// HERE GOES YOUR CODE
// Depending on the extracted authentication details of the current user, you can now overwrite the users GrantedAuthorities
Collection<SimpleGrantedAuthority> oldAuthorities = (Collection<SimpleGrantedAuthority>)SecurityContextHolder.getContext().getAuthentication().getAuthorities();
SimpleGrantedAuthority authority = new SimpleGrantedAuthority("ROLE_TEAMLEADER");
List<SimpleGrantedAuthority> updatedAuthorities = new ArrayList<SimpleGrantedAuthority>();
updatedAuthorities.add(authority);
updatedAuthorities.addAll(oldAuthorities);
SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken(     
SecurityContextHolder.getContext().getAuthentication().getPrincipal(),      
SecurityContextHolder.getContext().getAuthentication().getCredentials(),
updatedAuthorities));
chain.doFilter(request, response);
}
}

之后,您可以使用以下语句检查您的角色:@PreAuthorize("hasRole('ROLE_TEAMLEADER')")

然后,您可以在spring-security-context对象的帮助下访问用户角色:SecurityContextHolder.getContext().getAuthentication().getAuthorities()

根据其结果,您现在可以根据此对象中存储的角色自定义答案。例如,您可以在/userData上实现如下所示的 RestCall:

@GetMapping("/userData")
public List<Object> getUserData() {
List<SimpleGrantedAuthority> roles = (List<SimpleGrantedAuthority>) SecurityContextHolder.getContext().getAuthentication().getAuthorities();
SimpleGrantedAuthority authorityTeamLeader = new SimpleGrantedAuthority("ROLE_TEAMLEADER");
List<Object> result = new ArrayList<>();
if (roles.contains(authorityTeamLeader)) {
result = getAllUsers();
} else {
result = getPersonalUser(roles);
}
return result;
}

相关内容

  • 没有找到相关文章

最新更新