1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package fr.paris.lutece.plugins.franceconnect.oidc.jwt;
35
36 import fr.paris.lutece.plugins.franceconnect.oidc.AuthClientConf;
37 import fr.paris.lutece.plugins.franceconnect.oidc.AuthServerConf;
38 import fr.paris.lutece.plugins.franceconnect.oidc.IDToken;
39 import fr.paris.lutece.plugins.franceconnect.oidc.Token;
40 import fr.paris.lutece.plugins.franceconnect.web.Constants;
41
42 import io.jsonwebtoken.Claims;
43 import io.jsonwebtoken.ExpiredJwtException;
44 import io.jsonwebtoken.Jwt;
45 import io.jsonwebtoken.JwtParser;
46 import io.jsonwebtoken.Jwts;
47 import io.jsonwebtoken.SignatureException;
48
49 import org.apache.log4j.Logger;
50
51 import java.io.UnsupportedEncodingException;
52
53
54
55
56
57 public class JjwtJWTParser implements JWTParser
58 {
59
60
61
62 @Override
63 public void parseJWT( Token token, AuthClientConf clientConfig, AuthServerConf serverConfig, String strStoredNonce,
64 Logger logger ) throws TokenValidationException
65 {
66 String strCompactJwt = token.getIdTokenString( );
67
68 try
69 {
70 JwtParser parser = Jwts.parser( );
71 parser.setSigningKey( clientConfig.getClientSecret( ).getBytes( "UTF-8" ) );
72
73 Jwt jwt = parser.parse( strCompactJwt );
74 Claims claims = (Claims) jwt.getBody( );
75
76 IDToken idToken = new IDToken( );
77 idToken.setAudience( claims.getAudience( ) );
78 idToken.setIssuer( claims.getIssuer( ) );
79 idToken.setSubject( claims.getSubject( ) );
80
81
82 idToken.setNonce( getVerifiedNonce( claims, strStoredNonce ) );
83 idToken.setExpiration( getExpiration( claims ) );
84 idToken.setIssueAt( getIssueAt( claims ) );
85
86
87 idToken.setIdProvider( (String) claims.get( Constants.CLAIM_IDP ) );
88 idToken.setAcr( (String) claims.get( Constants.CLAIM_ACR ) );
89
90 logger.debug( "ID Token retrieved by JJWT parser implementation : " + idToken );
91
92 token.setIdToken( idToken );
93 }
94 catch ( SignatureException ex )
95 {
96 throw new TokenValidationException( ex.getMessage( ), ex );
97 }
98 catch ( ExpiredJwtException ex )
99 {
100 throw new TokenValidationException( ex.getMessage( ), ex );
101 }
102 catch ( UnsupportedEncodingException ex )
103 {
104 throw new TokenValidationException( ex.getMessage( ), ex );
105 }
106 }
107
108
109
110
111
112
113
114
115 private String getVerifiedNonce( Claims claims, String strStoredNonce )
116 throws TokenValidationException
117 {
118
119 String strNonce = (String) claims.get( Constants.CLAIM_NONCE );
120
121 if ( strNonce == null )
122 {
123 throw new TokenValidationException( "The token doesn't contains the nonce info." );
124 }
125
126 if ( !strNonce.equals( strStoredNonce ) )
127 {
128 throw new TokenValidationException( "The nonce info has not the value expected." );
129 }
130
131 return strNonce;
132 }
133
134
135
136
137
138
139 private String getExpiration( Claims claims )
140 {
141 long lExpiration = claims.getExpiration( ).getTime( );
142
143 return String.valueOf( lExpiration / 1000L );
144 }
145
146
147
148
149
150
151 private String getIssueAt( Claims claims )
152 {
153 long lIssueAt = claims.getIssuedAt( ).getTime( );
154
155 return String.valueOf( lIssueAt / 1000L );
156 }
157 }