728x90
반응형
728x170
[TestIdentityServer 프로젝트]
▶ Properties/launchSettings.json
{
"iisSettings" :
{
"windowsAuthentication" : false,
"anonymousAuthentication" : true,
"iisExpress" :
{
"applicationUrl" : "http://localhost:50000",
"sslPort" : 44300
}
},
"profiles" :
{
"IIS Express" :
{
"commandName" : "IISExpress",
"launchBrowser" : true,
"environmentVariables" :
{
"ASPNETCORE_ENVIRONMENT" : "Development"
}
},
"TestAuthorizationServer" :
{
"commandName" : "Project",
"launchBrowser" : true,
"applicationUrl" : "https://localhost:5001;http://localhost:5000",
"environmentVariables" :
{
"ASPNETCORE_ENVIRONMENT" : "Development"
}
}
}
}
728x90
▶ Program.cs
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace TestIdentityServer
{
/// <summary>
/// 프로그램
/// </summary>
public class Program
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Public
#region 프로그램 시작하기 - Main(argumentArray)
/// <summary>
/// 프로그램 시작하기
/// </summary>
/// <param name="argumentArray">인자 배열</param>
public static void Main(string[] argumentArray)
{
IHost host = CreateHostBuilder(argumentArray).Build();
using(IServiceScope scope = host.Services.CreateScope())
{
UserManager<IdentityUser> userManager = scope.ServiceProvider.GetRequiredService<UserManager<IdentityUser>>();
IdentityUser user = new IdentityUser("alice");
userManager.CreateAsync(user, "alice").GetAwaiter();
}
host.Run();
}
#endregion
#region 호스트 빌더 생성하기 - CreateHostBuilder(argumentArray)
/// <summary>
/// 호스트 빌더 생성하기
/// </summary>
/// <param name="argumentArray">인자 배열</param>
/// <returns>호스트 빌더</returns>
public static IHostBuilder CreateHostBuilder(string[] argumentArray) =>
Host.CreateDefaultBuilder(argumentArray)
.ConfigureWebHostDefaults
(
builder =>
{
builder.UseStartup<Startup>();
}
);
#endregion
}
}
300x250
▶ Configuration.cs
using System.Collections.Generic;
using IdentityModel;
using IdentityServer4;
using IdentityServer4.Models;
namespace TestIdentityServer
{
/// <summary>
/// 구성
/// </summary>
public static class Configuration
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Public
#region 신원 리소스 리스트 구하기 - GetIdentityResourceList()
/// <summary>
/// 신원 리소스 리스트 구하기
/// </summary>
/// <returns>신원 리소스 리스트</returns>
public static List<IdentityResource> GetIdentityResourceList()
{
return new List<IdentityResource>()
{
new IdentityResources.OpenId(),
new IdentityResources.Profile()
};
}
#endregion
#region API 범위 리스트 구하기 - GetAPIScopeList()
/// <summary>
/// API 범위 리스트 구하기
/// </summary>
/// <returns>API 범위 리스트</returns>
public static List<ApiScope> GetAPIScopeList()
{
return new List<ApiScope>
{
new ApiScope("API1", "API 1"),
new ApiScope("API2", "API 2")
};
}
#endregion
#region 클라이언트 리스트 구하기 - GetClientList()
/// <summary>
/// 클라이언트 리스트 구하기
/// </summary>
/// <returns>클라이언트 리스트</returns>
public static List<Client> GetClientList()
{
return new List<Client>
{
new Client
{
AllowedGrantTypes = GrantTypes.ClientCredentials,
ClientId = "CLIENTID0002",
ClientSecrets = { new Secret("CLIENTSECRET0002".ToSha256()) },
AllowedScopes = new List<string> { "API1" }
},
new Client
{
AllowedGrantTypes = GrantTypes.Code,
ClientId = "CLIENTID0003",
ClientSecrets = { new Secret("CLIENTSECRET0003".ToSha256()) },
RedirectUris = { "https://localhost:44330/signin-oidc" },
AllowedScopes = new List<string>
{
"API1",
"API2",
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile
},
RequireConsent = false
}
};
}
#endregion
}
}
▶ Data/DatabaseContext.cs
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
namespace TestIdentityServer.Data
{
/// <summary>
/// 데이터베이스 컨텍스트
/// </summary>
public class DatabaseContext : IdentityDbContext
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - DatabaseContext(options)
/// <summary>
/// 생성자
/// </summary>
/// <param name="options">데이터베이스 컨텍스트 옵션</param>
public DatabaseContext(DbContextOptions<DatabaseContext> options) : base(options)
{
}
#endregion
}
}
▶ Startup.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using TestIdentityServer.Data;
namespace TestIdentityServer
{
/// <summary>
/// 시작
/// </summary>
public class Startup
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 서비스 컬렉션 구성하기 - ConfigureServices(services)
/// <summary>
/// 서비스 컬렉션 구성하기
/// </summary>
/// <param name="services">서비스 컬렉션</param>
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<DatabaseContext>(options => { options.UseInMemoryDatabase("MemoryDB"); });
services.AddIdentity<IdentityUser, IdentityRole>
(
options =>
{
options.Password.RequiredLength = 4;
options.Password.RequireDigit = false;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireUppercase = false;
}
)
.AddEntityFrameworkStores<DatabaseContext>()
.AddDefaultTokenProviders();
services.ConfigureApplicationCookie
(
options =>
{
options.Cookie.Name = "IdentityServer.Cookie";
options.LoginPath = "/Auth/Login";
}
);
services.AddIdentityServer()
.AddAspNetIdentity<IdentityUser>()
.AddInMemoryIdentityResources(Configuration.GetIdentityResourceList())
.AddInMemoryApiScopes(Configuration.GetAPIScopeList())
.AddInMemoryClients(Configuration.GetClientList())
.AddDeveloperSigningCredential();
services.AddControllersWithViews();
}
#endregion
#region 구성하기 - Configure(app, environment)
/// <summary>
/// 구성하기
/// </summary>
/// <param name="app">애플리케이션 빌더</param>
/// <param name="environment">웹 호스트 환경</param>
public void Configure(IApplicationBuilder app, IWebHostEnvironment environment)
{
if(environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseIdentityServer();
app.UseEndpoints
(
endpoints =>
{
endpoints.MapDefaultControllerRoute();
}
);
}
#endregion
}
}
▶ Models/LoginViewModel.cs
namespace TestIdentityServer.Models
{
/// <summary>
/// 로그인 뷰 모델
/// </summary>
public class LoginViewModel
{
////////////////////////////////////////////////////////////////////////////////////////// Property
//////////////////////////////////////////////////////////////////////////////// Public
#region 사용자명 - UserName
/// <summary>
/// 사용자명
/// </summary>
public string UserName { get; set; }
#endregion
#region 패스워드 - Password
/// <summary>
/// 패스워드
/// </summary>
public string Password { get; set; }
#endregion
#region 반환 URL - ReturnURL
/// <summary>
/// 반환 URL
/// </summary>
public string ReturnURL { get; set; }
#endregion
}
}
▶ Models/RegisterViewModel.cs
using System.ComponentModel.DataAnnotations;
namespace TestIdentityServer.Models
{
/// <summary>
/// 등록 뷰 모델
/// </summary>
public class RegisterViewModel
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Property
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 사용자명 - UserName
/// <summary>
/// 사용자명
/// </summary>
[Required]
public string UserName { get; set; }
#endregion
#region 패스워드 - Password
/// <summary>
/// 패스워드
/// </summary>
[Required]
[DataType(DataType.Password)]
public string Password { get; set; }
#endregion
#region 확인 패스워드 - ConfirmPassword
/// <summary>
/// 확인 패스워드
/// </summary>
[Required]
[DataType(DataType.Password)]
[Compare("Password")]
public string ConfirmPassword { get; set; }
#endregion
#region 반환 URL - ReturnURL
/// <summary>
/// 반환 URL
/// </summary>
public string ReturnURL { get; set; }
#endregion
}
}
▶ Controllers/AuthController.cs
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
using TestIdentityServer.Models;
namespace TestIdentityServer.Controllers
{
/// <summary>
/// 인증 컨트롤러
/// </summary>
public class AuthController : Controller
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// 사용자 관리자
/// </summary>
private UserManager<IdentityUser> userManager;
/// <summary>
/// 서명 관리자
/// </summary>
private SignInManager<IdentityUser> signInManager;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - AuthController(userManager, signInManager)
/// <summary>
/// 생성자
/// </summary>
/// <param name="userManager">사용자 관리자</param>
/// <param name="signInManager">서명 관리자</param>
public AuthController(UserManager<IdentityUser> userManager, SignInManager<IdentityUser> signInManager)
{
this.userManager = userManager;
this.signInManager = signInManager;
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 로그인 페이지 처리하기 - Login(returnURL)
/// <summary>
/// 로그인 페이지 처리하기
/// </summary>
/// <param name="returnURL">반환 URL</param>
/// <returns>액션 결과</returns>
[HttpGet]
public IActionResult Login(string returnURL)
{
return View(new LoginViewModel { ReturnURL = returnURL });
}
#endregion
#region 로그인 페이지 처리하기 - Login(vm)
/// <summary>
/// 로그인 페이지 처리하기
/// </summary>
/// <param name="vm">로그인 뷰 모델</param>
/// <returns>액션 결과</returns>
[HttpPost]
public async Task<IActionResult> Login(LoginViewModel vm)
{
Microsoft.AspNetCore.Identity.SignInResult result = await this.signInManager.PasswordSignInAsync(vm.UserName, vm.Password, false, false);
if(result.Succeeded)
{
return Redirect(vm.ReturnURL);
}
return View();
}
#endregion
#region 등록 페이지 처리하기 - Register(returnURL)
/// <summary>
/// 등록 페이지 처리하기
/// </summary>
/// <param name="returnURL">반환 URL</param>
/// <returns>액션 결과</returns>
[HttpGet]
public IActionResult Register(string returnURL)
{
return View(new RegisterViewModel { ReturnURL = returnURL });
}
#endregion
#region 등록 페이지 처리하기 - Register(vm)
/// <summary>
/// 등록 페이지 처리하기
/// </summary>
/// <param name="vm">등록 뷰 모델</param>
/// <returns>액션 결과</returns>
[HttpPost]
public async Task<IActionResult> Register(RegisterViewModel vm)
{
if(!ModelState.IsValid)
{
return View(vm);
}
IdentityUser identityUser = new IdentityUser(vm.UserName);
IdentityResult result = await this.userManager.CreateAsync(identityUser, vm.Password);
if(result.Succeeded)
{
await this.signInManager.SignInAsync(identityUser, false);
return Redirect(vm.ReturnURL);
}
return View();
}
#endregion
}
}
▶ Views/Auth/Login.cshtml
@model LoginViewModel
<h1>신원 서버 인증 로그인 페이지</h1>
<hr />
<form asp-controller="Auth" asp-action="Login" method="post">
<input type="hidden" asp-for="ReturnURL" />
<div>
<label>사용자명</label>
<input asp-for="UserName" />
</div>
<div>
<label>패스워드</label>
<input asp-for="Password" />
</div>
<div>
<button type="submit">로그인</button>
</div>
</form>
<div>
<a asp-controller="Auth" asp-action="Register" asp-route-returnURL="@Model.ReturnURL">등록하기</a>
</div>
▶ Views/Auth/Register.cshtml
@model RegisterViewModel
<h1>신원 서버 인증 등록 페이지</h1>
<hr />
<form asp-controller="Auth" asp-action="Register" method="post">
<input type="hidden" asp-for="ReturnURL" />
<div>
<label>사용자명</label>
<input asp-for="UserName" />
<span asp-validation-for="UserName"></span>
</div>
<div>
<label>패스워드</label>
<input asp-for="Password" />
<span asp-validation-for="Password"></span>
</div>
<div>
<label>패스워드 확인</label>
<input asp-for="ConfirmPassword" />
<span asp-validation-for="ConfirmPassword"></span>
</div>
<div>
<button type="submit">등록</button>
</div>
</form>
<div>
<a asp-controller="Auth" asp-action="Login" asp-route-returnURL="@Model.ReturnURL">로그인 페이지로 돌아가기</a>
</div>
[TestClient 프로젝트]
▶ Properties/launchSettings.json
{
"iisSettings" :
{
"windowsAuthentication" : false,
"anonymousAuthentication" : true,
"iisExpress" :
{
"applicationUrl" : "http://localhost:50030",
"sslPort" : 44330
}
},
"profiles" :
{
"IIS Express" :
{
"commandName" : "IISExpress",
"launchBrowser" : true,
"environmentVariables" :
{
"ASPNETCORE_ENVIRONMENT" : "Development"
}
},
"TestAuthorizationServer" :
{
"commandName" : "Project",
"launchBrowser" : true,
"applicationUrl" : "https://localhost:5001;http://localhost:5000",
"environmentVariables" :
{
"ASPNETCORE_ENVIRONMENT" : "Development"
}
}
}
}
▶ Startup.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace TestClient
{
/// <summary>
/// 시작
/// </summary>
public class Startup
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 서비스 컬렉션 구성하기 - ConfigureServices(services)
/// <summary>
/// 서비스 컬렉션 구성하기
/// </summary>
/// <param name="services">서비스 컬렉션</param>
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication
(
options =>
{
options.DefaultScheme = "Cookie";
options.DefaultChallengeScheme = "oidc";
}
)
.AddCookie("Cookie")
.AddOpenIdConnect
(
"oidc",
options =>
{
options.Authority = "https://localhost:44300/";
options.ClientId = "CLIENTID0003";
options.ClientSecret = "CLIENTSECRET0003";
options.SaveTokens = true;
options.ResponseType = "code";
options.Scope.Add("profile");
options.Scope.Add("API1" );
}
);
services.AddControllersWithViews();
}
#endregion
#region 구성하기 - Configure(app, environment)
/// <summary>
/// 구성하기
/// </summary>
/// <param name="app">애플리케이션 빌더</param>
/// <param name="environment">웹 호스트 환경</param>
public void Configure(IApplicationBuilder app, IWebHostEnvironment environment)
{
if(environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints
(
endpoints =>
{
endpoints.MapDefaultControllerRoute();
}
);
}
#endregion
}
}
▶ Controllers/HomeController.cs
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace TestClient.Controllers
{
/// <summary>
/// 홈 컨트롤러
/// </summary>
public class HomeController : Controller
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 인덱스 페이지 처리하기 - Index()
/// <summary>
/// 인덱스 페이지 처리하기
/// </summary>
/// <returns>액션 결과</returns>
public IActionResult Index()
{
return View();
}
#endregion
#region 비밀 페이지 처리하기 - Secret()
/// <summary>
/// 비밀 페이지 처리하기
/// </summary>
/// <returns>액션 결과</returns>
[Authorize]
public IActionResult Secret()
{
return View();
}
#endregion
}
}
▶ Views/Home/Index.cshtml
<h1>클라이언트 홈 인덱스 페이지</h1>
<hr />
▶ Views/Home/Secret.cshtml
<h1>클라이언트 홈 비밀 페이지</h1>
<hr />
728x90
반응형
그리드형(광고전용)
댓글을 달아 주세요