重要提示:现在有比我的答案更好的消息来源了.请点击此答案最后一部分中提供的链接.
我使用API/IdentityServer4/Blazor(服务器端)进行了类似的设置.我将向您展示一些我使用的代码,也许您可以利用它.
I've got a similar setup with API / IdentityServer4 / Blazor(server-side). I'll show you some of the code I used, maybe you can make some use of it.
使用NuGet包Microsoft.AspNetCore.Authentication.OpenIdConnect,我在Startup类的ConfigureServices方法中获得了以下代码:
Using the NuGet Package Microsoft.AspNetCore.Authentication.OpenIdConnect, I've got this code in the ConfigureServices method in the Startup class:
services.AddAuthentication(options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies")
.AddOpenIdConnect("oidc", options =>
{
options.Authority = "https://localhost:5001";
options.ClientId = "myClient";
options.ClientSecret = "mySecret";
options.ResponseType = "code id_token";
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.Scope.Add("MyApi");
options.Scope.Add("offline_access");
options.ClaimActions.MapJsonKey("website", "website");
});
以及在Configure方法app.UseAuthentication();
and in the Configure method app.UseAuthentication();
然后在App.razor中,我使用了CascadingAuthenticationState组件:
Then in App.razor i used the CascadingAuthenticationState component:
<CascadingAuthenticationState>
<Router AppAssembly="typeof(Startup).Assembly" />
</CascadingAuthenticationState>
在我的主页Index.razor中使用NuGet包Microsoft.AspNetCore.Authorization:
And using the NuGet package Microsoft.AspNetCore.Authorization in my main page Index.razor:
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize]
现在,当您打开主页时,它应该显示未经身份验证",但是仍然没有重定向到IdentityServer4.为此,您还必须在启动时添加MVC,正如我从
Now it should say "Not authenticated" when you open the main page but there's still no redirection to the IdentityServer4. For this you've got to add MVC in the startup too, as I learned from this *** question:
services.AddMvcCore(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
});
现在,应该在启动应用程序后将您重定向到IdentityServer4进行登录.就我而言,我有一个ApiClient,它描述了我的API的方法.我使用DI注入ApiClient并添加访问令牌:
Now you should be getting redirected to IdentityServer4 to log in after starting the application. In my case I've got an ApiClient, which describes the methods of my API. I use DI to inject the ApiClient and add the access token:
services.AddHttpClient<IApiClient, ApiClient>(async (serviceProvider, client) =>
{
var httpContextAccessor = serviceProvider.GetService<IHttpContextAccessor>();
var accessToken = await httpContextAccessor.HttpContext.GetTokenAsync("access_token");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
client.BaseAddress = new Uri("http://localhost:55578");
});
就像您说的那样,除了关于***的一些答案以外,没有太多关于此主题的文档.我花了很长时间来设置它,所以我希望我可以在这篇文章中对其他人有所帮助.
Like you said, there is not much documentation on this topic except some answers here on ***. It took me a long time to set this up, so I hope I can help someone else with this post.
更新:注销过程
使用此设置注销要绕过剃须刀页面,因为在加载blazor组件后无法访问HttpContext.
Logging out with this setup requires a detour to a razor page because the HttpContext is inaccessible after the blazor component is loaded.
在Pages文件夹中创建一个新的Razor Page,并将以下代码添加到新创建的Logout.cshtml.cs
:
Create a new Razor Page in the Pages folder and add the following code to the newly created Logout.cshtml.cs
:
public class LogoutModel : PageModel
{
public async void OnGetAsync()
{
await HttpContext.SignOutAsync("Cookies");
var prop = new AuthenticationProperties()
{
RedirectUri = "http://localhost:62909"
};
await HttpContext.SignOutAsync("oidc", prop);
}
}
在某处添加一个注销按钮,该按钮依赖于@inject IUriHelper UriHelper
调用函数UriHelper.NavigateTo("/Logout")
.完成!
Add a logout button somewhere which calls the function UriHelper.NavigateTo("/Logout")
relying on @inject IUriHelper UriHelper
. Done!
更新:登录解决方法
前面描述的登录过程在本地工作,但是发布到测试服务器后,我遇到了问题,在AddHttpClient
方法中IHttpContextAccessor
始终为null.因此,我最终使用了与注销过程相同的解决方法.我让IdentityServer重定向到一个剃刀页面(始终具有HttpContext),将访问令牌保存在用户声明中,然后重定向到索引页面.在AddHttpClient
方法中,我仅从用户声明中获取令牌并将其放入身份验证标头中.
The previously described login process worked locally but after publishing to the test server, I had the problem, that the IHttpContextAccessor
was always null inside the AddHttpClient
method. So I ended up using the same workaround as with the logout process. I let the IdentityServer redirect to a razor page (which always has a HttpContext), save the access token in the user claim and redirect to the index page. In the AddHttpClient
method I only get the token from the user claim and put it into the authentication header.
更新:未解决的问题
我仍然很难在我们的服务器上运行此设置.我打开了这个问题和 https://mcguirev10.com/2019/12/15/blazor-authentication-with-openid-connect.html
https://wellsb.com/csharp/aspnet/blazor-consume -identityserver4-protected-api/
I still struggle to get this setup working on our server. I opened this issue and requirement on the AspNetCore Github but both got closed without a proper answer. For the time being, I found some blogs that give a good overview of the current state of the topic:
https://mcguirev10.com/2019/12/15/blazor-authentication-with-openid-connect.html
https://wellsb.com/csharp/aspnet/blazor-consume-identityserver4-protected-api/