Skip to content

Commit 9f642fe

Browse files
authored
Merge pull request ncanode-kz#226 from mitwork/jwt
Реализация подписания JWT GG2015
2 parents b871584 + 8ad434a commit 9f642fe

9 files changed

Lines changed: 715 additions & 0 deletions

File tree

build.gradle

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ repositories {
2323
}
2424
mavenLocal()
2525
mavenCentral()
26+
maven {
27+
url 'https://pkgs.dev.azure.com/as1an/public/_packaging/repo/maven/v1'
28+
}
2629
}
2730

2831
dependencies {
@@ -55,6 +58,9 @@ dependencies {
5558
implementation name: 'kalkancrypt-xmldsig-0.5'
5659
implementation 'org.apache.santuario:xmlsec:3.0.3'
5760

61+
// JWT GG2015
62+
implementation 'kz.gov.pki:java-jwt:4.4.0'
63+
5864
// SOAP/WSSE
5965
implementation 'org.apache.ws.security:wss4j:1.6.19'
6066
implementation 'org.apache.wss4j:wss4j-ws-security-dom:2.4.1'

openapi.yml

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ tags:
1818
description: Методы для работы с x509
1919
- name: XML
2020
description: Методы для работы с XML
21+
- name: JWT
22+
description: Методы для работы с JWT
2123
- name: Actuator
2224
description: Monitor and interact
2325
externalDocs:
@@ -276,6 +278,42 @@ paths:
276278
'*/*':
277279
schema:
278280
$ref: '#/components/schemas/CmsDataResponse'
281+
/jwt/encode:
282+
post:
283+
tags:
284+
- JWT
285+
operationId: encode
286+
requestBody:
287+
content:
288+
application/json:
289+
schema:
290+
$ref: '#/components/schemas/JwtEncodeRequest'
291+
required: true
292+
responses:
293+
'200':
294+
description: OK
295+
content:
296+
'*/*':
297+
schema:
298+
$ref: '#/components/schemas/JwtEncodeResponse'
299+
/jwt/decode:
300+
post:
301+
tags:
302+
- JWT
303+
operationId: decode
304+
requestBody:
305+
content:
306+
application/json:
307+
schema:
308+
$ref: '#/components/schemas/JwtDecodeRequest'
309+
required: true
310+
responses:
311+
'200':
312+
description: OK
313+
content:
314+
'*/*':
315+
schema:
316+
$ref: '#/components/schemas/JwtDecodeResponse'
279317
/actuator:
280318
get:
281319
tags:
@@ -791,6 +829,97 @@ components:
791829
type: string
792830
data:
793831
type: string
832+
JwtEncodeRequest:
833+
required:
834+
- jwt
835+
- key
836+
- password
837+
type: object
838+
properties:
839+
jwt:
840+
$ref: '#/components/schemas/JwtRequest'
841+
key:
842+
type: string
843+
password:
844+
type: string
845+
keyAlias:
846+
type: string
847+
JwtRequest:
848+
required:
849+
- header
850+
- payload
851+
type: object
852+
properties:
853+
header:
854+
$ref: '#/components/schemas/JwtHeader'
855+
payload:
856+
$ref: '#/components/schemas/JwtPayload'
857+
JwtHeader:
858+
required:
859+
- alg
860+
- typ
861+
type: object
862+
properties:
863+
alg:
864+
type: string
865+
enum:
866+
- GG2015
867+
- GG2004
868+
- ES256
869+
- ES384
870+
- ES512
871+
- RS256
872+
- RS384
873+
- RS512
874+
typ:
875+
type: string
876+
enum:
877+
- JWT
878+
JwtPayload:
879+
type: object
880+
example:
881+
cbin: "012345678909"
882+
mcheck: "DS"
883+
iat: 1631925900
884+
exp: 1631929500
885+
JwtEncodeResponse:
886+
type: object
887+
properties:
888+
status:
889+
type: integer
890+
format: int32
891+
message:
892+
type: string
893+
jwt:
894+
type: string
895+
JwtDecodeRequest:
896+
required:
897+
- jwt
898+
- key
899+
type: object
900+
properties:
901+
jwt:
902+
type: string
903+
key:
904+
type: string
905+
JwtDecodeResponse:
906+
type: object
907+
properties:
908+
status:
909+
type: integer
910+
format: int32
911+
message:
912+
type: string
913+
jwt:
914+
type: object
915+
properties:
916+
header:
917+
type: object
918+
additionalProperties:
919+
type: string
920+
payload:
921+
type: object
922+
additionalProperties: true
794923
Link:
795924
type: object
796925
properties:
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package kz.ncanode.controller;
2+
3+
import kz.ncanode.dto.request.JwtDecodeRequest;
4+
import kz.ncanode.dto.request.JwtEncodeRequest;
5+
import kz.ncanode.dto.response.JwtDecodeResponse;
6+
import kz.ncanode.dto.response.JwtEncodeResponse;
7+
import kz.ncanode.service.JwtService;
8+
import lombok.RequiredArgsConstructor;
9+
import org.springframework.http.ResponseEntity;
10+
import org.springframework.web.bind.annotation.PostMapping;
11+
import org.springframework.web.bind.annotation.RequestBody;
12+
import org.springframework.web.bind.annotation.RequestMapping;
13+
import org.springframework.web.bind.annotation.RestController;
14+
15+
import javax.validation.Valid;
16+
17+
import io.swagger.v3.oas.annotations.tags.Tag;
18+
19+
@Tag(name = "JWT", description = "Методы для работы с JWT")
20+
@RestController
21+
@RequestMapping("jwt")
22+
@RequiredArgsConstructor
23+
public class JwtController {
24+
private final JwtService jwtService;
25+
26+
@PostMapping("/encode")
27+
public ResponseEntity<JwtEncodeResponse> encode(@Valid @RequestBody JwtEncodeRequest jwtEncodeRequest) {
28+
return ResponseEntity.ok(jwtService.encode(jwtEncodeRequest));
29+
}
30+
31+
@PostMapping("/decode")
32+
public ResponseEntity<JwtDecodeResponse> decode(@Valid @RequestBody JwtDecodeRequest jwtDecodeRequest) {
33+
return ResponseEntity.ok(jwtService.decode(jwtDecodeRequest));
34+
}
35+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package kz.ncanode.dto.request;
2+
3+
import lombok.Builder;
4+
import lombok.Data;
5+
import lombok.extern.jackson.Jacksonized;
6+
7+
import javax.validation.constraints.NotEmpty;
8+
import javax.validation.constraints.NotNull;
9+
10+
@Jacksonized
11+
@Data
12+
@Builder
13+
public class JwtDecodeRequest {
14+
15+
@NotNull
16+
private String jwt;
17+
18+
@NotEmpty
19+
private String key;
20+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package kz.ncanode.dto.request;
2+
3+
import com.fasterxml.jackson.annotation.JsonAnyGetter;
4+
import com.fasterxml.jackson.annotation.JsonAnySetter;
5+
import lombok.Builder;
6+
import lombok.Data;
7+
import lombok.extern.jackson.Jacksonized;
8+
9+
import javax.validation.Valid;
10+
import javax.validation.constraints.NotEmpty;
11+
import javax.validation.constraints.NotNull;
12+
import java.util.LinkedHashMap;
13+
import java.util.Map;
14+
15+
@Jacksonized
16+
@Data
17+
@Builder
18+
public class JwtEncodeRequest {
19+
20+
@NotNull
21+
@Valid
22+
private JwtRequest jwt;
23+
24+
@NotEmpty
25+
private String key;
26+
27+
@NotEmpty
28+
private String password;
29+
30+
private String keyAlias;
31+
32+
@Jacksonized
33+
@Data
34+
@Builder
35+
public static class JwtRequest {
36+
@NotNull
37+
@Valid
38+
private JwtHeader header;
39+
40+
@NotNull
41+
@Valid
42+
private JwtPayload payload;
43+
}
44+
45+
@Jacksonized
46+
@Data
47+
@Builder
48+
public static class JwtHeader {
49+
@NotEmpty
50+
private String alg;
51+
52+
@NotEmpty
53+
private String typ;
54+
}
55+
56+
@Data
57+
public static class JwtPayload {
58+
private final Map<String, Object> claims = new LinkedHashMap<>();
59+
60+
@JsonAnySetter
61+
public void setClaim(String key, Object value) {
62+
claims.put(key, value);
63+
}
64+
65+
@JsonAnyGetter
66+
public Map<String, Object> getClaims() {
67+
return claims;
68+
}
69+
}
70+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package kz.ncanode.dto.response;
2+
3+
import lombok.Builder;
4+
import lombok.Data;
5+
import lombok.EqualsAndHashCode;
6+
import lombok.experimental.SuperBuilder;
7+
import lombok.extern.jackson.Jacksonized;
8+
9+
import java.util.Map;
10+
11+
@Jacksonized
12+
@EqualsAndHashCode(callSuper = true)
13+
@Data
14+
@SuperBuilder
15+
public class JwtDecodeResponse extends StatusResponse {
16+
private boolean valid;
17+
private Jwt jwt;
18+
19+
@Jacksonized
20+
@Data
21+
@Builder
22+
public static class Jwt {
23+
private Map<String, String> header;
24+
private Map<String, Object> payload;
25+
}
26+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package kz.ncanode.dto.response;
2+
3+
import lombok.Data;
4+
import lombok.EqualsAndHashCode;
5+
import lombok.experimental.SuperBuilder;
6+
import lombok.extern.jackson.Jacksonized;
7+
8+
@Jacksonized
9+
@EqualsAndHashCode(callSuper = true)
10+
@Data
11+
@SuperBuilder
12+
public class JwtEncodeResponse extends StatusResponse {
13+
private String jwt;
14+
}

0 commit comments

Comments
 (0)