asp.net core – Claims 기반으로 한 인증서비스 구현하기 ft. AddAuthentication() , AddCookies()

Claims 사용하기위한 절차

asp.net Core 의 Clamis 기반의 인증 cookie  기반으로  작동하도록 인증 서비스를  추가하고 방식을 추가한다
여기는 cookie 방식으로 설정했다.


1.  인증 서비스 “스키마이름”  등록
2. “스키마” 에 cookie 방식 추가


1)  서비스 등록 : ConfigurationServices에 사용할 인증서비스 등록
    public void ConfigurationServices(IServiceCollection services) 
    { 
            Services.AddAuthentication(“스키마명”).AddCookie(“스키마명” , option => {    });
            Services.AddAuthentication(“스키마명”).AddCookie(“스키마명”);

    }

2) 미들웨어 등록 : Congifure 메서드에 파이프라인등록 
       public void Configure(IApplicaion app , IWebHostEnvironment env)
       {
            app.UseAuthentication();  // app.UseAuthorization() 보다 먼저 등록되어야함
       }

3) 어플레케이션 처리
① Claim – 접속한 사용자에 대한 정보를 객체로 생성
② ClaimsIdentity –  Claims(접속자 정보 객체)를 AddClaim 으로 추가
③ ClaimsPrincipal –  ClaimsIdentity(접속자 정보객체 컬렉션) AddIdentity 로 추가
④ SignInAsync() – ClaimPrincipal 객체 HttpContext.SignInAsync(ClaimPrincipla객체)로그인 처리.

var MyUserID = new Claim(ClaimTypes.NameIdentifier , “MyUserID”);
var MyyName = new Claim(ClaimTypes.Name , “MyName”);

var MyClaimsIdentity = new ClaimsIdentity();
MyClaimsIdentity.AddClaim(MyUserID ); // MyClaimsIdentity.AddClaim(MyUserID , “쿠키스키마명:” );
MyClaimsIdentity.AddClaim(MyyName ); // MyClaimsIdentity.AddClaim(MyyName , “쿠키스키마명:” );

var MyClaimsPrincipal = new ClaimsPrincipal(MyClaimsIdentity);
MyClaimsPrincipal.AddIdentity(MyClaimsIdentity);

// 브라우저를 끄면 쿠키 날림 IsPersistent = false , 
// Claim 로그인 처리
await HttpContext.SignInAsync( MyClaimsPrincipal ,new AuthenticationProperties { IsPersistent = false });  // 로그인 처리완료
// await HttpContext.SignInAsync(ClaimsPrincipal객체  , new AuthenticationProperties{ 속성설정});

//Claim 로그아웃 처리
await HttpContext.SignOutAsync(“스키마명”);


하지만, ClaimsIdentity  클래스가 collection 을 지원하기때문에 Claim 객체를  별로도 만들지않고, List 객체로 만들어서 처리한다

