14
14
import javax .servlet .http .HttpServletRequest ;
15
15
import javax .servlet .http .HttpServletResponse ;
16
16
import java .io .IOException ;
17
+ import java .io .UnsupportedEncodingException ;
17
18
import java .net .MalformedURLException ;
18
19
import java .net .URL ;
20
+ import java .net .URLEncoder ;
19
21
import java .nio .charset .StandardCharsets ;
20
22
import java .security .MessageDigest ;
21
23
import java .security .NoSuchAlgorithmException ;
@@ -36,33 +38,31 @@ public class SimpleAuthnInterceptor implements HandlerInterceptor {
36
38
37
39
private final static String ILLEGAL_ACCESS_EXCEPTION_MESSAGE = "the cookie is invalid, please clear the cookie and try again." ;
38
40
41
+ private final static String UTF_8 = "UTF-8" ;
42
+
39
43
@ Autowired
40
44
private CustomOidcConfiguration customOidcConfiguration ;
41
45
42
46
@ Autowired
43
47
private CacheManager cacheManager ;
44
48
45
- @ Autowired
46
- private CommonUtil commonUtil ;
47
-
48
49
@ Override
49
50
public boolean preHandle (HttpServletRequest request , HttpServletResponse response , Object handler )
50
51
throws IOException , NoSuchAlgorithmException , IllegalAccessException {
51
52
Cookie cookie = WebUtils .getCookie (request , ParameterNameFactory .COOKIE_NAME );
52
53
if (cookie == null ) {
53
- String cacheKey = UUID .randomUUID ().toString ();
54
- String redirectUri = commonUtil .getRedirectUri (request );
55
- String loginUri = getAuthorizationEndpointLoginUri (request , cacheKey , redirectUri );
56
- if (customOidcConfiguration .isOpenPkce ()) {
57
- loginUri = getPkceAuthorizationEndpointLoginUri ( cacheKey , loginUri );
54
+ String state = UUID .randomUUID ().toString ();
55
+ String redirectUri = customOidcConfiguration .getRedirectUri ();
56
+ String iDaaSLoginUri = getIDaaSLoginUri (request , state , redirectUri );
57
+ if (customOidcConfiguration .isPkceRequired ()) {
58
+ iDaaSLoginUri = getIDaaSLoginUri ( state , iDaaSLoginUri );
58
59
}
59
- response .sendRedirect (loginUri );
60
+ response .sendRedirect (iDaaSLoginUri );
60
61
} else {
61
62
String cookieValue = cacheManager .getCache (CommonUtil .generateCacheKey (cookie .getValue (), ParameterNameFactory .COOKIE_NAME ));
62
63
if (StringUtils .isBlank (cookieValue ) || !cookie .getValue ().equals (cookieValue )) {
63
64
throw new IllegalAccessException (ILLEGAL_ACCESS_EXCEPTION_MESSAGE );
64
65
}
65
-
66
66
}
67
67
return true ;
68
68
}
@@ -71,10 +71,11 @@ public boolean preHandle(HttpServletRequest request, HttpServletResponse respons
71
71
* Redirect the user to the authorization endpoint of the authorization server
72
72
* and include some query parameters in the URL of the authorization endpoint
73
73
*
74
- * @param cacheKey 用于作为缓存的key
74
+ * @param state 用于作为缓存的key以及作为随机值用于跨站保护
75
75
* @return 登录的重定向地址
76
76
*/
77
- private String getAuthorizationEndpointLoginUri (HttpServletRequest request , String cacheKey , String redirectUri ) throws MalformedURLException {
77
+ private String getIDaaSLoginUri (HttpServletRequest request , String state , String redirectUri )
78
+ throws MalformedURLException , UnsupportedEncodingException {
78
79
EndpointContext endpointContext = cacheManager .getCache (customOidcConfiguration .getIssuer ());
79
80
String authorizationEndpoint = endpointContext .getAuthorizationEndpoint ();
80
81
final String clientId = customOidcConfiguration .getClientId ();
@@ -83,40 +84,37 @@ private String getAuthorizationEndpointLoginUri(HttpServletRequest request, Stri
83
84
final String queryString = request .getQueryString ();
84
85
final String requestUrl = request .getRequestURL ().toString ();
85
86
final URL url = new URL (requestUrl );
86
- final String state = url .getPath () + (queryString == null ? "" : "?" + queryString ) + ":" + cacheKey ;
87
+ String callbackUrl = url .getPath () + (queryString == null ? "" : "?" + queryString );
88
+ cacheManager .setCache (CommonUtil .generateCacheKey (state , ParameterNameFactory .URI ), callbackUrl );
87
89
// responseType = code , It means that this is an authorization code request
88
- final String loginUrl = String .format (
89
- "%s?response_type=code&client_id=%s&redirect_uri=%s&scope=%s&state=%s" ,
90
- authorizationEndpoint ,
91
- clientId ,
92
- redirectUri ,
93
- scopes ,
94
- state );
95
- return loginUrl ;
90
+ return authorizationEndpoint +
91
+ "?response_type=code"
92
+ + "&client_id=" + URLEncoder .encode (clientId , UTF_8 )
93
+ + "&redirect_uri=" + URLEncoder .encode (redirectUri , UTF_8 )
94
+ + "&scope=" + URLEncoder .encode (scopes , UTF_8 )
95
+ + "&state=" + URLEncoder .encode (state , UTF_8 );
96
96
}
97
97
98
98
/**
99
99
* Obtain the redirection URL of Authorization Code With PKCE Flow
100
100
*
101
101
* @param state 缓存code verifier 的key
102
- * @param loginUri 授权码情况下的重定向地址
102
+ * @param iDaaSLoginUri 授权码情况下的重定向地址
103
103
* @return pkce情况下登录的的重定向地址
104
104
* @throws NoSuchAlgorithmException
105
105
*/
106
- private String getPkceAuthorizationEndpointLoginUri (String state , String loginUri ) throws NoSuchAlgorithmException {
106
+ private String getIDaaSLoginUri (String state , String iDaaSLoginUri ) throws NoSuchAlgorithmException , UnsupportedEncodingException {
107
107
String codeVerifier = createCodeVerifier ();
108
108
String codeChallenge = codeVerifier ;
109
109
String codeChallengeMethod = customOidcConfiguration .getCodeChallengeMethod ();
110
110
if (codeChallengeMethod .equals (CodeChallengeMethodFactory .SHA_256 )) {
111
111
codeChallenge = createHash (codeVerifier );
112
112
}
113
113
cacheManager .setCache (CommonUtil .generateCacheKey (state , ParameterNameFactory .CODE_VERIFIER ), codeVerifier );
114
- loginUri = String .format (
115
- "%s&code_challenge_method=%s&code_challenge=%s" ,
116
- loginUri ,
117
- customOidcConfiguration .getCodeChallengeMethod (),
118
- codeChallenge );
119
- return loginUri ;
114
+ iDaaSLoginUri = iDaaSLoginUri
115
+ + "&code_challenge_method=" + URLEncoder .encode (customOidcConfiguration .getCodeChallengeMethod (), UTF_8 )
116
+ + "&code_challenge=" + URLEncoder .encode (codeChallenge , UTF_8 );
117
+ return iDaaSLoginUri ;
120
118
}
121
119
122
120
/**
@@ -140,9 +138,8 @@ private static String createCodeVerifier() {
140
138
*/
141
139
private static String createHash (String codeVerifier ) throws NoSuchAlgorithmException {
142
140
MessageDigest md = MessageDigest .getInstance (SHA_256 );
143
- byte [] digest = md .digest (codeVerifier .getBytes (StandardCharsets .UTF_8 ));
141
+ byte [] digest = md .digest (codeVerifier .getBytes (StandardCharsets .US_ASCII ));
144
142
return Base64 .getUrlEncoder ().withoutPadding ().encodeToString (digest );
145
143
}
146
-
147
144
}
148
145
0 commit comments