estou tentando implementar uma api usando spring boot e spring security, consegui fazer a autenticação de acesso co login e senha, no entanto, apos conseguir acesso não consigo fazer a busca por dados no banco, o navegador alega acesso negado, alguém poderia me ajudar com esse problema??
bom dia Lucas! eu acabei observando que na minha classe
br.com.alexdeveloper.springrestapi.security.JWTTokenAutenticacaoService
dentro do método de pegar a autenticação, getAuthentication o token esta vindo nulo, na hora que faço a minha consulta depois de ter logado, não consegui entender o porque disso esta ocorrendo, consegue me ajudar?
Lucas, como eu ainda estou estudando sobre o assunto, acabo tendo alguns problemas no entendimento. mas acredito que faço esse envio no método addAuthentication. dentro da classe JWTTokenAutenticacaoService
@Service @Component
public class JWTTokenAutenticacaoService {
// Senha única para compor a autenticação e ajudar na segurança
private static final String SECRET = "SenhaExtremamenteSecreta";
// Prefixo padrão de Token
private static final String TOKEN_PREFIX = "Bearer";
private static final String HEADER_STRING = "Authorization";
// Gerando token de autenticação e adicionando ao cabeçalho e resposta Http
/*Gerando token de autenticado e adiconando ao cabeçalho e resposta Http*/
public void addAuthentication(HttpServletResponse response , String username) throws IOException {
liberacaoCors(response);
/*Montagem do Token*/
String JWT = Jwts.builder() /*Chama o gerador de Token*/
.setSubject(username) /*Adicona o usuario*/
.signWith(SignatureAlgorithm.HS512, SECRET).compact(); /*Compactação e algoritmos de geração de senha*/
/*Junta token com o prefixo*/
String token = JWT; /*Bearer 87878we8we787w8e78w78e78w7e87w*/
/*Adiciona no cabeçalho http*/
response.addHeader(HEADER_STRING, token); /*Authorization: Bearer 87878we8we787w8e78w78e78w7e87w*/
/*Liberando resposta para porta diferente do projeto Angular*/
/*Escreve token como responsta no corpo http*/
response.getWriter().write("{\"Authorization\": \""+token+"\"}");
}
// Retorna o usuário validado com token ou caso não seja válido retorna null
public Authentication getAuthentication(HttpServletRequest request, HttpServletResponse response) {
liberacaoCors(response);
// Pega o token enviado no cabeçalho Http
String token = request.getHeader(HEADER_STRING);
if (token != null) {
// Faz validação do Token do usuário na requisição
String user = Jwts.parser()
.setSigningKey(SECRET)
.parseClaimsJws(token.replace(TOKEN_PREFIX, ""))
.getBody()
.getSubject();
if (user != null) {
Usuario usuario = ApplicationContextLoad
.getApplicationContext()
.getBean(UsuarioRepository.class)
.findUserByLogin(user);
if (usuario != null) {
return new UsernamePasswordAuthenticationToken(
usuario.getLogin(),
usuario.getSenha(),
usuario.getAuthorities());
}
}
}
return null;
}
private void liberacaoCors(HttpServletResponse response) {
if (response.getHeader("Access-Control-Allow-Origin") == null) {
response.addHeader("Access-Control-Allow-Origin", "*");
}
if (response.getHeader("Access-Control-Allow-Headers") == null) {
response.addHeader("Access-Control-Allow-Headers", "*");
}
if (response.getHeader("Access-Control-Request-Headers") == null) {
response.addHeader("Access-Control-Request-Headers", "*");
}
}
Veja bem. Ao autenticar, quando o token for gerado, ele deve ser enviado ao cliente (frontend). Com o token em mãos, o frontend deve armazená-lo em um cookie ou localstorage do navegador, para que, em novas requisições, o frontend envie esse token utilizando o header Authorization.
entendi Lucas! nesse momento eu estou recebendo essa autenticação no meu front, pois com ela é possivel eu fazer o login, nesse trecho do código ocorre exatamente o que vc esta dizendo, coloquei um debugger no codigo do front e abri o console pra vc ver como estou conseguindo capturar a autenticação, a questao e que depois de conseguir logar eu nao consigo buscar uma lista de dados no meu banco, pois ele continua alegando erro de autenticação.
armazenando o token no storage no front
login(usuario){
console.info(JSON.stringify(usuario));
return this.http.post(AppConstants.baseLogin, JSON.stringify(usuario)).subscribe(data => {
debugger;
var token = JSON.parse(JSON.stringify(data)).Authorization;
localStorage.setItem("token", token);
console.log("token " + localStorage.getItem("token"));
this.router.navigate(['home']);
},
error => {
console.error("Erro ao fazer login");
alert("Acesso negado");
}
);
Após o login, a rota é enviada para home. O componente dessa rota faz alguma requisição http? Se sim, como que vc está enviado o token nessa requisição?
Coloque um debugger nele para ver se ele está sendo chamado. Para checar se não eh problema no backend, tente fazer a requisição pelo postman (ou qualquer outro) passando o token.
O HttpInterceptorModule foi adicionado ao módulo principal app.module ? Vc também pode tentar adicionar o interceptor diretamente no app.module para testar.
@Lucas_Camara, o HttpInterceptorModule não estava adicionado do app.module acabei de fazer isso e obtive outro erro, nao consegui entender do que se trata.
import { HeaderInterceptorService } from './service/header-interceptor-service.service';
import { RouterModule, Routes } from '@angular/router';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { FormsModule } from '@angular/forms';
import {HttpClientModule} from '@angular/common/http';
import { HomeComponent } from './home/home.component';
import {ModuleWithProviders} from '@angular/compiler/src/core';
import { LoginComponent } from './login/login.component';
import { UsuarioComponent } from './componente/usuario/usuario.component';
export const appRouters: Routes = [
{path : 'home', component: HomeComponent},
{path: 'login', component: LoginComponent},
{path: '', component: LoginComponent},
{path: 'usuariosList', component: UsuarioComponent}
];
export const routes: ModuleWithProviders = RouterModule.forRoot(appRouters);
@NgModule({
declarations: [
AppComponent,
HomeComponent,
LoginComponent,
UsuarioComponent,
],
imports: [
BrowserModule,
AppRoutingModule,
FormsModule,
HttpClientModule,
routes,
HeaderInterceptorService
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }