gpt4 book ai didi

java - Spring 数据休息: How to publish a user management api

转载 作者:行者123 更新时间:2023-11-30 07:04:35 27 4
gpt4 key购买 nike

是否可以公开 Spring Data 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 data Rest 可以为我做到这一点,并且我可以使用 spring security 来保护它。

@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);

}

问题是一个人不能拥有 multiple repositories for the same entities with spring data rest ,使用安全的存储库会产生先有鸡还是先有蛋的问题,并阻止我使用创建默认用户的启动代码(因为安全检查已经强制执行)。

最佳答案

我最终通过拥抱 Spring 安全性而不是试图规避它来解决这个问题。

我实现了这个实用程序:

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())));
}
}

当然,存储库需要授予对新 ROLE_INTERNAL 的访问权限

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

用户注册等其他地方也必须升级为内部角色。

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

关于java - Spring 数据休息: How to publish a user management api,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40367131/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com