Como faço para retornar um 403 Forbidden no Spring MVC?
Pergunta
Quero que meu controlador retorne o código de resposta HTTP correto quando o usuário não tiver permissão para visualizar uma página específica.
Solução
Rápidinha
Se você estiver usando visualizações JSP simples (como é mais comum), basta adicionar
<% response.setStatus( 403 ); %>
em algum lugar no seu arquivo de visualização.No topo há um lugar agradável.
Detalhe
No MVC, eu sempre definiria isso na visualização e, na maioria dos casos, com Spring-MVC, usaria o SimpleMappingExceptionResolver
para apresentar a visualização correta em resposta a uma exceção de tempo de execução lançada.
Por exemplo:crie e lance um PermissionDeniedException
em seu controlador ou camada de serviço e faça com que o resolvedor de exceção aponte para um arquivo de visualização permissionDenied.jsp
.Este arquivo de visualização define o status 403 e mostra ao usuário uma mensagem apropriada.
No seu arquivo XML do Spring Bean:
<bean id="exceptionResolver"
class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="PermissionDeniedException">
rescues/permissionDenied
</prop>
... set other exception/view mappings as <prop>s here ...
</props>
</property>
<property name="defaultErrorView" value="rescues/general" />
</bean>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
Se você precisar implementar um mecanismo de login de usuário, dê uma olhada em Segurança Primavera (anteriormente Acegi Segurança).
Outras dicas
Você também pode simplesmente jogar
org.springframework.security.access.AccessDeniedException("403 returned");
Isso retorna um 403 no cabeçalho de resposta.
Crie uma exceção anotada com @ResponseStatus por exemplo.assim:
@ResponseStatus(HttpStatus.FORBIDDEN)
public class ForbiddenException extends RuntimeException {
}
Agora basta lançar essa exceção no seu método manipulador e a resposta terá o status 403.
Usando um ExceptionResolver
é uma ótima opção, mas se você quiser apenas que seja independente da visualização, certamente poderá ligar para response.sendError(HttpServletResponse.SC_FORBIDDEN, "AdditionalInformationIfAvailable");
em seu controlador.
Usa isto:response.setStatus(403)
.