22
22
import com .alibaba .nacos .plugin .auth .exception .AccessException ;
23
23
import com .alibaba .nacos .plugin .auth .impl .constant .AuthConstants ;
24
24
import com .alibaba .nacos .plugin .auth .impl .oidc .OIDCClient ;
25
- import com .alibaba .nacos .plugin .auth .impl .oidc .OIDCConfigurations ;
25
+ import com .alibaba .nacos .plugin .auth .impl .oidc .OIDCConfigs ;
26
26
import com .alibaba .nacos .plugin .auth .impl .oidc .OIDCProvider ;
27
27
import com .alibaba .nacos .plugin .auth .impl .oidc .OIDCService ;
28
+ import com .alibaba .nacos .plugin .auth .impl .oidc .OIDCState ;
28
29
import com .alibaba .nacos .plugin .auth .impl .users .NacosUser ;
29
30
import com .fasterxml .jackson .databind .node .ObjectNode ;
31
+ import com .nimbusds .jose .util .Base64URL ;
30
32
import com .nimbusds .oauth2 .sdk .AuthorizationCode ;
31
33
import com .nimbusds .openid .connect .sdk .AuthenticationRequest ;
32
34
import com .nimbusds .openid .connect .sdk .claims .UserInfo ;
35
+ import org .springframework .beans .factory .annotation .Autowired ;
33
36
import org .springframework .web .bind .annotation .GetMapping ;
34
37
import org .springframework .web .bind .annotation .RequestMapping ;
35
38
import org .springframework .web .bind .annotation .RequestParam ;
@@ -60,19 +63,40 @@ public class OIDCController {
60
63
61
64
private final OIDCService oidcService ;
62
65
66
+ @ Autowired
63
67
public OIDCController (OIDCClient oidcClient , OIDCService oidcService ) {
64
68
this .oidcClient = oidcClient ;
65
69
this .oidcService = oidcService ;
66
70
}
67
71
72
+ private static String buildRedirectUriWithPayload (String origin , String resultCode , String result ) {
73
+ // split the origin URL into base URL and hash route
74
+ int hashIndex = origin .indexOf ('#' );
75
+ String baseUrl = hashIndex != -1 ? origin .substring (0 , hashIndex ) : origin ;
76
+ String hashRoute = hashIndex != -1 ? origin .substring (hashIndex ) : "" ;
77
+
78
+ // build redirect url with hash route and token
79
+ UriComponentsBuilder redirectUriBuilder = UriComponentsBuilder .fromUriString (baseUrl );
80
+ if (!hashRoute .isEmpty ()) {
81
+ StringBuilder sb = new StringBuilder (hashRoute );
82
+ if (hashRoute .contains ("?" )) {
83
+ sb .append ("&" );
84
+ } else {
85
+ sb .append ("?" );
86
+ }
87
+ hashRoute = sb .append (resultCode ).append ("=" ).append (result ).toString ();
88
+ }
89
+ return redirectUriBuilder .build ().toUriString () + hashRoute ;
90
+ }
91
+
68
92
/**
69
93
* Get current OIDC provider.
70
94
*/
71
95
@ GetMapping ("/provider" )
72
96
public OIDCProvider getProvider () {
73
- String providerKey = OIDCConfigurations .getProvider ();
97
+ String providerKey = OIDCConfigs .getProvider ();
74
98
OIDCProvider provider = new OIDCProvider ();
75
- provider .setName (OIDCConfigurations .getNameByKey (providerKey ));
99
+ provider .setName (OIDCConfigs .getNameByKey (providerKey ));
76
100
provider .setKey (providerKey );
77
101
return provider ;
78
102
@@ -89,13 +113,12 @@ public OIDCProvider getProvider() {
89
113
public void startAuthentication (@ RequestParam ("origin" ) String origin , HttpServletResponse response ,
90
114
HttpSession session ) throws IOException {
91
115
92
- String callbackUri = ServletUriComponentsBuilder .fromCurrentContextPath ().path (CALLBACK_PATH )
93
- .queryParam ("origin" , origin ).toUriString ();
116
+ String callbackUri = ServletUriComponentsBuilder .fromCurrentContextPath ().path (CALLBACK_PATH ).toUriString ();
94
117
95
- AuthenticationRequest authRequest = oidcClient .createAuthenticationRequest (callbackUri );
118
+ AuthenticationRequest authRequest = oidcClient .createAuthenticationRequest (callbackUri , origin );
96
119
97
- session .setAttribute ("oidc_state" , authRequest .getState ().getValue ());
98
- session .setAttribute ("oidc_nonce" , authRequest .getNonce ().getValue ());
120
+ session .setAttribute (AuthConstants . OIDC_STATE , authRequest .getState ().getValue ());
121
+ session .setAttribute (AuthConstants . OIDC_NONCE , authRequest .getNonce ().getValue ());
99
122
100
123
// Redirect to Authentication endpoint
101
124
response .sendRedirect (authRequest .toURI ().toString ());
@@ -112,29 +135,39 @@ public void startAuthentication(@RequestParam("origin") String origin, HttpServl
112
135
*/
113
136
@ GetMapping ("/callback" )
114
137
public void callback (@ RequestParam ("code" ) String code , @ RequestParam ("state" ) String returnedState ,
115
- @ RequestParam ("origin" ) String origin , HttpServletResponse response , HttpSession session )
116
- throws IOException {
138
+ HttpServletResponse response , HttpSession session ) throws IOException {
117
139
118
140
// Check if the state is valid
119
- String originalState = (String ) session .getAttribute ("oidc_state" );
120
- if (originalState == null || !originalState .equals (returnedState )) {
121
- String uriString = buildRedirectUriWithPayload (origin , "msg" , "Invalid state" );
141
+ String originalState = (String ) session .getAttribute (AuthConstants .OIDC_STATE );
142
+ if (originalState == null ) {
143
+ String missingOrigin = ServletUriComponentsBuilder .fromCurrentContextPath ().path (AuthConstants .LOGIN_PAGE )
144
+ .toUriString ();
145
+ String uriString = buildRedirectUriWithPayload (missingOrigin , AuthConstants .OIDC_PARAM_MSG ,
146
+ "Session expired" );
147
+ response .sendRedirect (uriString );
148
+ return ;
149
+ }
150
+ String json = Base64URL .from (originalState ).decodeToString ();
151
+ OIDCState state = JacksonUtils .toObj (json , OIDCState .class );
152
+ if (!originalState .equals (returnedState )) {
153
+ String uriString = buildRedirectUriWithPayload (state .getOrigin (), AuthConstants .OIDC_PARAM_MSG ,
154
+ "Invalid state" );
122
155
response .sendRedirect (uriString );
123
156
return ;
124
157
}
125
158
126
159
// Exchange the authorization code for the information
127
- String callbackUri = ServletUriComponentsBuilder .fromCurrentContextPath ().path (CALLBACK_PATH )
128
- .queryParam ("origin" , origin ).toUriString ();
129
- UserInfo userInfo = oidcClient .getUserInfo (new AuthorizationCode (code ), callbackUri );
160
+ String callbackUri = ServletUriComponentsBuilder .fromCurrentContextPath ().path (CALLBACK_PATH ).toUriString ();
161
+ UserInfo userInfo = oidcClient .getUserInfo (new AuthorizationCode (code ), callbackUri , state .getNonce ());
130
162
131
163
// Extract the username from the user info
132
164
String preferredUsername = userInfo .getPreferredUsername ();
133
165
NacosUser nacosUser ;
134
166
try {
135
167
nacosUser = oidcService .getUser (preferredUsername );
136
168
} catch (AccessException e ) {
137
- String uriString = buildRedirectUriWithPayload (origin , "msg" , "User not found" );
169
+ String uriString = buildRedirectUriWithPayload (state .getOrigin (), AuthConstants .OIDC_PARAM_MSG ,
170
+ "User not found" );
138
171
response .sendRedirect (uriString );
139
172
return ;
140
173
}
@@ -153,30 +186,10 @@ public void callback(@RequestParam("code") String code, @RequestParam("state") S
153
186
154
187
byte [] resultCodedBytes = Base64 .encodeBase64 (result .toString ().getBytes (StandardCharsets .UTF_8 ));
155
188
156
- String uriString = buildRedirectUriWithPayload (origin , "token" ,
189
+ String uriString = buildRedirectUriWithPayload (state . getOrigin (), AuthConstants . OIDC_PARAM_TOKEN ,
157
190
new String (resultCodedBytes , StandardCharsets .UTF_8 ));
158
191
159
192
response .sendRedirect (uriString );
160
193
}
161
194
162
- private static String buildRedirectUriWithPayload (String origin , String resultCode , String result ) {
163
- // split the origin URL into base URL and hash route
164
- int hashIndex = origin .indexOf ('#' );
165
- String baseUrl = hashIndex != -1 ? origin .substring (0 , hashIndex ) : origin ;
166
- String hashRoute = hashIndex != -1 ? origin .substring (hashIndex ) : "" ;
167
-
168
- // build redirect url with hash route and token
169
- UriComponentsBuilder redirectUriBuilder = UriComponentsBuilder .fromUriString (baseUrl );
170
- if (!hashRoute .isEmpty ()) {
171
- StringBuilder sb = new StringBuilder (hashRoute );
172
- if (hashRoute .contains ("?" )) {
173
- sb .append ("&" );
174
- } else {
175
- sb .append ("?" );
176
- }
177
- hashRoute = sb .append (resultCode ).append ("=" ).append (result ).toString ();
178
- }
179
- return redirectUriBuilder .build ().toUriString () + hashRoute ;
180
- }
181
-
182
195
}
0 commit comments