Я пытаюсь создать небольшое демонстрационное приложение для электронной коммерции, используя. net основной API 3.1 с сервером идентификации 4.
Config.cs (проект Demo.Auth)
public static class Config
{
public static IEnumerable<IdentityResource> Ids =>
new IdentityResource[]
{
new IdentityResources.Profile(),
};
public static IEnumerable<ApiResource> ApiResources => new[]
{
new ApiResource("Demo.Api", "Demo Api")
};
public static IEnumerable<Client> Clients => new[]
{
new Client()
{
ClientId = "mvc",
ClientName = "Demo.MvcClient",
AllowedGrantTypes = GrantTypes.ClientCredentials,
RequirePkce = true,
ClientSecrets =
{
new Secret("49C1A7E1-0C79-4A89-A3D6-A37998FB86B0".Sha256())
},
RedirectUris = {"http://localhost:5003/signin-oidc"},
FrontChannelLogoutUri = "http://localhost:5003/signout-oidc",
PostLogoutRedirectUris = {"http://localhost:5003/signout-callback-oidc"},
AllowOfflineAccess = true,
AllowedScopes = {"profile"}
}
};
}
Startup.cs (проект Demo.Auth)
public class Startup
{
// 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.AddControllersWithViews();
IConfigurationRoot config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.Build();
string identityConnectionString = config.GetSection("ConnectionStrings")
.Value;
var migratingAssembly = typeof(Startup).GetTypeInfo()
.Assembly.GetName()
.Name;
if (config.GetValue<bool>("UseInMemoryDatabase"))
{
services.AddIdentityServer(options =>
{
options.Events.RaiseErrorEvents = true;
options.Events.RaiseInformationEvents = true;
options.Events.RaiseFailureEvents = true;
options.Events.RaiseSuccessEvents = true;
})
.AddTestUsers(TestUsers.Users)
.AddInMemoryIdentityResources(Config.Ids)
.AddInMemoryApiResources(Config.ApiResources)
.AddInMemoryClients(Config.Clients)
.AddDeveloperSigningCredential();
}
else
{
services.AddIdentityServer(options =>
{
options.Events.RaiseErrorEvents = true;
options.Events.RaiseInformationEvents = true;
options.Events.RaiseFailureEvents = true;
options.Events.RaiseSuccessEvents = true;
})
.AddTestUsers(TestUsers.Users)
.AddDeveloperSigningCredential()
//This will store client and ApiResource
.AddConfigurationStore(options =>
{
options.ConfigureDbContext = b => b.UseSqlServer(identityConnectionString,
sql => sql.MigrationsAssembly(migratingAssembly));
})
//This will store token, consent or code
.AddOperationalStore(options =>
{
options.ConfigureDbContext = b => b.UseSqlServer(identityConnectionString,
sql => sql.MigrationsAssembly(migratingAssembly));
});
}
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app,
IWebHostEnvironment env)
{
// this will do the initial DB population
// InitializeDatabase(app);
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
app.UseRouting();
app.UseIdentityServer();
app.UseEndpoints(endpoints =>
{
endpoints.MapGet("/",
async context => { await context.Response.WriteAsync("Hello World!"); });
});
}
}
Startup.cs (проект API)
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)
{
services.AddAuthentication("Bearer").AddIdentityServerAuthentication(options =>
{
options.Authority = "http://localhost:5000";
options.RequireHttpsMetadata = false;
options.ApiName = "Demo.Api";
});
services.AddControllers();
}
// 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.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
}
}
WeatherForecastController (проекта Demo.Api)
[Authorize]
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
[HttpGet]
public IEnumerable<WeatherForecast> Get()
{
var rng = new Random();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)]
})
.ToArray();
}
}
Я тестирую API в почтальоне, и он работает нормально. Проект «Demo.Auth» генерирует токен, и я могу успешно получить доступ к своему контроллеру авторизации.
Идея здесь:
MVC Клиент ----> Проект сервера идентификации - -> API
MVC клиент хочет получить доступ к API. Итак, я аутентифицирую клиента Mvc в проекте сервера идентификации, сгенерирую токен, если он действительный пользователь, и затем вызову свой api.
Примечание: в настоящее время я использую клиент MVC, но позже я добавлю еще одного клиента, может быть Angular.
Но у меня есть вопросы.
Как можно Я добавляю пользователей в свою базу данных и аутентифицирую пользователя базы данных, а не тестируемого.
Еще я не понимаю, где мне разместить функции входа и регистрации и как будет выглядеть этот код.
Я новичок в сервере идентификации, пожалуйста, извините.
Может ли кто-нибудь помочь мне ответить на мой вопрос с помощью кода? Заранее спасибо