Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,6 @@ target/
.env
.env.*
!.env.example

### Claude Code ###
.claude/
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,22 @@ O objetivo é enxergar cada peça do Spring Security sem ruído.
A API sobe em `http://localhost:8080`. O log está em `DEBUG` para o pacote
`org.springframework.security`, então dá para acompanhar cada filtro decidindo o que fazer.

## Tela de testes

Com a API no ar, abra `http://localhost:8080` no navegador. A página `index.html` (servida pelo
próprio Spring Boot, pasta `static/`) deixa escolher um usuário, chamar cada endpoint e ver o
status, o corpo da resposta e o header `Authorization` que foi enviado. Nada ali é protegido:
a proteção está na API que a tela chama.

## Testando com curl, Postman ou `.http`

O guia passo a passo com tudo pronto para copiar e colar está em
[docs/GUIA_CURL_POSTMAN.md](docs/GUIA_CURL_POSTMAN.md). Resumo:

- `./scripts/testar-api.sh` roda todas as chamadas com curl e confere os códigos.
- `postman/SenacSpringSecurity.postman_collection.json` importa no Postman com testes automáticos.
- `docs/requisicoes.http` funciona no VS Code (REST Client) e no IntelliJ.

## Usuários de exemplo

| Login | Senha | Papéis |
Expand Down
143 changes: 143 additions & 0 deletions docs/GUIA_CURL_POSTMAN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
# Guia passo a passo: testando a API com curl, Postman ou `.http`

Tudo aqui é copiar e colar. Antes de começar, suba a API:

```bash
./mvnw spring-boot:run
```

Ela responde em `http://localhost:8080`. Usuários disponíveis:

| Login | Senha | Papéis |
|-------------|------------|------------------|
| `aluno` | `aluno123` | ALUNO |
| `professor` | `prof123` | PROFESSOR |
| `admin` | `admin123` | ADMIN, PROFESSOR |

O que observar em cada resposta:

- **200** → autenticado (quando exigido) e autorizado.
- **401 Unauthorized** → falha de **autenticação**: sem credencial, senha errada ou usuário inexistente.
- **403 Forbidden** → falha de **autorização**: login certo, mas o papel não permite.

---

## Opção 1: curl

O `-i` mostra o status e os headers. O `-u login:senha` monta o header
`Authorization: Basic base64(login:senha)` por você.

### Passo 1: rota pública (sem login)

```bash
curl -i http://localhost:8080/api/publico
```
Esperado: `200`.

### Passo 2: rota protegida sem credenciais

```bash
curl -i http://localhost:8080/api/perfil
```
Esperado: `401`. Repare que não vem o header `WWW-Authenticate`: a API responde "seco", sem pedir popup de login.

### Passo 3: senha errada e usuário inexistente

```bash
curl -i -u aluno:senha-errada http://localhost:8080/api/perfil
```
```bash
curl -i -u ninguem:qualquer http://localhost:8080/api/perfil
```
Esperado: `401` nos dois. A resposta é igual de propósito, para não revelar quais logins existem.

### Passo 4: login correto, ver o perfil

```bash
curl -i -u aluno:aluno123 http://localhost:8080/api/perfil
```
Esperado: `200` com `{"login":"aluno","papeis":["ROLE_ALUNO"]}`. Note o prefixo `ROLE_`.

### Passo 5: autorização por URL, papel a papel

Aluno:
```bash
curl -i -u aluno:aluno123 http://localhost:8080/api/aluno
```
```bash
curl -i -u aluno:aluno123 http://localhost:8080/api/professor
```
```bash
curl -i -u aluno:aluno123 http://localhost:8080/api/admin
```
Esperado: `200`, `403`, `403`.

Professor:
```bash
curl -i -u professor:prof123 http://localhost:8080/api/professor
```
```bash
curl -i -u professor:prof123 http://localhost:8080/api/admin
```
Esperado: `200`, `403`.

Admin:
```bash
curl -i -u admin:admin123 http://localhost:8080/api/admin
```
Esperado: `200`.

### Passo 6: autorização por método (`@PreAuthorize`)

