Auth Emulator - Indicate valid Username characters when invalid character(s) submitted
Is your feature request related to a problem? Please describe.
Using the Auth Emulator page for GitHub (may be the same for other Identity Providers): http://localhost:4280/.auth/login/github
If the user enters invalid characters for Username, an attempt to submit the form fails "silently" in the UI.
Example value for Username:
یونیکد
The console gives additional information:
The string to be encoded contains characters outside of the Latin1 range.
Uncaught DOMException: Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range. at saveCookie (http://localhost:4280/.auth/login/github:168:54) at HTMLFormElement.<anonymous> (http://localhost:4280/.auth/login/github:316:11) at HTMLFormElement.dispatch (https://ajax.aspnetcdn.com/ajax/jquery/jquery-3.2.1.min.js:3:10316) at HTMLFormElement.q.handle (https://ajax.aspnetcdn.com/ajax/jquery/jquery-3.2.1.min.js:3:8343)
Describe the solution you'd like If it is required that Username characters be in the Latin1 range, add a validation message near the Username field in the UI. If the full range of Unicode characters is allowed, adjust logic, to allow such characters.
Describe alternatives you've considered Open the DevTools Console while running, to view run-time exceptions
Additional context Exception is thrown in this source code file: https://github.com/Azure/static-web-apps-cli/blob/main/src/public/auth.html
function saveCookie(formElement) {
const data = localStorage[hashStorageKey(formElement)];
document.cookie = `StaticWebAppsAuthCookie=${btoa(data)}; path=/`;
}
This link may provide a workaround for the problem:
https://developer.mozilla.org/en-US/docs/Glossary/Base64
function utf8_to_b64( str ) {
return window.btoa(unescape(encodeURIComponent( str )));
}
function b64_to_utf8( str ) {
return decodeURIComponent(escape(window.atob( str )));
}
// Usage:
utf8_to_b64('✓ à la mode'); // "4pyTIMOgIGxhIG1vZGU="
b64_to_utf8('4pyTIMOgIGxhIG1vZGU='); // "✓ à la mode"
I found that, if I change the Javascript in auth.html:
function utf8_to_b64( str ) {
return window.btoa(unescape(encodeURIComponent( str )));
}
function saveCookie(formElement) {
const data = localStorage[hashStorageKey(formElement)];
// document.cookie = `StaticWebAppsAuthCookie=${btoa(data)}; path=/`;
document.cookie = `StaticWebAppsAuthCookie=${utf8_to_b64(data)}; path=/`;
}
The redirect occurs in the browser.
If a Function needs to inspect the x-ms-client-principal cookie, a small change is required
(based on https://github.com/MicrosoftDocs/azure-docs/blob/master/articles/static-web-apps/user-information.md):
public static ClaimsPrincipal Parse(HttpRequest req)
{
var principal = new ClientPrincipal();
if (req.Headers.TryGetValue("x-ms-client-principal", out var header))
{
var data = header[0];
var decoded = Convert.FromBase64String(data);
// Use UTF-8 Encoding
// var json = Encoding.ASCII.GetString(decoded);
var json = Encoding.UTF8.GetString(decoded);
principal = JsonSerializer.Deserialize<ClientPrincipal>(json, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
}
principal.UserRoles = principal.UserRoles?.Except(new string[] { "anonymous" }, StringComparer.CurrentCultureIgnoreCase);
if (!principal.UserRoles?.Any() ?? true)
{
return new ClaimsPrincipal();
}
var identity = new ClaimsIdentity(principal.IdentityProvider);
identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, principal.UserId));
identity.AddClaim(new Claim(ClaimTypes.Name, principal.UserDetails));
identity.AddClaims(principal.UserRoles.Select(r => new Claim(ClaimTypes.Role, r)));
return new ClaimsPrincipal(identity);
}
Thanks for pointing this out. Looks like Static Web Apps is using UTF8 to encode the client principal, so it's probably more correct for the emulator to encode as UTF8 and for the Functions code samples to use UTF8 when decoding.
@anthonychu Thanks for investigating.
Do you think we should:
- Mark this issue as a CLI bug (for the
saveCookieproblem)? - Create a docs issue for the ClaimsPrinicpal sample?