Spring Boot, устанавливающий JsonView для AuthSuccess, меняет больше, чем я думаю - PullRequest
0 голосов
/ 27 сентября 2018

Я хочу иметь возможность включать некоторую информацию о сотрудниках в мой объект org.springframework.security.core.userdetails.User, поэтому я расширил класс User и добавил данные о сотрудниках.Все это работало хорошо, но затем я хотел ограничить данные из класса Employee только тем, что было необходимо для аспекта пользователя / авторизации.Чтобы сделать это, я внес изменения в свою реализацию обработчика успеха аутентификации.

Итак, вот часть моей конфигурации веб-безопасности:

@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()
            ...
    }
}

В обработчике успеха аутентификации я теперьhave:

@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, а затем указать, какие свойства я хочу вернуть, но это не выглядит ожидаемым поведением.

Почему изменение конфигурации сопоставления в обработчике успеха аутентификации оказывает влияниегде-либо еще?Какой самый лучший и простой способ справиться с этим?

...