当前位置: 首页 > 知识库问答 >
问题:

Spring data rest:如何发布用户管理api

怀展
2023-03-14

是否可以公开一个spring数据rest生成的API来管理与Spring Security性一起用于身份验证和访问控制的相同用户?

考虑实体:

@Entity
public class User implements UserDetails {
   ....
}

与spring security一起使用的是:

@Service
public class RepositoryUserDetailsService implements UserDetailsService{

    private final UnsecuredUserRepository users;

    @Autowired
    public RepositoryUserDetailsService(UnsecuredUserRepository users) {
        this.users = users;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User one = users.findOne(username);
        if (one == null) {
            throw new UsernameNotFoundException("No such user");
        }
        return one;
    }

}

它使用以下spring数据存储库:

public interface UnsecuredUserRepository extends CrudRepository<User, String> {
}

我现在想要添加一个管理 API 来管理用户。Spring数据Rest可以为我做到这一点,我可以使用Spring安全性来保护它。

@PreAuthorize("hasRole('ROLE_USER_MANAGER')")
public interface UserRepository extends CrudRepository<User, String>, UserSignUpExtension {

    @Override
    @PreAuthorize("hasRole('ROLE_USER_MANAGER') or #userName == authentication?.name")
    void delete(@Param("userName") String userName);

}

问题是,使用spring data rest不能为相同的实体拥有多个存储库,使用安全的repo会产生一个鸡蛋问题,并阻止我拥有创建默认用户的启动代码(因为已经执行了安全检查)。

共有1个答案

子车俊哲
2023-03-14

我最终通过接受Spring Security性解决了这个问题,而不是试图绕过它。

我实现了这个实用程序:

import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;

public class AsInternalUser implements AutoCloseable {

    private final SecurityContext previousContext;

    public AsInternalUser() {
        previousContext = SecurityContextHolder.getContext();
        SecurityContext context = SecurityContextHolder.createEmptyContext();
        context.setAuthentication(
                new AnonymousAuthenticationToken("INTERNAL","INTERNAL_USERNAME", AuthorityUtils.createAuthorityList("ROLE_INTERNAL"))
        );
        SecurityContextHolder.setContext(
                context
        );
    }

    @Override
    public void close() {
        if (previousContext == null) {
            SecurityContextHolder.clearContext();
        } else {
            SecurityContextHolder.setContext(previousContext);
        }
    }
}

因此,我的初始用户创建变成:

try (AsInternalUser __ = new AsInternalUser()) {
            if (!users.exists(DEFAULT_ADMIN_NAME)) {
                users.save(new User(DEFAULT_ADMIN_NAME, passwordEncoder.encode(DEFAULT_ADMIN_PASSWORD), Arrays.asList(Roles.values())));
            }
        }

当然,存储库需要向新角色_INTERNAL授予访问权限

@PreAuthorize("hasAnyRole('ROLE_USER_MANAGER', 'ROLE_INTERNAL')")
public interface UserRepository extends CrudRepository<User, String>, UserSignUpExtension {
}

其他位置(如用户注册)也必须升级到内部角色。

我认为这比规避安全模型更好,因为它允许更精细的控制,并减少意外调用不安全存储库和损害安全性的机会。

 类似资料:
  • 一、简介 用于生成静态,更新URL等。 二、功能演示 批量更新栏目页 生成首页 批量更新URL 批量更新内容页

  • 一、简介 V9 系统内置的发布点功能结合站群功能,通过发布点可将各子站点内容发布到不同的服务器上,轻松实现服务器集群部署。以实现负载的分离,更加符合大访问量网站的需求。为用户提供更好的用户体验。示意图如下 二、功能演示 何时使用发布点: 当你想把各站点数据分布部署到不同的服务器上时使用发布点。 如何使用: 步骤一、添加发布点 (点击这里) 步骤二、添加站点时指定发布点 步骤三、添加站点时设置的域名

  • 一、简介 用于内容发布管理,发布管理以及内容相关设置的管理。 二、功能演示 管理内容 附件管理 专题 碎片管理 采集管理 批量更新栏目页 批量更新内容页 管理栏目 模型管理 类别管理 推荐位管理

  • 问题内容: 我需要能够从Go应用程序中管理Windows本地用户帐户,并且似乎没有使用CGo,就没有本机绑定。 我的最初搜索使人们说,最好使用“ exec.Command”运行“ net user”命令,但是在解析响应代码时,这似乎很混乱且不可靠。 我发现可以在netapi32.dll库中找到处理此类事件的函数,但是由于Go本身不支持Windows头文件,因此调用这些函数似乎并不容易。 以http

  • 在初次撰写本书时,都只讨论到了“物”,而没有关注“人”。而在实际使用中,Linux 系统首先是面向用户的系统,所有之前介绍的内容全部是提供给不同的用户使用的。实际使用中常常碰到各类用户操作,所以这里添加一个独立的章节来介绍。 Linux 支持多用户,也就是说允许不同的人使用同一个系统,每个人有一个属于自己的帐号。而且允许大家设置不同的认证密码,确保大家的私有信息得到保护。另外,为了确保整个系统的安

  • 本文档叙述了 Ceph 客户端的用户身份,及其与 Ceph 存储集群的认证和授权。用户可以是个人或系统角色(像应用程序),它们用 Ceph 客户端和 Ceph 服务器守护进程交互。 When Ceph runs with authentication and authorization enabled (enabled by default), you must specify a user na