服务在可信空间中的网关之后工作(gateWay验证OAuth令牌,并仅向服务提供唯一的用户ID,否则它将重定向以验证服务)。
我希望在服务中使用Spring安全性,以便能够验证userId的权限。
所以我把CustomUserDetailsService
@Service("userDetailsService")
public class CustomUserDetailsService implements UserDetailsService {
@Autowired(required = false)
private ContextSsoActiveProfileIdProvider contextSsoActiveProfileIdProvider;
@Autowired
private GrantedAuthorityService grantedAuthorityService;
@Override
public User loadUserByUsername(final String username) throws UsernameNotFoundException {
// verify it with authentication service, but there is not token, userId only, so trust to gateway service.
return new User(
String.valueOf(contextSsoActiveProfileIdProvider.getSsoActiveProfileId()),
"authenticatedWithGateWay",
grantedAuthorityService.getGrantedAuthoritiesForCurrentUser()
);
}
}
其中,* contextSsoActiveProfileId提供者。getSsoActiveProfileId()* 返回唯一的用户ID,grantedAuthorityService。getGrantedAuthoritiesForCurrentUser() 返回授权。
该服务在受信任区域中启动,因此我已按以下方式配置了安全性:
@EnableWebSecurity
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/**").permitAll();
}
@Override
protected UserDetailsService userDetailsService() {
return userDetailsService;
}
}
我需要为所有用户提供免费访问所有URI(http.authorizeRequests().antMatchers("/**").permitAll();
)(不触发登录提供),但它似乎抑制了下一个注解@PreAuthorize
,@PreFilter
,@PostAuthorize
和@PostFilter
的触发处理程序。
我想我在这里把http.authorizeRequests().antMatchers("/**").permitAll();
或其他配置部分搞错了。
更多问题症状:
- 从不调用
CustomUserDetailsService.loadUserByUsername(..)
; - 在REST API部分
@AuthenticationPrincipal User activeUser
为空 - 在REST API上,
Principal principal
部分也为空
1条答案
按热度按时间xiozqbni1#
可信空间问题的解决方案与匿名用户身份识别类似(我在研究它时得出了这个结论)。
简短回答
信任空间不需要授权,但不会调用 UserDetailsService,因为默认情况下只使用
AnonymousAuthenticationProvider
和AnonymousAuthenticationFilter
。可以实现基于AnonymousAuthenticationFilter
覆盖createAuthentication
的自定义过滤器,并将默认过滤器(AnonymousAuthenticationFilter
)替换为自定义过滤器(CustomAnonymousAuthenticationFilter
):完整答案
我发现如果用户未授权,CustomUserDetailsService将永远不会被调用。继续研究时请注意AnonymousAuthenticationFilter,它负责创建匿名用户信息。因此,在非常和目的是用我的IdentifiableAnonymousAuthenticationFilter替换AnonymousAuthenticationFilter,其中一些方法应被覆盖:
将其注入到配置中
现在看起来好多了,因为 identifiableAnonymousAuthenticationFilter 被注入到了AnonymousConfigurer中。请注意您基于
WebSecurityConfigurerAdapter
的配置。如果您有几个配置,其中一个不会设置 customAnonymousAuthenticationFilter,而是在 *custom.. * 之前配置,您将获得 AnonymousAuthenticationFilter 的默认示例(默认情况下在WebSecurityConfigurerAdapter
中配置):如果应用程序已修复,我不会关心它,但AnonymousAuthenticationFilter调用时间早于IdentifiableAnonymousAuthenticationFilter,并且 doFilter 将SecurityContextHolder
incorrect
身份验证放入SecurityContextHolder因此,当下次为IdentifiableAnonymousAuthenticationFilter调用 doFilter 时,由于条件
if(SecurityContextHolder.getContext().getAuthentication() == null)
(请参见前面的方法),它不会替换Authentication
。因此,如果能够提供配置,其中使用magic annotation**@Order**修复
WebSecurityConfigurerAdapter
配置,以管理配置加载顺序,效果会非常好。警告
或者有人可能会想-在IdentifiableAnonymousAuthenticationFilter中添加
doFilter
覆盖而不带条件(它是hack):如果您需要处理授权/已验证用户的Spring安全性,则这是不可接受的,但在某些情况下,这已经足够了。
附言
解决方案的某些部分可以改进,但我希望这个想法总体上是清楚的。