WIP separation Web et API

This commit is contained in:
Paul Schneider
2025-02-12 20:41:14 +00:00
parent 6cd5f1d041
commit c2ae054719
55 changed files with 71 additions and 98 deletions

View File

@ -5,6 +5,7 @@
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.12" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.13" />
<ProjectReference Include="../Yavsc/Yavsc.csproj" />
</ItemGroup>
</Project>

View File

@ -30,7 +30,7 @@ namespace Yavsc.WebApi.Controllers
UserManager = userManager;
this.roleManager = roleManager;
_signInManager = signInManager;
_logger = loggerFactory.CreateLogger("ApiAuth");
_logger = loggerFactory.CreateLogger(nameof(ApiAccountController));
_dbContext = dbContext;
}
@ -154,7 +154,7 @@ namespace Yavsc.WebApi.Controllers
return Ok(user);
}
[HttpGet("~/api/myhost")]
[HttpGet("myhost")]
public IActionResult MyHost ()
{
return Ok(new { host = Request.ForHost() });
@ -165,7 +165,7 @@ namespace Yavsc.WebApi.Controllers
/// </summary>
/// <param name="me">MyUpdate containing the new user name </param>
/// <returns>Ok when all is ok.</returns>
[HttpPut("~/api/me")]
[HttpPut("me")]
public async Task<IActionResult> UpdateMe(UserInfo me)
{
if (!ModelState.IsValid) return new BadRequestObjectResult(

View File

@ -44,7 +44,7 @@ internal class Program
.AllowAnyMethod();
});
})
.AddControllers();
.AddControllersWithViews();
// accepts any access token issued by identity server
var authenticationBuilder = services.AddAuthentication()
@ -64,14 +64,22 @@ internal class Program
app
.UseRouting()
.UseAuthentication()
.UseAuthorization()
.UseCors("default");
.UseAuthorization().UseCors("default")
.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute()
.RequireAuthorization();
});
app.MapGet("/identity", (HttpContext context) =>
new JsonResult(context?.User?.Claims.Select(c => new { c.Type, c.Value }))
).RequireAuthorization("ApiScope");
await app.RunAsync();
}
};
}
}

View File

@ -341,19 +341,13 @@ internal static class HostingExtensions
})
.AddCors(options =>
{
options.AddPolicy("CorsPolicy", builder =>
options.AddPolicy("default", builder =>
{
_ = builder.WithOrigins("*")
.AllowAnyHeader()
.AllowAnyMethod();
});
options.AddPolicy("default", policy =>
{
policy.WithOrigins("https://localhost:5003")
.AllowAnyHeader()
.AllowAnyMethod();
});
});
services.AddSingleton<IAuthorizationHandler, PermissionHandler>();
@ -379,6 +373,7 @@ internal static class HostingExtensions
app.UseRouting();
app.UseIdentityServer();
app.UseAuthorization();
app.UseCors("default");
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
@ -399,7 +394,7 @@ internal static class HostingExtensions
payPalSettings, googleAuthSettings, localization, loggerFactory,
app.Environment.EnvironmentName);
app.ConfigureFileServerApp();
return app;
}

View File

@ -17,20 +17,20 @@
<PackageReference Include="Serilog.AspNetCore" Version="8.0.3" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.11" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.Google" Version="8.0.12" />
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="8.0.12" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.12" />
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="8.0.12" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.12">
<PackageReference Include="Microsoft.AspNetCore.Authentication.Google" Version="8.0.13" />
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="8.0.13" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.13" />
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="8.0.13" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.13">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.12">
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.13">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.12" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.12" IncludeAssets="All" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.13" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.13" />
<PackageReference Include="Google.Apis.Compute.v1" Version="1.54.0" />
<PackageReference Include="Microsoft.AspNetCore.SignalR" Version="1.1.0" />
<PackageReference Include="Microsoft.AspNetCore.Razor" Version="2.2.0" />

View File

@ -12,13 +12,13 @@ using Microsoft.AspNetCore.Mvc;
// But, this redirect URI doesn't need to match the OAuth parameter, it's serialized in the query state,
// to be used once the identification ends.
var properties = new AuthenticationProperties { RedirectUri = returnUrl };
return new ChallengeResult("Yavsc", properties);
return new ChallengeResult("oidc", properties);
}
[HttpGet("~/signout")]
public async Task<IActionResult> SignOut(string returnUrl="/") {
return SignOut("Cookies", "Yavsc");
return SignOut("Cookies", "oidc");
}
}

