Login para um Spring Web App - Tratamento e localização de erros
1. Visão geral
Neste artigo, vamos ilustrar como implementara simple Login Page com Spring MVC para um aplicativo que está lidando com a autenticação com Spring Security no back-end.
Para obter os detalhes completos sobre como lidar com o login com Spring Security,here’s the article indo a fundo na configuração e implementação disso.
2. A página de login
Vamos começar definindoa very simple login page:
Login
Agora, vamos incluir uma verificação do lado do cliente para garantir queusernameepassword foram inseridos antes mesmo de enviarmos o formulário. Para este exemplo, usaremos Javascript simples, mas JQuery também é uma excelente opção:
Como você pode ver, simplesmente verificamos se os camposusername oupassword estão vazios; se estiverem - uma caixa de mensagem javascript aparecerá com a mensagem correspondente.
3. Localização de Mensagens
A seguir - vamos localizar as mensagens que estamos usando no front end. Existem tipos de mensagens e cada uma é localizada de uma maneira diferente:
-
Mensagens geradasbefore o formulário é processado pelos controladores ou manipuladores do Spring. Essas mensagens podem ser referenciadas nas páginas JSP e são localizadas comJsp/Jslt localization (consulte a Seção 4.3.)
-
Mensagens que são localizadas depois que uma página foi enviada para processamento pelo Spring (após o envio do formuláriologin); essas mensagens são localizadas usandoSpring MVC localization (consulte a seção 4.2.)
3.1. Os arquivosmessage.properties
Em ambos os casos, precisamos criar um arquivomessage.properties para cada idioma que desejamos oferecer suporte; os nomes dos arquivos devem seguir esta convenção:messages [localeCode] .properties_.
Por exemplo, se quisermos oferecer suporte a mensagens de erro em inglês e espanhol, teríamos o arquivo:messages_en.propertiesemessages_es_ES.properties. Observe que, para inglês -messages.properties também é válido.
Vamos colocar esses dois arquivos no classpath do projeto (src/main/resources). Os arquivos simplesmente contêm os códigos de erro e as mensagens que precisamos exibir em diferentes idiomas - por exemplo:
message.username=Username required
message.password=Password required
message.unauth=Unauthorized access!!
message.badCredentials=Invalid username or password
message.sessionExpired=Session timed out
message.logoutError=Sorry, error login out
message.logoutSucc=You logged out successfully
3.2. Configurando a localização Spring MVC
Spring MVC fornece umLocaleResolver que funciona em conjunto com sua APILocaleChangeInterceptor para tornar possível a exibição de mensagens em diferentes idiomas, dependendo da configuração local. Para configurar a localização - precisamos definir os seguintes beans em nossa configuração MVC:
@Override
public void addInterceptors(InterceptorRegistry registry) {
LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
localeChangeInterceptor.setParamName("lang");
registry.addInterceptor(localeChangeInterceptor);
}
@Bean
public LocaleResolver localeResolver() {
CookieLocaleResolver cookieLocaleResolver = new CookieLocaleResolver();
return cookieLocaleResolver;
}
@Bean
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource messageSource =
new ReloadableResourceBundleMessageSource();
messageSource.setBasename("classpath:messages");
messageSource.setUseCodeAsDefaultMessage(true);
messageSource.setDefaultEncoding("UTF-8");
messageSource.setCacheSeconds(0);
return messageSource;
}
Uma observação importante e mais avançada aqui é que precisamos ter certeza de quethe messageSource bean is defined in the right Spring context - o contexto em que será usado. Lembre-se de que o aplicativo Web possui o contexto raiz e, em seguida, possui um (ou mais) contextos de servlet.
Por padrão, o resolvedor de localidade obterá o código de localidade no cabeçalho HTTP. Para forçar uma localidade padrão, precisamos defini-la nolocaleResolver():
@Bean
public LocaleResolver localeResolver() {
CookieLocaleResolver cookieLocaleResolver = new CookieLocaleResolver();
cookieLocaleResolver.setDefaultLocale(Locale.ENGLISH);
return cookieLocaleResolver;
}
Este resolvedor de localidade é umCookieLocaleResolver, o que significa que ele armazena as informações de localidade em um cookie do lado do cliente; como tal - ele se lembrará da localidade do usuário sempre que ele fizer login e durante toda a visita.
Como alternativa, existe umSessionLocaleResolver, que lembra o local durante a sessão. Para usar esteLocaleResolver, precisamos substituir o método acima pelo seguinte:
@Bean
public LocaleResolver localeResolver() {
SessionLocaleResolver sessionLocaleResolver = new SessionLocaleResolver();
return sessionLocaleResolver;
}
Por último, observe queLocaleChangeInterceptor mudará o local com base no valor de um parâmetrolang enviado com a página de login por links simples:
3.3. JSP/JSLT Localization
JSP/JSLT API will be used to display localized messages that are caught in the jsp page itself. Para usar as bibliotecas de localização jsp, devemos adicionar as seguintes dependências aopom.xml:
javax.servlet.jsp
javax.servlet.jsp-api
2.3.2-b01
javax.servlet
jstl
1.2
4. Exibindo Mensagens de Erro
4.1. Erros de validação de login
Para usar o suporte JSP / JSTL e exibir mensagens localizadas nologin.jsp, permite implementar as seguintes mudanças na página:
1. Adicione o seguinte elemento de tag lib aologin.jsp:
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
2. Adicione o elemento jsp / jslt que apontará para os arquivosmessages.properties:
3. Adicione os seguintes elementos<fmt:…> para armazenar as mensagens nas variáveis jsp:
4. Modifique o script de validação de login que vimos na Seção 3, para localizar as mensagens de erro:
4.2. Erros de pré-login
Às vezes, a página de login recebe um parâmetro de erro se a operação anterior falhar. Por exemplo, um botão de envio do formulário de registro carregará a página de login. Se o registro foi bem-sucedido, seria uma boa idéia mostrar uma mensagem de sucesso no formulário de login e uma mensagem de erro se o contrário fosse verdadeiro.
No formuláriologin de amostra abaixo, estamos implementando isso interceptando os parâmetros eregSucceregError e exibindo uma mensagem localizada com base em seus valores.
4.3. Erros de segurança de login
Caso o processo de login falhe por algum motivo, Spring Security fará um redirecionamento para uma URL de erro de login, que definimos como/login.html?error=true.
Portanto, da mesma forma que mostramos o status do registro na página, precisamos fazer o mesmo no caso de um problema de login:
Observe que estamos usando um elemento<spring:message …>. Isso significa que as mensagens de erro são geradas durante o processamento do Spring MVC.
A página de login completa - incluindo a validação de js e essas mensagens de status adicionais pode ser encontrada emgithub project.
4.4. Erros de logout
No exemplo a seguir, o código jsp<c:if test=”$\{not empty SPRING_SECURITY_LAST_EXCEPTION}”> na páginalogout.html verificará se houve um erro no processo de logout.
Por exemplo - se houver uma exceção de persistência quando um manipulador de logout personalizado tentar armazenar dados do usuário antes de redirecionar para a página de logout. Embora esses erros sejam raros, devemos resolvê-los da maneira mais clara possível.
Vamos dar uma olhada nologout.jsp completo:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="sec"
uri="http://www.springframework.org/security/tags"%>
<%@taglib uri="http://www.springframework.org/tags" prefix="spring"%>
Logged Out
Login
Observe que a página de logout também lê o parâmetro de string de consultalogSucc, e se seu valor for igual atrue, uma mensagem de sucesso localizada será exibida.
5. A configuração de segurança Spring
O foco deste artigo é o front-end do processo de login, não o back-end - então, veremos apenas brevemente os pontos principais da configuração de segurança; para a configuração completa, você deve ler oprevious article.
5.1. Redirecionando para o URL de erro de login
A seguinte diretiva no elemento<form-login…/> direciona o fluxo do aplicativo para o url onde o erro de login será tratado:
authentication-failure-url="/login.html?error=true"
5.2. O redirecionamento de sucesso de logout
O atributologout-success-url simplesmente redireciona para a página de logoff com um parâmetro que confirma que o logoff foi bem-sucedido.
6. Conclusão
Neste artigo, ilustramos como implementar uma página de login para um aplicativo suportado pelo Spring Security - lidando com a validação de login, exibindo erros de autenticação e localização de mensagens.
Veremos uma implementação de registro completa no próximo artigo - com o objetivo de ter uma implementação completa do processo de login e registro pronto para produção.