```bash
curl -i -u aluno:aluno123 http://localhost:8080/api/notas/aluno
```
```bash
curl -i -u aluno:aluno123 http://localhost:8080/api/notas/outro
```
```bash
curl -i -u professor:prof123 http://localhost:8080/api/notas/aluno
```
Esperado: `200` (as próprias notas), `403` (notas de outro), `200` (professor vê qualquer um).

### Passo 7: montar o header na mão

Para ver o que o `-u` faz por baixo dos panos:

```bash
echo -n 'admin:admin123' | base64
```
```bash
curl -i -H 'Authorization: Basic YWRtaW46YWRtaW4xMjM=' http://localhost:8080/api/admin
```
Base64 **não é criptografia**: qualquer um decodifica. Por isso HTTP Basic só faz sentido com HTTPS.

### Rodar tudo de uma vez

O script abaixo executa todas as chamadas acima e confere o status de cada uma:

```bash
./scripts/testar-api.sh
```

---

## Opção 2: Postman

1. Abra o Postman e clique em **Import**.
2. Arraste o arquivo [`postman/SenacSpringSecurity.postman_collection.json`](../postman/SenacSpringSecurity.postman_collection.json).
3. A coleção já vem com a variável `baseUrl = http://localhost:8080` e com **testes automáticos**
em cada requisição (aba *Tests*), conferindo o status esperado.
4. Abra cada requisição e clique em **Send**; o resultado dos testes aparece na aba *Test Results*.
5. Para rodar tudo: clique com o botão direito na coleção → **Run collection** → **Run**.
Todas as 17 requisições devem passar.

Como a autenticação está configurada no Postman: cada requisição usa **Auth → Basic Auth**
com login e senha preenchidos. Veja a aba *Authorization* de qualquer requisição para trocar o usuário.

---

## Opção 3: arquivo `.http` (VS Code ou IntelliJ)

Abra [`docs/requisicoes.http`](requisicoes.http). No VS Code instale a extensão **REST Client**;
no IntelliJ o suporte é nativo. Clique em **Send Request** acima de cada bloco.
61 changes: 61 additions & 0 deletions docs/requisicoes.http
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
### Requisições da API SenacSpringSecurity
### VS Code: extensão "REST Client" | IntelliJ: suporte nativo
@baseUrl = http://localhost:8080

### 1. Rota pública, sem login -> 200
GET {{baseUrl}}/api/publico

### 2. Rota protegida sem credenciais -> 401
GET {{baseUrl}}/api/perfil

### 3. Senha errada -> 401
GET {{baseUrl}}/api/perfil
Authorization: Basic aluno senha-errada

### 4. Usuário inexistente -> 401
GET {{baseUrl}}/api/perfil
Authorization: Basic ninguem qualquer

### 5. Perfil do aluno -> 200
GET {{baseUrl}}/api/perfil
Authorization: Basic aluno aluno123

### 6. Aluno na área do aluno -> 200
GET {{baseUrl}}/api/aluno
Authorization: Basic aluno aluno123

### 7. Aluno na área do professor -> 403
GET {{baseUrl}}/api/professor
Authorization: Basic aluno aluno123

### 8. Aluno na área admin -> 403
GET {{baseUrl}}/api/admin
Authorization: Basic aluno aluno123

### 9. Professor na área do professor -> 200
GET {{baseUrl}}/api/professor
Authorization: Basic professor prof123

### 10. Professor na área admin -> 403
GET {{baseUrl}}/api/admin
Authorization: Basic professor prof123

### 11. Admin na área admin -> 200
GET {{baseUrl}}/api/admin
Authorization: Basic admin admin123

### 12. Aluno vê as próprias notas -> 200
GET {{baseUrl}}/api/notas/aluno
Authorization: Basic aluno aluno123

### 13. Aluno tenta ver notas de outro -> 403
GET {{baseUrl}}/api/notas/outro
Authorization: Basic aluno aluno123

### 14. Professor vê notas de qualquer aluno -> 200
GET {{baseUrl}}/api/notas/aluno
Authorization: Basic professor prof123

### 15. Header montado na mão (admin:admin123 em base64) -> 200
GET {{baseUrl}}/api/admin
Authorization: Basic YWRtaW46YWRtaW4xMjM=
Loading
Loading