List<Claim> myClaimsList = new List<Claims>();
myClaimsList .Add(new Claim(ClaimTypes.NameIdentifier , “MyUserID”);
myClaimsList .Add(new Claim(ClaimTypes.Name , “MyName”);

ClaimIdentity myClaimIdentity = new ClaimIdentity(myClaimsList , “스키마명”); // StartUp.cs ConfigurationServices 에 등록한 
ClaimPrincipal myClaimPrincipal = new ClaimPrincipal(myClaimIdentity);

// claim 로그인 처리
await HttpContext.SignInAsync( myClaimsPrincipal, new AuthenticationProperties { IsPersistent = false });

// claim 로그아웃처리
await HttpContext.SignOutAsync(“스키마명”);

// Claim 객체로 로그인 여부확인
claim 사용시, 
ClaimsPrincipal 의 “User” 객체를 사용할 수 있으며,

 if (User.Identity.IsAuthenticationed)  로 로그인 여부를 true / false 로 확인 가능

// claim 으로 만든 값을 사용하기
Claim <  ClaimsIdentity  <  ClaimPrincipal

claim 객체사용지 claim 처리된 사용자 객체는 ClaimPrincipla 객체인 User 가 되고,
User 안에서 Claim 에 설정된 모든 들을 Key로 가져올수있다.

User.Claims.Where(c => c.Type == “LEVEL”).Select(c => c.Value).FirstOrDefault();
User.FindFirst(ClaimTypes.Email).Value;
User.FindFirst(“LEVEL”);  Claim에 없는 사용자정의 타입  또는 FintFirstValue 사용
User.FindFirstValue(“LEVEL”);  Claim에 없는 사용자정의 타입


ㆍAuthentication  서비스 등록 ,  Authentication 미들웨어  등록하기
ㆍAuthentication 서비스 등록하기
   – ConfigureServices(IServicesCollection services)

Authentication미들웨어등록
   – Configure(IApplicationBuilder app , IWebEnvironment env)

Authentication은 “인증”과 관련된 역할을 하고 ,  Authorization 은 “권한(허가)” 과 관련된 역할을 하는 서비스로 분류된다.
(메서도 또는 객체의 경우도 인증과 권한에 대한 역할을 한다고 보면된다)

ConfigurationService() 메서드 에서는 services 객체를 통해 Authentication  과 Authorization 서비스를 등록할수있으며,
services.AddAuthentication() 과 services.AddAuthorization() 와 같이 추가하여 서비스를 구성할수있다.

ㆍService.AddAuthenticaion() : 현재 웹프로젝트에 인증서비스를 등록한다.
  예를들어, 쿠키를 사용할지, oAuth를 사용할지 또는 Basic Authentication 을 사용 할지 등, 현재 웹사이트가 사용할 인증  
  을 사용할지를 결정하고 설정한다.
  인증서비스를 등록 , 어떤 인증방식을 사용할지 추가 ,  인증 옵션 설정한다.

   
   1) 웹에서 사용할 “인증 서비스”를 “스키마명”을 지정하고, 컨테이너에 추가한다.
   2) 만들어진 “인증 서비스” 객체의 메서드를 통해 인증방식을 추가한다.
       (AddCookie , AddOAuth 등 , 핸들러를 통해 Basic Authentication 도 사용가능함)
   3) 추가된 인증방식에 옵션을 설정한다.
   4) 미들웨어App.UseAuthentication() 메서드를  실행해서 인증서비스를 활성화 한다.

   5) services.authentication(“스키마명”) 로 등록된 “스키마명” (정확히는 scheme(스킴명임)) 을 claim 객체와 연동하여
        claim 기반의 인증서비스를 구현한다.  claim 기본의 인증 서비스 구현을 위해 3 개의 클래스가 필요하다.
        필요 클래스 : Claims , ClaimIdentitys , ClaimPrincipals  

[예제]
※ 서비스 컨테이너에 옵션설정과 함께 등록
public void ConfigurationServices(IServiceCollection services)


           // 옵션없이 사용
             services.AddAuthentication(“MyAuth”).AddCookie();
  

           // 옵션설정하고 사용
             services.AddAuthentication(“MyAuth“).AddCookie( options => {
           
                   // options.속성 인증서비스와 관련된 옵션 설정 ,
                   // options.Cookie.속성 쿠키와 직접적인 관련속성

                   // 인증과 관련된 옵션설정
                    options.ExpireTimeSpan = TimeSpan.FromMinutes(20); // 사용자 입력이 20 분 동안없으면 
                    options.LoginPath = “/Home/Login”;
                    options.LogoutPath = “/Home/LogOut”;
                    options.AccessDeniedPath = “Home/AccesDenided”;       

                   // 쿠키와 관련된 옵션설정
                    options.Cookie.HttpOnly = true;
                    options.Cookie.Expiration = TimeSpan.FromDays(1); // 현재시간으로부터 1일 유효                   
                    // Authentication() 서비스에서는
                       options.Cookies.Expiration 대신 options.ExpireTimeSpan 을 사용해야한다.(오류남)

          });

       
}

