Login para um Spring Web App - Tratamento e localização de erros

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

User:
Password:

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:

  1. 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.)

  2. 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.