2023-08-02 22:25:13 +08:00

173 lines
6.7 KiB
C#

using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi.Models;
using NCaptcha.AspNetCore.SessionImages;
using IGeekFan.AspNetCore.Knife4jUI;
using Microsoft.AspNetCore.Mvc.Controllers;
namespace OAuth2Integration
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// Register IdentityServer services to power OAuth2.0 flows
services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddInMemoryClients(AuthServer.Config.Clients())
.AddInMemoryApiResources(AuthServer.Config.ApiResources())
.AddTestUsers(AuthServer.Config.TestUsers());
// The auth setup is a little nuanced because this app provides the auth-server & the resource-server
// Use the "Cookies" scheme by default & explicitly require "Bearer" in the resource-server controllers
// See https://docs.microsoft.com/en-us/aspnet/core/security/authorization/limitingidentitybyscheme?tabs=aspnetcore2x
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie()
.AddIdentityServerAuthentication(c =>
{
c.Authority = "http://localhost:5000/auth-server/";
c.RequireHttpsMetadata = false;
c.ApiName = "api";
});
// Configure named auth policies that map directly to OAuth2.0 scopes
services.AddAuthorization(c =>
{
c.AddPolicy("readAccess", p => p.RequireClaim("scope", "readAccess"));
c.AddPolicy("writeAccess", p => p.RequireClaim("scope", "writeAccess"));
});
services.AddControllersWithViews();
services.AddSession();
services.AddSessionBasedImageCaptcha();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Version = "v1", Title = "Test API V1" });
//// Define the OAuth2.0 scheme that's in use (i.e. Implicit Flow)
//c.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
//{
// Type = SecuritySchemeType.OAuth2,
// Flows = new OpenApiOAuthFlows
// {
// AuthorizationCode = new OpenApiOAuthFlow
// {
// AuthorizationUrl = new Uri("/auth-server/connect/authorize", UriKind.Relative),
// TokenUrl = new Uri("/auth-server/connect/token", UriKind.Relative),
// Scopes = new Dictionary<string, string>
// {
// { "readAccess", "Access read operations" },
// { "writeAccess", "Access write operations" }
// }
// }
// }
//});
c.CustomOperationIds(apiDesc =>
{
var controllerAction = apiDesc.ActionDescriptor as ControllerActionDescriptor;
return controllerAction.ControllerName + "-" + controllerAction.ActionName;
});
c.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "oauth2" }
},
new[] { "readAccess", "writeAccess" }
}
});
// Assign scope requirements to operations based on AuthorizeAttribute
//c.OperationFilter<SecurityRequirementsOperationFilter>();
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseSession();
app.Map("/auth-server", authServer =>
{
authServer.UseRouting();
authServer.UseAuthentication();
authServer.UseIdentityServer();
authServer.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
});
app.Map("/resource-server", resourceServer =>
{
resourceServer.UseRouting();
resourceServer.UseAuthentication();
resourceServer.UseAuthorization();
resourceServer.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
resourceServer.UseSwagger();
app.UseKnife4UI(c =>
{
c.RoutePrefix = ""; //http://localhost:5000/index.html#/home
c.SwaggerEndpoint("/resource-server/swagger/v1/swagger.json", "My API V1");
c.EnableDeepLinking();
c.OAuthClientId("test-id");
c.OAuthClientSecret("test-secret");
c.OAuthAppName("test-app");
c.OAuthScopeSeparator(" ");
c.OAuthUsePkce();
});
resourceServer.UseSwaggerUI(c =>
{
//http://localhost:5000/resource-server/swagger/index.html
c.SwaggerEndpoint("/resource-server/swagger/v1/swagger.json", "My API V1");
c.EnableDeepLinking();
// Additional OAuth settings (See https://github.com/swagger-api/swagger-ui/blob/v3.10.0/docs/usage/oauth2.md)
c.OAuthClientId("test-id");
c.OAuthClientSecret("test-secret");
c.OAuthAppName("test-app");
c.OAuthScopeSeparator(" ");
c.OAuthUsePkce();
});
});
}
}
}