Spring boot 我是否可以基于来自控制器方法的一些信息,使用Spring security为端点实现授权/筛选?
我有一个控制器方法,看起来像这样Spring boot 我是否可以基于来自控制器方法的一些信息,使用Spring security为端点实现授权/筛选?,spring-boot,spring-security,Spring Boot,Spring Security,我有一个控制器方法,看起来像这样 @GetMapping public ResponseEntity<String> getInformation(@PathVariable("id") String id, InternalAuthInfo info) { // do something return new ResponseEntity(value, HttpStatus.OK); } @GetMapping 公共响应属性getInformation(@PathVari
@GetMapping
public ResponseEntity<String> getInformation(@PathVariable("id") String id, InternalAuthInfo info) {
// do something
return new ResponseEntity(value, HttpStatus.OK);
}
@GetMapping
公共响应属性getInformation(@PathVariable(“id”)字符串id,InternalAuthInfo信息){
//做点什么
返回新的ResponseEntity(值,HttpStatus.OK);
}
我想做的是根据InternalAuthInfo信息对象的信息过滤/授权一些get调用,我不想在控制器内部实现过滤逻辑
我是否可以使用spring security实现此功能?您可以为api用户分配一个角色,然后在控制器中使用@PreAuthorize注释
@GetMapping
@PreAuthorize("hasRole(ALLOWED_ROLE')")
public ResponseEntity<String> getInformation(@PathVariable("id") String id, InternalAuthInfo info) {
// do something
return new ResponseEntity(value, HttpStatus.OK);
}
@GetMapping
@预授权(“hasRole(允许的角色”))
公共响应属性getInformation(@PathVariable(“id”)字符串id,InternalAuthInfo信息){
//做点什么
返回新的ResponseEntity(值,HttpStatus.OK);
}
参考资料:这实际上取决于您想要的复杂程度,但让我们简单地开始 在SpringSecurity中,有用于检索用户和用户权限的服务API。例如
UserDetailsService
。一般来说,如果您试图从数据库中获取用户,例如基于用户名,那么这是一个很好的选择。这也是Spring Security默认选择用于用户名/密码身份验证的API
因此,您可以创建一个委托UserDetailsService
,如下所示:
public class InternalAuthInfoUserDetailsService implements UserDetailsService {
UserDetailsService delegate = new JdbcUserDetailsManager();
public UserDetails loadUserByUsername(String username) {
User user = this.delegate.loadUserByUsername(username);
InternalAuthInfo info = myWayToLookThisUp(username);
Collection<GrantedAuthority> roles = myWayToMapInfo(info);
return new User(user.getUsername(), user.getPassword(), roles);
}
}
这种方法的思想是将详细信息从InternalAuthInfo
映射到您将决定的各种授权角色,如ROLE\u USER
。此时,有两种受支持的过滤方法:
@PreAuthorize("hasRole('USER')")
@GetMapping(...
正如另一张海报所说,这是一个非常简单的方法
或者,如果要将InternalAuthInfo
实例作为用户主体的一部分进行维护,则可以在自定义UserDetailsService
中创建桥接对象:
@Bean
UserDetailsService userDetailsService() {
return new InternalAuthInfoUserDetailsService();
}
public class InternalAuthInfoUserDetailsService
implements UserDetailsService {
UserDetailsService delegate = new JdbcUserDetailsManager();
public UserDetails loadUserByUsername(String username) {
User user = this.delegate.loadUserByUsername(username);
InternalAuthInfo info = myWayToLookThisUp(username);
return new MyUser(info, user);
}
private static class MyUser extends InternalAuthInfo
implements UserDetails {
private final UserDetails delegate;
public MyUser(InternalAuthInfo info, UserDetails user) {
super(info);
this.delegate = user;
}
// ... delegate methods
}
}
其余的接线是一样的,但用法有点不同
通过此设置,您可以直接在授权表达式中引用InternalAuthInfo
:
@PreAuthorize("principal?.someAuthInfoProperty == 'some-value'")
@GetMapping(...
其中,我假设InternalAuthInfo
具有类似于getSomeAuthInfoProperty
的方法
顺便说一句,UserDetailsService
通常假定一组特定的数据库表和列。因此,您可能会有一个利用Spring Data JPA之类的实现:
public class InternalAuthInfoUserDetailsService
implements UserDetailsService {
@Autowired
private InternalAuthInfoRepository repository;
@Override
public User loadUserByUsername(String username) {
InternalAuthInfo info = this.repository.findByUsername(username);
return new MyInternalAuthInfoUser(info);
}
}
但是,这里我们开始对您的设置进行其他假设
这里的要点是你可以
userdetails服务
,将InternalAuthInfo
转换为一组GrantedAuthority
s-这些将成为身份验证#getAuthority
UserDetailsService
,将Spring Security的User
域对象和InternalAuthInfo
对象连接起来-这些将成为Authentication\getPrincipal
InternalAuthInfo
的一个实例,用于更复杂的检查
最后,这不完全是您的问题,但我想指出,用户可以在方法级授权和过滤器级授权之间进行选择。它们各有优缺点,但我建议大家看一下,因为你可以用表达式来描述整个应用程序的规则,而不是逐个方法。我在这里一个接一个地使用这个方法只是为了便于演示。谢谢您的回答@fctmolina。但是如何将信息从InternalAuthInfo传递到我的过滤器类?这就是我正在努力解决的问题。