ㆍservices.AddAuthentication() 등록시 “스키마명”  유의사항
   – 스키마명을 기본값  CookieAuthenticationDefault.AuthenticationScheme 상수 사용시  ( AddCookie 에 Cookie 스키마 생략가능 )
      services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie( options => {. …. });

 //  [정상] CookieAuthenticationDefaults.AuthenticationScheme 사용시 AddCookie 에 스키마명 생략가능
      services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie( options => {. …. });

  –  스키마명을 CookieAuthenticationDefault.AuthenticationScheme 상수 사용 할 경우  ( AddCookie 에 Cookie 스키마 지정필수 )
      services.AddAuthentication(“MyProjectAuth“).AddCookie(“MyProjectAuth“, options => { });   

  –  [오류발행] 스키마명을 기본아닌 사용자정의 “임의로 입력” 할 경우 , 아래 샘플
     Authentication “스키마명과” AddCookie 의 “스키마명”을 반드시 입력해야하며, 반드시 일치 시켜야 한다.
     입력하지 않거나, 일치 시키지 않으면 
unhandled exception 오류가 발생한다.    
     → 일반페이지에서는 오류가 발생하지 않으며 , 스키마명을 사용하는 claim 객체사용 참조시 오류발생

      ㆍ1) 디폴트 스키마명을 Authentication 서비스에 사용시 AddCookies에 쿠키가 사용할 인증 시키마명을 입력하지않아도됨
     // unhandled exception 오류발생 (AddAuthentication 스키마 명 입력했이나,  AddCookie 의 스카마명 입력을 안함)
      services.AddAuthentication(“MyProjectAuth“).AddCookie(options => {. …. }); 

    //  정상처리  CookieAuthenticationDefaults.AuthenticationScheme  디폴트 상수를 사용하면 가능함.
     services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(options => { …. });
    
    ㆍ2) 임의의 사용자가 입력한 스키마명을 사용할시 AddCookies 에 명시적으로 일치 시켜줘야한다.
     // unhandled exception 오류발생 (AddAuthentication 스키마 명과 AddCookie 의 스키마명이 다름)
      services.AddAuthentication(“MyProjectAuth“).AddCookie(“MyProjectTEST“, options => {. …. });   

     // 정상 Authentication 의 스키마명과 인증서비스에서 사용할 쿠키의 스키마명을일치 시켜줘야한다.     
      services.AddAuthentication(“MyProjectAuth“).AddCookie(“MyProjectAuth“, options => { });      



▶  서비스에 등록된 인증서비스 미들웨어 등록

public void Configure(IApplication App , IWebHostEnvironment env)

{
          app.UseAuthentication();
      //  app.UseAuthentication(); //app.UseAuthorization(); 앞에 위치해야 한다.
     //  Authenication 은 “인증” 에 관련되었으므로 서비스 전체에 대한 영향을 미치며,

     //  Authorization  은 “권한” 에 관련되므로 클라이언트 개인의 영향을 미치므로, 순서를 기억하자
}

▶ MVC controller 에서 claim 기반 인증시스템 구현
    
    [HttpPost]
    public IActionResult Login(string userId ,  string userpwd)
    {
         
    }

options.Cookie.Expiration  vs options.ExpireTimeSpan
     – options.Cookie.Expiration : 사용자의 접속과 이용과 관계없이 Expire 만료 시간아 되면 자동으로 쿠키가 없어진다.
     – options.ExpireTimeSpan : 사용자 (입력) 응답이 지정된 시간동안 없을경우 쿠키 자동 만료

options.ExpireTimeSpan는 쿠키가 만료될 시간 간격을 지정하는 값이다.이 만료시간을 쿠키가 생성된 이후가 아닌 사용자의 조작이 없을 때를 기준으로 한다. 사용자의 조작이 10:30에 있다면 쿠키의 만료시간은 11:30으로 갱신되게 된다.그리고 사용자의 조작이 없이 1시간이 지나면 만료시간이 지나기 때문에 삭제된다. 결국 쿠키가 없기 때문에 options.LogoutPath에 설정된 경로로 로그아웃을 하게 된다.

options.LoginPath를 설정하면 만약 로그인이 필요한 페이지의 경우 자동으로 리디렉션 된다. options.AccessDeniedPath는 엑세스가 거부되었을 때의 경로이다.

options.Cookies.Expiration 사용자 조작시간 및 이용과 관계없이 쿠키를 Expiration 날짜가 되면 쿠키를 소멸시킨다.

 

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다