C# 带AzureAD的Blazor WebAssembly
我需要让我正在开发的WebAssembly应用程序的用户通过AzureAD登录。 我正在使用repo(和UI) 以下是我迄今为止所做的: appsetting.jsonC# 带AzureAD的Blazor WebAssembly,c#,asp.net-core,cors,azure-active-directory,blazor-client-side,C#,Asp.net Core,Cors,Azure Active Directory,Blazor Client Side,我需要让我正在开发的WebAssembly应用程序的用户通过AzureAD登录。 我正在使用repo(和UI) 以下是我迄今为止所做的: appsetting.json "AzureAd": { "Instance": "https://login.microsoftonline.com", "Domain": "xxx", "TenantId": "xxx", "ClientId": "xxx", "CallbackPath": "/signin-oi
"AzureAd": {
"Instance": "https://login.microsoftonline.com",
"Domain": "xxx",
"TenantId": "xxx",
"ClientId": "xxx",
"CallbackPath": "/signin-oidc",
"SignedOutCallbackPath ": "/signout-callback-oidc",
"ClientSecret": "xxx"
},
服务器端启动.cs
public class Startup
{
public IConfiguration Configuration { get; }
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddResponseCompression(opts =>
{
opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(
new[] { "application/octet-stream" });
});
// Sign-in users with the Microsoft identity platform
//services.AddSignIn(Configuration);
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddSignIn("AzureAD", Configuration, options => Configuration.Bind("AzureAD", options));
// Looks like I need this to have the login UI
services.AddControllersWithViews(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
}).AddMicrosoftIdentityUI();
services.AddRazorPages();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseResponseCompression();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseBlazorDebugging();
}
app.UseCors();
app.UseStaticFiles();
app.UseClientSideBlazorFiles<Client.Program>();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
endpoints.MapFallbackToClientSideBlazor<Client.Program>("index.html");
});
}
}
客户端程序.cs
public class Program
{
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
// Use our CustomAuthenticationProvider as the
// AuthenticationStateProvider
builder.Services.AddScoped<AuthenticationStateProvider, CustomAuthenticationProvider>();
// Add Authentication support
builder.Services.AddOptions();
builder.Services.AddAuthorizationCore();
builder.RootComponents.Add<App>("app");
await builder.Build().RunAsync();
}
}
public class CustomAuthenticationProvider : AuthenticationStateProvider
{
private readonly HttpClient _httpClient;
public CustomAuthenticationProvider(HttpClient httpClient)
{
_httpClient = httpClient;
}
public override async Task<AuthenticationState> GetAuthenticationStateAsync()
{
ClaimsPrincipal user;
// Call the GetUser method to get the status
// This only sets things like the AuthorizeView
// and the AuthenticationState CascadingParameter
var result = await _httpClient.GetJsonAsync<AppUser>("api/user");
// Was a UserName returned?
if (result.UserName != "")
{
// Create a ClaimsPrincipal for the user
var identity = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.Name, result.UserName),
}, "AzureAdAuth");
user = new ClaimsPrincipal(identity);
}
else
{
user = new ClaimsPrincipal(); // Not logged in
}
return await Task.FromResult(new AuthenticationState(user));
}
}
我正试图在服务器端启用CORS,正如前面所解释的,但还没有成功。
我错过了什么?
Blazor WebAssembly的预览版2附带了一个现成的工作模板。
Blazor WebAssembly的预览版2附带了一个现成的工作模板。看起来您的API正在将API调用重定向到AAD。您应该使用MSAL在前端实现身份验证。而且你的API需要支持JWTs和交互式身份验证。因此,如果我理解正确,我应该在Blazor上使用MSAL将身份验证从服务器端移动到客户端。是的,这是JS前端的典型方法:)Blazor在这方面没有什么不同,它是一个富有意义的前端应用程序,我对此感到困惑:看起来您的API正在将API调用重定向到AAD。您应该使用MSAL在前端实现身份验证。而且你的API需要支持JWTs和交互式身份验证。因此,如果我理解正确,我应该在Blazor上使用MSAL将身份验证从服务器端移动到客户端。是的,这是JS前端的典型方法:)Blazor在这方面没有什么不同,它是一个富有意义的前端应用程序,我对此感到困惑:
public class Program
{
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
// Use our CustomAuthenticationProvider as the
// AuthenticationStateProvider
builder.Services.AddScoped<AuthenticationStateProvider, CustomAuthenticationProvider>();
// Add Authentication support
builder.Services.AddOptions();
builder.Services.AddAuthorizationCore();
builder.RootComponents.Add<App>("app");
await builder.Build().RunAsync();
}
}
public class CustomAuthenticationProvider : AuthenticationStateProvider
{
private readonly HttpClient _httpClient;
public CustomAuthenticationProvider(HttpClient httpClient)
{
_httpClient = httpClient;
}
public override async Task<AuthenticationState> GetAuthenticationStateAsync()
{
ClaimsPrincipal user;
// Call the GetUser method to get the status
// This only sets things like the AuthorizeView
// and the AuthenticationState CascadingParameter
var result = await _httpClient.GetJsonAsync<AppUser>("api/user");
// Was a UserName returned?
if (result.UserName != "")
{
// Create a ClaimsPrincipal for the user
var identity = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.Name, result.UserName),
}, "AzureAdAuth");
user = new ClaimsPrincipal(identity);
}
else
{
user = new ClaimsPrincipal(); // Not logged in
}
return await Task.FromResult(new AuthenticationState(user));
}
}
Access to fetch at 'https://login.microsoftonline.com/xxx/oauth2/v2.0/authorize?client_id=xxx&redirect_uri=https%3A%2F%2Flocalhost%3A44316%2Fsignin-oidc&response_type=code%20id_token&scope=openid%20profile%20offline_access%xxx%2Fuser_impersonation&response_mode=form_post&nonce=xxx&x-client-SKU=ID_NETSTANDARD2_0&x-client-ver=5.5.0.0' (redirected from 'https://localhost:44316/api/user') from origin 'https://localhost:44316' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.