我希望能够在我的org.springframework.security.core.userdetails.User
对象中包含一些员工信息,因此我扩展了User
类并添加了员工数据。一切都很好,但是随后我想将Employee
类中的数据限制为仅用户/授权方面所需的数据。为此,我对身份验证成功处理程序实现进行了更改。
因此,这是我的Web安全配置的一部分:
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
@Override
public UserDetailsService userDetailsService() {
return new UserDetailsServiceImpl();
};
@Autowired
private AuthSuccessHandler authSuccessHandler;
@Autowired
private AuthLogoutSuccessHandler authLogoutSuccessHandler;
@Autowired
private AuthFailureHandler authFailureHandler;
@Autowired
private RestAuthenticationEntryPoint restAuthenticationEntryPoint;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.exceptionHandling()
.authenticationEntryPoint(restAuthenticationEntryPoint)
.and()
.formLogin()
.loginProcessingUrl("/api/dologin")
.usernameParameter("username").passwordParameter("password")
.successHandler(authSuccessHandler).failureHandler(authFailureHandler)
.and()
...
}
}
在身份验证成功处理程序中,我现在有:
@Component
public class AuthSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
private final ObjectMapper mapper;
AuthSuccessHandler(@Qualifier("mappingJackson2HttpMessageConverter") MappingJackson2HttpMessageConverter messageConverter) {
this.mapper = messageConverter.getObjectMapper().setConfig(messageConverter.getObjectMapper().getSerializationConfig().withView(View.LoginView.class));
// old mapper config: this.mapper = messageConverter.getObjectMapper();
}
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
response.setStatus(HttpServletResponse.SC_OK);
PrintWriter writer = response.getWriter();
mapper.writeValue(writer, authentication.getPrincipal());
writer.flush();
}
}
只需做一些工作(必须执行GrantedAuthority
的新实现,等等),我就只能获取成功登录后想要在JSON中查看的数据。
缺点是现在对于任何其他REST端点,我必须指定一些JsonView才能返回任何数据。它不必是LoginView,但必须具有某些内容,否则我只能将{}
作为任何端点的JSON。一旦在控制器(当然还有域对象)中指定了任何内容(@JsonView(View.Anything.class
),数据就会按预期显示。
但是,更糟糕的是,当我尝试检索java.security.Principal
信息时。我有一个RestController:
@RequestMapping("/api/user-principal")
public Principal user(Principal user) {
return user;
}
对于这个特定的端点,即使添加@JsonView注释也无济于事,大概是因为Principal
是一个接口,因此没有具有正确视图的属性。我可以创建自己的Principal实现,然后指定要返回的属性,但这似乎不是预期的行为。
为什么更改身份验证成功处理程序上的映射配置会在其他地方产生影响?最好,最简单的方法是什么?