-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathindex.html
106 lines (91 loc) · 4.49 KB
/
index.html
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Public Client Sample</title>
</head>
<body>
<h1>Public Client Sample</h1>
<button id="startButton">Start OAuth Flow</button>
<div id="result"></div>
<script>
const authorizeEndpoint = "https://idsvr:8443/oauth/v2/oauth-authorize";
const tokenEndpoint = "https://idsvr:8443/oauth/v2/oauth-token";
const clientId = "public-test-client";
if (window.location.search) {
var args = new URLSearchParams(window.location.search);
var code = args.get("code");
if (code) {
var xhr = new XMLHttpRequest();
xhr.onload = function() {
var response = xhr.response;
var message;
if (xhr.status == 200) {
message = "Access Token: " + response.access_token;
}
else {
message = "Error: " + response.error_description + " (" + response.error + ")";
}
document.getElementById("result").innerHTML = message;
};
xhr.responseType = 'json';
xhr.open("POST", tokenEndpoint, true);
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.send(new URLSearchParams({
client_id: clientId,
code_verifier: window.sessionStorage.getItem("code_verifier"),
grant_type: "authorization_code",
redirect_uri: location.href.replace(location.search, ''),
code: code
}));
}
}
document.getElementById("startButton").onclick = function() {
var codeVerifier = generateRandomString(64);
const challengeMethod = crypto.subtle ? "S256" : "plain"
Promise.resolve()
.then(() => {
if (challengeMethod === 'S256') {
return generateCodeChallenge(codeVerifier)
} else {
return codeVerifier
}
})
.then(function(codeChallenge) {
window.sessionStorage.setItem("code_verifier", codeVerifier);
var redirectUri = window.location.href.split('?')[0];
var args = new URLSearchParams({
response_type: "code",
client_id: clientId,
code_challenge_method: challengeMethod,
code_challenge: codeChallenge,
redirect_uri: redirectUri
});
window.location = authorizeEndpoint + "/?" + args;
});
}
async function generateCodeChallenge(codeVerifier) {
var digest = await crypto.subtle.digest("SHA-256",
new TextEncoder().encode(codeVerifier));
return btoa(String.fromCharCode(...new Uint8Array(digest)))
.replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_')
}
function generateRandomString(length) {
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (var i = 0; i < length; i++) {
text += possible.charAt(Math.floor(Math.random() * possible.length));
}
return text;
}
if (!crypto.subtle) {
document.writeln('<p>' +
'<b>WARNING:</b> The script will fall back to using plain code challenge as crypto is not available.</p>' +
'<p>Javascript crypto services require that this site is served in a <a href="https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts">secure context</a>; ' +
'either from <b>(*.)localhost</b> or via <b>https</b>. </p>' +
'<p> You can add an entry to /etc/hosts like "127.0.0.1 public-test-client.localhost" and reload the site from there, enable SSL using something like <a href="https://letsencrypt.org/">letsencypt</a>, or refer to this <a href="https://stackoverflow.com/questions/46468104/how-to-use-subtlecrypto-in-chrome-window-crypto-subtle-is-undefined">stackoverflow article</a> for more alternatives.</p>' +
'<p>If Javascript crypto is available this message will disappear.</p>')
}
</script>
</body>
</html>