Autenticação JHipster com um serviço externo
1. Introdução
Por padrão, os aplicativosJHipster usam um armazenamento de dados local para armazenar nomes de usuário e senhas. Em muitos cenários do mundo real, no entanto, pode ser desejável usar um serviço externo existente para autenticação.
Neste tutorial, veremos como usar um serviço externo para autenticação no JHipster. Pode ser qualquer serviço conhecido, como LDAP, login social ou qualquer serviço arbitrário que aceite um nome de usuário e senha.
2. Autenticação no JHipster
JHipster usaSpring Security para autenticação. The AuthenticationManager class is responsible for validating username and passwords.
OAuthenticationManager padrão no JHipster simplesmente verifica o nome de usuário e a senha em um armazenamento de dados local. Pode ser MySQL, PostgreSQL, MongoDB ou qualquer uma das alternativas suportadas pelo JHipster.
É importante observar quethe AuthenticationManager is only used for initial login. Depois que um usuário é autenticado, ele recebe um JSON Web Token (JWT) usado para chamadas de API subseqüentes.
2.1. Alterando a autenticação no JHipster
Mas e se já tivermos um armazenamento de dados que contenha nomes de usuário e senhas ou um serviço que faça autenticação para nós?
To provide a custom authentication scheme, we simply create a new bean of type AuthenticationManager. Isso terá precedência sobre a implementação padrão.
Abaixo está um exemplo que mostra como criar umAuthenticationManager personalizado. Ele possui apenas um método para implementar:
public class CustomAuthenticationManager implements AuthenticationManager {
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
try {
ResponseEntity response =
restTemplate.postForEntity(REMOTE_LOGIN_URL, loginRequest, LoginResponse.class);
if(response.getStatusCode().is2xxSuccessful()) {
String login = authentication.getPrincipal().toString();
User user = userService.getUserWithAuthoritiesByLogin(login)
.orElseGet(() -> userService.createUser(
createUserDTO(response.getBody(), authentication)));
return createAuthentication(authentication, user);
}
else {
throw new BadCredentialsException("Invalid username or password");
}
}
catch (Exception e) {
throw new AuthenticationServiceException("Failed to login", e);
}
}
}
Neste exemplo, passamos o nome de usuário e as credenciais do objetoAuthentication para uma API externa.
Se a chamada for bem-sucedida, retornamos um novoUsernamePasswordAuthenticationToken para indicar o sucesso. Observe quewe also create a local user entry, which we’ll discuss later on.
Se a chamada falhar, lançamossome variant of AuthenticationException para que o Spring Security retorne normalmente para nós.
Este exemplo é intencionalmente simples para mostrar o básico da autenticação personalizada. No entanto, ele pode executar operações mais complexas, como ligação e autenticação de LDAP ouuse OAuth.
3. outras considerações
Até agora, nos concentramos no fluxo de autenticação no JHipster. Mas existem várias outras áreas do nosso aplicativo JHipster que precisamos modificar.
3.1. Código Front-End
O código JHipster padrão implementa o seguinte processo de registro e ativação do usuário:
-
Um usuário se inscreve em uma conta usando seu e-mail e outros detalhes necessários
-
O JHipster cria uma conta e a define como inativa e envia um email para o novo usuário com um link de ativação
-
Ao clicar no link, a conta do usuário é marcada como ativa
Também existe um fluxo semelhante para redefinição de senha.
Tudo isso faz sentido quando o JHipster está gerenciando contas de usuário. Mas eles não são necessários quando contamos com um serviço externo para autenticação.
Therefore, we need to take steps to ensure these account management features are not accessible to the user.
Isso significa removê-los do código Angular ou React, dependendo da estrutura que está sendo usada no aplicativo JHipster.
Usando Angular como exemplo, o prompt de login padrão inclui links para redefinição e registro de senha. Devemos removê-los deapp/shared/login/login.component.html:
You don't have an account yet?
Register a new account
Também devemos remover os itens desnecessários do menu de navegação deapp/layouts/navbar/navbar.component.html:
and
Mesmo tendo removido todos os links,a user could still manually navigate to these pages. A etapa final é remover as rotas angulares não utilizadas deapp/account/account.route.ts.
Depois de fazer isso, apenas a rota de configurações deve permanecer:
import { settingsRoute } from './';
const ACCOUNT_ROUTES = [settingsRoute];
3.2. APIs Java
Na maioria dos casos, basta remover o código de gerenciamento de contas front-end. No entanto,to be absolutely sure the account management code is not invoked, we can also lock down the associated Java APIs.
A maneira mais rápida de fazer isso é atualizar a classeSecurityConfiguration para negar todas as solicitações aos URLs associados:
.antMatchers("/api/register").denyAll()
.antMatchers("/api/activate").denyAll()
.antMatchers("/api/account/reset-password/init").denyAll()
.antMatchers("/api/account/reset-password/finish").denyAll()
Isso impedirá qualquer acesso remoto às APIs, sem a necessidade de remover nenhum código.
3.3. Modelos de email
Os aplicativos JHipster vêm com um conjunto de modelos de email padrão para registro de conta, ativação e redefinição de senha. The previous steps will effectively prevent the default emails from being sent, mas em alguns casos, podemos querer reutilizá-los.
Por exemplo, podemos enviar um email de boas-vindas quando um usuário faz login pela primeira vez. O modelo padrão inclui etapas para a ativação da conta, por isso precisamos modificá-lo.
Todos os modelos de email estão localizados emresources/templates/mail. Eles são arquivos HTML que usamThymeleaf para passar dados do código Java para os emails.
Tudo o que precisamos fazer é editar o modelo para incluir o texto e layout desejados e, em seguida, usarMailService para enviá-lo.
3.4. Funções
Quando criamos a entrada do usuário JHipster local,we also have to take care to ensure it has at least one role. Normalmente, a função padrãoUSER é suficiente para novas contas.
Se o serviço externo fornecer seu próprio mapeamento de funções, teremos duas etapas adicionais:
-
Certifique-se de quaisquer funções personalizadasexist in JHipster
-
Atualize nossoAuthenticationManager personalizado para definir as funções personalizadas ao criar novos usuários
O JHipster também fornece uma interface de gerenciamento para adicionar e remover funções dos usuários.
3.5. Remoção de conta
É importante mencionar que o JHipster também fornece uma visualização de gerenciamento de remoção de conta e API. Essa visualização está disponível apenas para usuários administradores.
We could remove and restrict this code as we did for account registration and password reset, but it’s not really necessary. NossoAuthenticationManager personalizado sempre criará uma nova entrada de conta quando alguém fizer login, portanto, excluir a conta não adianta muito.
4. Conclusão
Neste tutorial, vimos como substituir o código de autenticação JHipster padrão por nosso próprio esquema de autenticação. Pode ser LDAP, OIDC ou qualquer outro serviço que aceite um nome de usuário e senha.
Também vimos que o uso de um serviço de autenticação externa também requer algumas alterações em outras áreas de nosso aplicativo JHipster. Isso inclui visualizações de front-end, APIs e muito mais.
Como sempre, o código de exemplo deste tutorial está disponívelover on GitHub.