package br.gov.servicos.editor.security; import br.gov.servicos.editor.conteudo.TipoPagina; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.dao.DaoAuthenticationProvider; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.web.authentication.AuthenticationSuccessHandler; import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint; import static br.gov.servicos.editor.security.TipoPermissao.*; import static java.lang.String.format; import static org.springframework.http.HttpMethod.*; @Configuration @EnableWebSecurity public class SecurityWebAppInitializer extends WebSecurityConfigurerAdapter { private static final String LOGIN_URL = "/editar/autenticar"; private static final String API_NOVO_USUARIO = "/editar/usuarios/usuario/**"; private static final String ADMIN = "ADMIN"; private static final String PONTOFOCAL = "PONTO_FOCAL"; private static final String PUBLICADOR = "PUBLICADOR"; private static final String EDITOR = "EDITOR"; private static final String API_DESPUBLICAR_PATTERN = "/editar/api/pagina/%s/*/despublicar"; private static final String API_DESCARTAR_PATTERN = "/editar/api/pagina/%s/*/descartar"; private static final String API_PAGINA_PATTERN = "/editar/api/pagina/%s/*"; private static final String API_NOVA_PAGINA_PATTERN = "/editar/api/pagina/%s/novo"; @Autowired private DaoAuthenticationProvider daoAuthenticationProvider; @Autowired private AuthenticationSuccessHandler successHandler; @Autowired private UserDetailsService editorUserDetailsService; @Override protected void configure(HttpSecurity http) throws Exception { CustomAccessDeniedHandler accessDeniedHandler = new CustomAccessDeniedHandler(); accessDeniedHandler.setErrorPage("/editar/acesso-negado"); HttpSecurity httpSecurityBuilder = http .httpBasic() .authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint(LOGIN_URL)) .and() .formLogin() .loginPage(LOGIN_URL) .successHandler(successHandler) .permitAll() .and() .logout() .logoutUrl("/editar/sair") .logoutSuccessUrl("/editar/autenticar?sair") .deleteCookies("JSESSIONID", "SESSION") .and() .authorizeRequests() .antMatchers("/editar/autenticar", "/editar/api/ping", "/editar/recuperar-senha", "/editar/acesso-cidadao").permitAll() .and(); // este laço irá adicionar todas as permissões específicas por página for (TipoPagina tipoPagina : TipoPagina.values()) { httpSecurityBuilder.authorizeRequests() .antMatchers(GET, urlParaTipoDePagina(API_NOVA_PAGINA_PATTERN, tipoPagina)) .hasAnyAuthority(CRIAR.comTipoPagina(tipoPagina), CRIAR.comTipoPaginaParaOrgaoEspecifico(tipoPagina)) .antMatchers(DELETE, urlParaTipoDePagina(API_PAGINA_PATTERN, tipoPagina)) .hasAnyAuthority(EXCLUIR.comTipoPagina(tipoPagina), EXCLUIR.comTipoPaginaParaOrgaoEspecifico(tipoPagina)) .antMatchers(PATCH, urlParaTipoDePagina(API_PAGINA_PATTERN, tipoPagina)) .hasAnyAuthority(CRIAR.comTipoPagina(tipoPagina), CRIAR.comTipoPaginaParaOrgaoEspecifico(tipoPagina)) .antMatchers(PUT, urlParaTipoDePagina(API_PAGINA_PATTERN, tipoPagina)) .hasAnyAuthority(PUBLICAR.comTipoPagina(tipoPagina), PUBLICAR.comTipoPaginaParaOrgaoEspecifico(tipoPagina)) .antMatchers(POST, urlParaTipoDePagina(API_PAGINA_PATTERN, tipoPagina)) .hasAnyAuthority(EDITAR_SALVAR.comTipoPagina(tipoPagina), EDITAR_SALVAR.comTipoPaginaParaOrgaoEspecifico(tipoPagina)) .antMatchers(POST, urlParaTipoDePagina(API_DESPUBLICAR_PATTERN, tipoPagina)) .hasAnyAuthority(DESPUBLICAR.comTipoPagina(tipoPagina), DESPUBLICAR.comTipoPaginaParaOrgaoEspecifico(tipoPagina)) .antMatchers(POST, urlParaTipoDePagina(API_DESCARTAR_PATTERN, tipoPagina)) .hasAnyAuthority(DESCARTAR.comTipoPagina(tipoPagina), DESCARTAR.comTipoPaginaParaOrgaoEspecifico(tipoPagina)) .and(); } httpSecurityBuilder.authorizeRequests() .antMatchers(GET, API_NOVO_USUARIO).hasAnyAuthority(CADASTRAR.comPapel(ADMIN), CADASTRAR.comPapel(PONTOFOCAL), CADASTRAR.comPapel(PUBLICADOR), CADASTRAR.comPapel(EDITOR)) .antMatchers(POST, API_NOVO_USUARIO).hasAnyAuthority(CADASTRAR.comPapel(ADMIN), CADASTRAR.comPapel(PONTOFOCAL), CADASTRAR.comPapel(PUBLICADOR), CADASTRAR.comPapel(EDITOR)) .anyRequest().fullyAuthenticated() .and() .exceptionHandling().accessDeniedHandler(accessDeniedHandler) .and() .sessionManagement() .invalidSessionUrl("/editar/autenticar?sessao"); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth .authenticationProvider(daoAuthenticationProvider) .userDetailsService(editorUserDetailsService); } private String urlParaTipoDePagina(String urlPattern, TipoPagina tipoPagina) { return format(urlPattern, tipoPagina.getNome()); } }