Hi,
I am wondering if anyone has tried (successfully) to setup OAuth in a Blazor Web Assembly. I think I have things configured based on the documentation but continue to get an error saying it is not setup correct. Without any specifics.
Thanks - joe
Awesome @joe !! thanks for taking the time to share the solution 🙂
In the end is pretty straight forward. The simplest way is to simply get a token directly from a call to the /authorize method. This was done by navigating to the authorize Url in the OnInitialized method of the Index.razor page
protected override void OnInitialized() { try { string authorizeUrl = "https://www.arcgis.com/sharing/rest/oauth2/authorize"; string clientId = Configuration["Authorization:clientId"]!.ToString(); string redirectUrl = Configuration["Authorization:redirectUrl"]!.ToString(); string responseType = "token"; UriBuilder builder = new UriBuilder(authorizeUrl) { Query = $"client_id={clientId}&redirect_uri={redirectUrl}&response_type={responseType}" }; string oAuthUrl = builder.ToString(); NavigationManager.NavigateTo(oAuthUrl); } catch (Exception e) { Console.WriteLine(e); } }
Then in the page defined in the redirectUrl you grab the token from the return returned url
protected override void OnInitialized() { try { _token = Navigation.Uri.Substring(Navigation.Uri.IndexOf("=", StringComparison.Ordinal) + 1); } catch (Exception e) { Console.WriteLine(e); } }
An approach which I think is a bit more secure would involve requesting code from /authorize method and then getting the token in the redirect page using the /token method. In this case in the Index.razor we have
protected override void OnInitialized() { try { string authorizeUrl = "https://www.arcgis.com/sharing/rest/oauth2/authorize"; string clientId = Configuration["Authorization:clientId"]!.ToString(); string redirectUrl = Configuration["Authorization:redirectUrl"]!.ToString(); string responseType = "code"; string codeChallenge = CreateChallangeCode(); string codeChallengeMethod = "plain"; UriBuilder builder = new UriBuilder(authorizeUrl) { Query = $"client_id={clientId}&redirect_uri={redirectUrl}&response_type={responseType}&code_challenge={codeChallenge}&code_challenge_method={codeChallengeMethod}" }; string oAuthUrl = builder.ToString(); NavigationManager.NavigateTo(oAuthUrl); } catch (Exception e) { Console.WriteLine(e); } } private string CreateChallangeCode() { using SHA256 sha256 = SHA256.Create(); byte[] data = sha256.ComputeHash(Encoding.UTF8.GetBytes("blazor")); var builder = new StringBuilder(); // Loop through each byte of the hashed data // and format each one as a hexadecimal string. foreach (var b in data) { builder.Append(b.ToString("x2")); } return builder.ToString(); }
and in the redirect page get the token from the returned code
protected override async void OnInitialized() { try { string code = Navigation.Uri.Substring(Navigation.Uri.IndexOf("=", StringComparison.Ordinal) + 1); await RequestToken(code); } catch (Exception e) { Console.WriteLine(e); } } private async Task RequestToken(string code) { string tokenUrl = "https://www.arcgis.com/sharing/rest/oauth2/token"; string clientId = Configuration["Authorization:clientId"]!; string redirectUrl = Configuration["Authorization:redirectUrl"]!; string codeChallenge = CreateCodeChallenge(); var dictionary = new Dictionary<string, string> { { "client_id", clientId }, { "grant_type", "authorization_code" }, { "code", code! }, { "code_verifier", codeChallenge }, { "redirect_uri", redirectUrl } }; FormUrlEncodedContent content = new FormUrlEncodedContent(dictionary); using HttpClient client = new HttpClient(); var response = await client.PostAsync(tokenUrl, content); var json = await response.Content.ReadAsStringAsync(); JsonNode node = JsonNode.Parse(json)!; _token = node!["access_token"]!.ToString(); }
I haven't @joe but if you solve it let us know how!!
Thanks and good luck!
Signed in members can post, follow updates, and more. New here? Register a free account.
Find useful guides, FAQs, and documents to help you navigate and make the most of Esri Community.