View File

@ -57,7 +57,7 @@ namespace testOauthClient.Controllers
var client = new HttpClient(new HttpClientHandler(){ AllowAutoRedirect=false });
client.DefaultRequestHeaders.Add("Accept", "application/json");
client.SetBearerToken(accessToken);
var content = await client.GetAsync("https://localhost:5001/api/account/me");
var content = await client.GetAsync("https://localhost:6001/api/account/me");
content.EnsureSuccessStatusCode();
var json = await content.Content.ReadAsStreamAsync();
var obj = JsonSerializer.Deserialize<JsonElement>(json);

View File

@ -4,25 +4,17 @@
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:5002",
"applicationUrl": "https://localhost:5003",
"sslPort": 5003
}
},
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "http://localhost:5002",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:5003;http://localhost:5002",
"applicationUrl": "https://localhost:5003;",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}

View File

@ -10,43 +10,43 @@ public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
JwtSecurityTokenHandler.DefaultMapInboundClaims = false;
services.AddAuthentication(options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "Yavsc";
})
.AddCookie("Cookies")
.AddOpenIdConnect("Yavsc", options =>
{
options.Authority = "https://localhost:5001";
options.ClientId = "mvc";
options.ClientSecret = "49C1A7E1-0C79-4A89-A3D6-A37998FB86B0";
options.ResponseType = "code";
options.UsePkce = true;
options.Scope.Clear();
options.Scope.Add("openid");
options.Scope.Add("profile");
options.Scope.Add("email");
options.Scope.Add("offline_access");
options.Scope.Add("scope2");
options.GetClaimsFromUserInfoEndpoint = true;
options.SaveTokens = true;
options.ClaimActions.MapUniqueJsonKey("http://schemas.microsoft.com/ws/2008/06/identity/claims/role", "http://schemas.microsoft.com/ws/2008/06/identity/claims/role");
options.ClaimActions.MapUniqueJsonKey("role", "http://schemas.microsoft.com/ws/2008/06/identity/claims/role");
options.ClaimActions.MapUniqueJsonKey("roles", "http://schemas.microsoft.com/ws/2008/06/identity/claims/role");
options.TokenValidationParameters = new TokenValidationParameters
services
.AddAuthentication(options =>
{
NameClaimType = "name",
RoleClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role"
};
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies")
.AddOpenIdConnect("oidc", options =>
{
options.Authority = "https://localhost:5001";
options.ClientId = "mvc";
options.ClientSecret = "49C1A7E1-0C79-4A89-A3D6-A37998FB86B0";
options.ResponseType = "code";
options.Scope.Add("scope2");
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.SaveTokens = true;
options.ClaimActions.MapUniqueJsonKey(
"http://schemas.microsoft.com/ws/2008/06/identity/claims/role",
"http://schemas.microsoft.com/ws/2008/06/identity/claims/role");
options.ClaimActions.MapUniqueJsonKey("role",
"http://schemas.microsoft.com/ws/2008/06/identity/claims/role");
options.ClaimActions.MapUniqueJsonKey("roles",
"http://schemas.microsoft.com/ws/2008/06/identity/claims/role");
options.TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = "name",
RoleClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role"
};
});
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)

View File

@ -9,9 +9,6 @@
"Kestrel": {
"Endpoints":
{
"Http": {
"Url": "http://localhost:5002"
},
"Https": {
"Url": "https://localhost:5003"
}

View File

@ -2,7 +2,7 @@
<ItemGroup>
<ProjectReference Include="..\Yavsc.Abstract\Yavsc.Abstract.csproj" />
<PackageReference Include="IdentityModel.AspNetCore" Version="4.3.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.12" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.13" />
</ItemGroup>
<ItemGroup>

View File

@ -78,26 +78,6 @@ namespace yavscTests
throw;
}
}
public static IEnumerable<object[]> GetLoginIntentData(int numTests)
{
var allData = new List<object[]>();
allData.Add(new object[] { "blouh", "profile",
"http://localhost:5000/authorize", "http://localhost:5000/oauth/success",
"http://localhost:5000/token", "http://localhost:5000/authorize"});
allData.Add(new object[] { "blouh", "profile",
"http://localhost:5000/authorize", "http://localhost:5000/oauth/success",
"http://localhost:5000/token", "http://localhost:5000/authorize"});
return allData.Take(numTests);;
}
}
}