이 시리즈의 종합편???
이라고 하기에는 좀 그렇고 합본 정도입니다.
지금까지 샘플은 인증서버와 API 서버가 따로 있는 것을 가정하여 만들어져 있었습니다.
이것은 인증서버를 하나만 두고 여러 API서버를 연동해서 사용할 수 있기 때문입니다.
하지만!
인증서버 하나에 API서버가 하나라면 굳이 따로 만들 필요가 없죠.
이번에는 인증서버와 API서버를 합치도록 하겠습니다.
이전 포스팅에서 여러 번 다뤘던 내용이므로 이번 포스팅은 대부분 링크로 대체합니다.
새 프로젝트를 만듭니다.
프로젝트는 생성 옵션은
닷넷 코어 2.2
웹 응용프로그램
빈 프로젝트
입니다.
누겟에서 'IdentityServer4'를 찾아 설치합니다.
우리는 Core 2.2 가 기준이라 2.x 버전을 설치해야 합니다.
누겟에서 'IdentityServer4.AccessTokenValidation' 찾아 설치합니다.
우리는 Core 2.2 가 기준이라 2.x 버전을 설치해야 합니다.
빈 프로젝트는 아무것도 없기 때문에 html을 읽을 수 있도록 세팅합니다.
여기에 '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'에 대한 심화학습은 계획되어 있지 않습니다만......
필요하면 다시 오겠습니다. ㅎㅎㅎㅎㅎ