이 시리즈의 종합편???
이라고 하기에는 좀 그렇고 합본 정도입니다.
지금까지 샘플은 인증서버와 API 서버가 따로 있는 것을 가정하여 만들어져 있었습니다.
이것은 인증서버를 하나만 두고 여러 API서버를 연동해서 사용할 수 있기 때문입니다.
하지만!
인증서버 하나에 API서버가 하나라면 굳이 따로 만들 필요가 없죠.
이번에는 인증서버와 API서버를 합치도록 하겠습니다.
[ASP.NET Core 2] OAuth2 인증에서 사용까지 (1) - 'IdentityServer'를 이용하여 'OAuth2' 인증 서버 구현
[ASP.NET Core 2] OAuth2 인증에서 사용까지 (2) - 'IdentityServer'를 이용하여 'OAuth2' 인증 받기
[ASP.NET Core 2] OAuth2 인증에서 사용까지 (3) - 'IdentityServer'의 리플레시 토큰(Refresh Token) 사용하기
[ASP.NET Core 2] OAuth2 인증에서 사용까지 (4) - 'IdentityServer'로 만든 인증서버와 'WebAPI' 같이 사용하기
이전 포스팅에서 여러 번 다뤘던 내용이므로 이번 포스팅은 대부분 링크로 대체합니다.
프로젝트는 생성 옵션은
닷넷 코어 2.2
웹 응용프로그램
빈 프로젝트
입니다.
누겟에서 'IdentityServer4'를 찾아 설치합니다.
우리는 Core 2.2 가 기준이라 2.x 버전을 설치해야 합니다.
누겟에서 'IdentityServer4.AccessTokenValidation' 찾아 설치합니다.
우리는 Core 2.2 가 기준이라 2.x 버전을 설치해야 합니다.
여기에 'JQuery'의 CDN 주소를 추가합니다.
1) 토큰을 요청하는 함수
2) 토큰 갱신을 요청하는 함수
3) API를 요청하는 함수
이렇게 3개의 함수를 추가합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> <script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script> <script> var sUrl = "https://localhost:44350"; var access_token = ""; var refresh_token = ""; /** 토큰 요청 */ function CallToken() { $.ajax({ type: "POST" , url: sUrl + "/connect/token" , data: { "grant_type": "password" , "client_id": "resourceownerclient" , "client_secret": "dataEventRecordsSecret" , "scope": "dataEventRecords offline_access" , "username": "raphael" , "password": "raphael" } , dataType: "json" , success: function (result) { console.log(result); access_token = result.access_token; refresh_token = result.refresh_token; } }); } /** 액세스 토큰 갱신 */ function RefreshToAccess() { $.ajax({ type: "POST" , url: sUrl + "/connect/token" , data: { "grant_type": "refresh_token" , "client_id": "resourceownerclient" , "client_secret": "dataEventRecordsSecret" , "scope": "dataEventRecords offline_access" , "refresh_token" : refresh_token } , dataType: "json" , success: function (result) { console.log(result); access_token = result.access_token; refresh_token = result.refresh_token; } }); } /** API 호출 */ function CallValues() { $.ajax({ type: "GET" , url: sUrl + "/api/values" , headers: { "authorization": "Bearer " + access_token } , dataType: "json" , data: { } , success: function (result) { console.log(result); } }); } </script> </head> <body> 이 서버는 인증만 가능합니다. </body> </html> | cs |
참고 : [ASP.NET Core 2] 빈 프로젝트 세팅 (2) - 'WebAPI' 설정
'Controllers'폴더를 만들고 'ValuesController'를 추가합니다.
아래와 같이 작성합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | [Route("api/[controller]")] [ApiController] //OAuth2 인증 설정
[Authorize] public class ValuesController : ControllerBase { // GET api/values [HttpGet] public ActionResult<IEnumerable<string>> Get() { return new string[] { "value1", "value2" }; } // GET api/values/5 [HttpGet("{id}")] public ActionResult<string> Get(int id) { return "value"; } // POST api/values [HttpPost] public void Post([FromBody] string value) { } // PUT api/values/5 [HttpPut("{id}")] public void Put(int id, [FromBody] string value) { } // DELETE api/values/5 [HttpDelete("{id}")] public void Delete(int id) { } } | cs |
이전 글을 참고하여 'Config.cs'와 'UserServices'폴더의 클래스를 만듭니다.
참고 : [ASP.NET Core 2] OAuth2 인증에서 사용까지 (3) - 'IdentityServer'의 리플레시 토큰(Refresh Token) 사용하기
이전에 만들어놓은 코드가 있다면 'Config.cs'와 'UserServices'는 통으로 복사해서 사용해도 됩니다.
'Startup.cs'에 이전 글을 참고하여 'ConfigureServices'와 'Configure'를 수정합니다.
참고 : [ASP.NET Core 2] OAuth2 인증에서 사용까지 (3) - 'IdentityServer'의 리플레시 토큰(Refresh Token) 사용하기
참고 : [ASP.NET Core 2] OAuth2 인증에서 사용까지 (2) - 'IdentityServer'를 이용하여 'OAuth2' 인증 받기
이 두 가지를 합친 'Startup.cs'입니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } /// <summary> /// This method gets called by the runtime. /// Use this method to add services to the container. /// </summary> /// <param name="services"></param> public void ConfigureServices(IServiceCollection services) { //7. OAuth2 미들웨어(IdentityServer) 설정 //AddCustomUserStore : 앞에서 만든 확장메소드를 추가 services.AddIdentityServer() .AddDeveloperSigningCredential() //.AddSigningCredential() .AddInMemoryApiResources(Config.GetApiResources()) .AddInMemoryClients(Config.GetClients()) .AddCustomUserStore(); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); //인증 요청 정보 services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }).AddJwtBearer(o => { o.Audience = "apiApp"; //인증서버의 주소 o.Authority = "https://localhost:44350"; o.RequireHttpsMetadata = false; //인증서버에서 선언한 권한 o.Audience = "dataEventRecords"; }); } /// <summary> /// This method gets called by the runtime. /// Use this method to configure the HTTP request pipeline. /// </summary> /// <param name="app"></param> /// <param name="env"></param> public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { //HSTS 사용 //The default HSTS value is 30 days. //You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } //09. OAuth2 미들웨어(IdentityServer) CROS 접근 권한 문제 //app.UseCors(options => //{ // //전체 허용 // options.AllowAnyOrigin(); //}); //OAuth2 미들웨어(IdentityServer) 설정 app.UseIdentityServer(); //8. 프로젝트 미들웨어 기능 설정 //웹사이트 기본파일 읽기 설정 app.UseDefaultFiles(); //wwwroot 파일읽기 app.UseStaticFiles(); //http요청을 https로 리디렉션합니다. //https를 허용하지 않았다면 제거 합니다. //https://docs.microsoft.com/ko-kr/aspnet/core/security/enforcing-ssl?view=aspnetcore-3.0&tabs=visual-studio app.UseHttpsRedirection(); //인증 요청 app.UseAuthentication(); //에러가 났을때 Http 상태코드를 전달하기위한 설정 app.UseStatusCodePages(); app.UseMvc(); } } | cs |
html을 만들어놨으므로 함수만 호출해주면 됩니다.
1) 'CallToken()'를 호출해 봅시다.
2) 넘어온 엑세스 토큰과 리플레시 토큰을 저장합니다.
3) 'CallValues()'를 호출하여 API를 호출합니다.
4) 'RefreshToAccess()'를 호출하여 액세스 토큰을 갱신 할 수 있습니다.
완성된 샘플 : Github - OAuth2Sample/OAuth2Sample/Auth_WebAPI/
'IdentityServer'에 대한 심화학습은 계획되어 있지 않습니다만......
필요하면 다시 오겠습니다. ㅎㅎㅎㅎㅎ