Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Companion article for BWA OIDC w/Aspire sample app #31265

Closed
guardrex opened this issue Dec 18, 2023 · 2 comments · Fixed by #31555
Closed

Companion article for BWA OIDC w/Aspire sample app #31265

guardrex opened this issue Dec 18, 2023 · 2 comments · Fixed by #31555
Assignees

Comments

@guardrex
Copy link
Collaborator

guardrex commented Dec 18, 2023

https://github.com/dotnet/blazor-samples/tree/main/8.0/BlazorWebAppOidc

Change the sample folder name first. Done! ... BlazorWebAppOidc

@guardrex
Copy link
Collaborator Author

guardrex commented Jan 25, 2024

@travaille-dev ... Here's a revised LogInOrOut component that deals with the redirect problem. It's not particularly elegant relying upon reflection. However, it's a reasonable hack 🙈 until Stephen can get back and tell me how best to solve the problem. As for the IWeatherForecaster service not being on the server for server-side rendering, I'll work on that tomorrow.

@implements IDisposable
@using System.Reflection
@using System.Security.Claims
@using Microsoft.AspNetCore.Authorization
@inject IAuthorizationService AuthorizationService
@inject NavigationManager NavigationManager

<div class="nav-item px-3">
    <AuthorizeView>
        <Authorized>
            <form action="authentication/logout" method="post">
                <AntiforgeryToken />
                <input type="hidden" name="ReturnUrl" value="@currentUrl" />
                <button type="submit" class="nav-link">
                    <span class="bi bi-arrow-bar-left-nav-menu" aria-hidden="true"></span> Logout @context.User.Identity?.Name
                </button>
            </form>
        </Authorized>
        <NotAuthorized>
            <a class="nav-link" href="authentication/login">
                <span class="bi bi-person-badge-nav-menu" aria-hidden="true"></span> Login
            </a>
        </NotAuthorized>
    </AuthorizeView>
</div>

@code {
    private string? currentUrl;
    private ClaimsPrincipal? user;

    [CascadingParameter]
    private Task<AuthenticationState>? authenticationState { get; set; }

    protected override async Task OnInitializedAsync()
    {
        currentUrl = NavigationManager.ToBaseRelativePath(NavigationManager.Uri);
        NavigationManager.LocationChanged += OnLocationChanged;

        if (authenticationState is not null)
        {
            var authState = await authenticationState;
            user = authState?.User;
        }
    }

    private void OnLocationChanged(object? sender, LocationChangedEventArgs e)
    {
        var currentUrl = NavigationManager.ToBaseRelativePath(e.Location);

        if (user?.Identity is not null && user.Identity.IsAuthenticated)
        {
            var matchingAuthComponentCount =
            Assembly.GetExecutingAssembly()
                    .ExportedTypes
                    .Where(t => t.IsSubclassOf(typeof(ComponentBase)))
                    .Any(c => c.GetCustomAttributes(inherit: true)
                                    .OfType<AuthorizeAttribute>()
                                    .Any() &&
                                c.GetCustomAttributes(inherit: true)
                                    .OfType<RouteAttribute>()
                                    .Where(d => d.Template == $"/{currentUrl}")
                                    .Any());

            if (matchingAuthComponentCount)
            {
                currentUrl = string.Empty;
            }
        }

        StateHasChanged();
    }

    public void Dispose()
    {
        NavigationManager.LocationChanged -= OnLocationChanged;
    }
}

@guardrex
Copy link
Collaborator Author

guardrex commented Jan 26, 2024

UPDATE (1/26) ...

  • I created a server implementation of the IWeatherForecaster service and moved the interface to a shared project, but I still ran into some auth problems. My current workaround is just to place <AuthorizeView>...</AuthorizeView> tags around the Weather entry in the NavMenu component, which stops a user from seeing it until they're logged in; therefore, prevents the prerendering error with IWeatherForecaster from ever happening by an unauthenticated user just selecting to navigate to the Weather component, signing in, and then getting a 💥 when they're redirected back to the app. That flow isn't a concern if they can't select the Weather component in the nav sidebar in the first place. I've set the sample apps up that way for now, and we'll see what Stephen wants to do when he gets back.
  • I found a number of good constants to use in the Program file; however, I really want to make the samples use configuration in the end. That's really the best way to manage all of this configuration, not via hard-coding anything into the Program file. I guess I can show both (e.g., place these hard-coded settings into a section at the end of the article for reference), but I think the main demonstration should use configuration. That's what professional production apps do! 😄

@github-project-automation github-project-automation bot moved this from In progress to Done in Blazor.Docs Feb 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

1 participant