[c#] .NET Core Identity Server 4 인증 VS ID 인증

ASP.NET Core에서 인증을 수행하는 적절한 방법을 이해하려고합니다. 여러 리소스를 살펴 봤습니다 (대부분 구식 임).

어떤 사람들은 Azure AD와 같은 클라우드 기반 솔루션을 사용하거나 IdentityServer4를 사용하고 내 토큰 서버를 호스팅하는 대체 솔루션을 제공합니다.

이전 버전의 .Net에서 더 간단한 인증 형식 중 하나는 사용자 지정 Iprinciple을 만들고 추가 인증 사용자 데이터를 내부에 저장하는 것입니다.

public interface ICustomPrincipal : System.Security.Principal.IPrincipal
{
    string FirstName { get; set; }

    string LastName { get; set; }
}

public class CustomPrincipal : ICustomPrincipal
{
    public IIdentity Identity { get; private set; }

    public CustomPrincipal(string username)
    {
        this.Identity = new GenericIdentity(username);
    }

    public bool IsInRole(string role)
    {
        return Identity != null && Identity.IsAuthenticated &&
           !string.IsNullOrWhiteSpace(role) && Roles.IsUserInRole(Identity.Name, role);
    }

    public string FirstName { get; set; }

    public string LastName { get; set; }

    public string FullName { get { return FirstName + " " + LastName; } }
}

public class CustomPrincipalSerializedModel
{
    public int Id { get; set; }

    public string FirstName { get; set; }

    public string LastName { get; set; }
}

그런 다음 데이터를 쿠키로 직렬화하고 클라이언트에 다시 반환합니다.

public void CreateAuthenticationTicket(string username) {

    var authUser = Repository.Find(u => u.Username == username);
    CustomPrincipalSerializedModel serializeModel = new CustomPrincipalSerializedModel();

    serializeModel.FirstName = authUser.FirstName;
    serializeModel.LastName = authUser.LastName;
    JavaScriptSerializer serializer = new JavaScriptSerializer();
    string userData = serializer.Serialize(serializeModel);

    FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(
    1,username,DateTime.Now,DateTime.Now.AddHours(8),false,userData);
    string encTicket = FormsAuthentication.Encrypt(authTicket);
    HttpCookie faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
    Response.Cookies.Add(faCookie);
}

내 질문은 다음과 같습니다.

  1. 이전 버전의 .Net에서 수행 한 방식과 유사한 인증 방법은 이전 방식이 여전히 작동하거나 최신 버전이 있습니까?

  2. 고유 한 사용자 지정 원칙을 만드는 고유 한 토큰 서버 구절을 사용할 때의 장단점은 무엇입니까?

  3. 클라우드 기반 솔루션 또는 별도의 토큰 서버를 사용할 때이를 현재 애플리케이션과 어떻게 통합 하시겠습니까? 여전히 내 애플리케이션에 사용자 테이블이 필요합니까? 두 가지를 어떻게 연결 하시겠습니까?

  4. 다른 SSO로 확장 할 수있는 동시에 Gmail / Facebook을 통한 로그인을 허용하기 위해 엔터프라이즈 애플리케이션을 만드는 방법에는 여러 가지 솔루션이 있습니다.

  5. 이러한 기술의 간단한 구현은 무엇입니까?



답변

TL; DR

IdentityServer = OAuth 2.0 / OpenId-Connect를 통한 토큰 암호화 및 유효성 검사 서비스

ASP.NET Identity = ASP.NET의 현재 ID 관리 전략

이전 버전의 .Net에서 수행 한 방식과 유사한 인증 방법은 이전 방식이 여전히 작동하거나 최신 버전이 있습니까?

ASP.NET Core에서 이전 방식을 달성 할 수없는 이유는 알 수 없지만 일반적으로 해당 전략은 ASP.NET ID로 대체되었으며 ASP.NET ID는 ASP.NET Core에서 잘 작동합니다.

https://docs.microsoft.com/en-us/aspnet/core/security/authentication/identity

ASP.NET Identity는 SQL Server와 같은 백업 저장소를 사용하여 사용자 이름, 암호 (해시 됨), 전자 메일, 전화와 같은 사용자 정보를 보관하고 FirstName, LastName 또는 기타 모든 것을 보관하도록 쉽게 확장 할 수 있습니다. 따라서 사용자 정보를 쿠키로 암호화하고 클라이언트에서 서버로 앞뒤로 전달할 이유가 없습니다. 사용자 클레임, 사용자 토큰, 사용자 역할 및 외부 로그인과 같은 개념을 지원합니다. 다음은 ASP.NET ID의 엔터티입니다.

  • AspNetUsers
  • AspNetUserRoles
  • AspNetUserClaims
  • AspNetUserLogins (Google, AAD와 같은 외부 ID 공급자 연결 용)
  • AspNetUserTokens (사용자가 수집 한 access_tokens 및 refresh_tokens와 같은 항목 저장 용)

고유 한 사용자 지정 원칙을 만드는 고유 한 토큰 서버 구절을 사용할 때의 장단점은 무엇입니까?

토큰 서버는 인증 및 / 또는 인증 정보를 포함하는 간단한 데이터 구조를 생성하는 시스템입니다. 인증은 일반적으로 access_token 이라는 토큰을 받습니다. 말하자면 이것은 “집으로가는 열쇠”라고 말하면 출입구를 통해 보호 된 리소스 (일반적으로 웹 API)의 거주지로 들어갈 수있게합니다. 인증의 경우 id_token에 사용자 / 개인에 대한 고유 식별자 가 포함됩니다. 그러한 식별자를 access_token에 넣는 것이 일반적이지만,이를위한 전용 프로토콜이 있습니다 : OpenID-Connect .

자체 보안 토큰 서비스 (STS)를 갖는 이유는 암호화를 통해 정보 자산을 보호하고 이러한 리소스에 액세스 할 수있는 클라이언트 (애플리케이션)를 제어하기위한 것입니다. 또한 ID 제어에 대한 표준은 이제 OpenID-Connect 사양에 존재합니다. IdentityServer는 OpenID-Connect 인증 서버와 결합 된 OAuth 2.0 인증 서버의 예입니다.

그러나 응용 프로그램에 사용자 테이블 만 있으면이 중 어느 것도 필요하지 않습니다. 토큰 서버가 필요하지 않습니다. ASP.NET ID 만 사용하면됩니다. ASP.NET Identity는 사용자를 서버 의 ClaimsIdentity 개체에 매핑 하므로 사용자 지정 IPrincipal 클래스가 필요하지 않습니다.

클라우드 기반 솔루션 또는 별도의 토큰 서버를 사용할 때이를 현재 애플리케이션과 어떻게 통합 하시겠습니까? 여전히 내 애플리케이션에 사용자 테이블이 필요합니까? 두 가지를 어떻게 연결 하시겠습니까?

별도의 ID 솔루션을 애플리케이션과 통합하려면 다음 자습서를 참조하십시오.
https://identityserver4.readthedocs.io/en/latest/quickstarts/0_overview.html
https://auth0.com/docs/quickstart/webapp/aspnet-core

최소한 사용자 이름을 외부 공급자의 사용자 식별자에 매핑하는 두 개의 열 테이블이 필요합니다. 이것이 ASP.NET Identity에서 AspNetUserLogins 테이블이 수행하는 작업입니다. 그러나 해당 테이블의 행은 AspNetUsers의 사용자 레코드에 따라 다릅니다.

ASP.NET ID는 Google, Microsoft, Facebook, 모든 OpenID-Connect 공급자, Azure AD와 같은 외부 공급자를 지원합니다. (Google과 Microsoft는 이미 OpenID-Connect 프로토콜을 구현 했으므로 예를 들어 이와 같은 맞춤형 통합 패키지가 필요하지 않습니다 .) 또한 ADFS는 ASP.NET Core ID에서 아직 사용할 수 없습니다.

ASP.NET Identity에서 외부 공급자를 시작하려면이 문서를 참조하십시오.

https://docs.microsoft.com/en-us/aspnet/core/security/authentication/social/

다른 SSO로 확장 할 수있는 동시에 Gmail / Facebook을 통한 로그인을 허용하기 위해 엔터프라이즈 애플리케이션을 만드는 방법에는 여러 가지 솔루션이 있습니다.

위에서 설명한 것처럼 ASP.NET Identity는 이미이 작업을 수행합니다. “외부 공급자”테이블을 만들고 데이터가 외부 로그인 프로세스를 구동하는 것은 매우 쉽습니다. 따라서 새 “SSO”가 나오면 제공 업체의 URL, 클라이언트 ID 및 비밀번호와 같은 속성이있는 새 행을 추가하면됩니다. ASP.NET ID에는 이미 Visual Studio 템플릿에 UI가 내장되어 있지만 더 멋진 단추는 소셜 로그인 을 참조하십시오 .

요약

암호 로그인 기능과 사용자 프로필이있는 사용자 테이블 만 필요한 경우 ASP.NET ID가 완벽합니다. 외부 기관을 개입시킬 필요가 없습니다. 그러나 많은 API에 액세스해야하는 애플리케이션이 많은 경우 ID 및 액세스 토큰을 보호하고 유효성을 검사하는 독립적 인 권한이 필요합니다. IdentityServer가 적합하거나 클라우드 솔루션의 경우 openiddict-core 또는 Auth0 을 참조하십시오 .

제 사과는 이것이 성공하지 못하거나 너무 입문이라는 것입니다. 찾고있는 과녁에 도달하기 위해 자유롭게 상호 작용하십시오.

부록 : 쿠키 인증

쿠키로 베어 본 인증을 수행하려면 다음 단계를 따르십시오. 그러나 내가 아는 한 사용자 지정 클레임 주체는 지원되지 않습니다. 동일한 효과를 얻으려면 ClaimPrincipal개체 의 클레임 목록을 활용하십시오 .

대화 상자에서 “인증 없음”을 선택하여 Visual Studio 2015/2017에서 새 ASP.NET Core 1.1 웹 애플리케이션을 만듭니다. 그런 다음 패키지를 추가합니다.

Microsoft.AspNetCore.Authentication.Cookies

제자리에 있는 Configure방법에서 Startup.cs(이전 app.UseMvc) :

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
    AuthenticationScheme = "MyCookieMiddlewareInstance",
    LoginPath = new PathString("/Controller/Login/"),
    AutomaticAuthenticate = true,
    AutomaticChallenge = true
});

그런 다음 로그인 UI를 빌드하고 다음과 같이 html Form을 Action Method에 게시합니다.

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(String username, String password, String returnUrl = null)
{
    ViewData["ReturnUrl"] = returnUrl;
    if (ModelState.IsValid)
    {
        // check user's password hash in database
        // retrieve user info

        var claims = new List<Claim>
        {
            new Claim(ClaimTypes.Name, username),
            new Claim("FirstName", "Alice"),
            new Claim("LastName", "Smith")
        };

        var identity = new ClaimsIdentity(claims, "Password");

        var principal = new ClaimsPrincipal(identity);

        await HttpContext.Authentication.SignInAsync("MyCookieMiddlewareInstance", principal);

        return RedirectToLocal(returnUrl);
    }

    ModelState.AddModelError(String.Empty, "Invalid login attempt.");

    return View();
}

HttpContext.User 개체에는 사용자 지정 클레임이 있어야하며 ClaimPrincipal의 List 컬렉션을 쉽게 검색 할 수 있습니다.

전체 솔루션 / 프로젝트가 StackOverflow 게시물에 대해 약간 많이 보이기 때문에 이것이 충분하기를 바랍니다.


답변

TL; DR

IdentityServer4를 올바르게 구현하는 방법에 대한 전체 게시물을 표시하고 싶지만 모든 텍스트를 맞추려고 노력했지만 StackOverflow가 허용하는 한계를 벗어 났으므로 대신 몇 가지 팁과 배운 것들을 바로 잡겠습니다.

토큰 서버 대 ASP ID 사용의 이점은 무엇입니까?

토큰 서버는 많은 이점이 있지만 모든 사람에게 적합하지는 않습니다. 여러 클라이언트가 로그인 할 수 있도록하는 엔터프라이즈와 같은 솔루션을 구현하는 경우 토큰 서버가 최선의 방법이지만 외부 로그인을 지원하려는 간단한 웹 사이트를 만드는 경우 ASP ID 및 일부 미들웨어.

Identity Server 4 팁

Identity Server 4는 내가 본 많은 다른 프레임 워크에 비해 문서화가 잘되어 있지만 처음부터 시작하여 전체 그림을 보는 것은 어렵습니다.

내 첫 번째 오해는 OAuth를 인증으로 사용하려고 시도했습니다. 예, 그렇게 할 수있는 방법이 있지만 OAuth는 인증이 아닌 인증을위한 것입니다. 인증하려면 OIDC (OpenIdConnect)를 사용합니다.

제 경우에는 웹 API에 연결하는 자바 스크립트 클라이언트를 만들고 싶었습니다. 많은 솔루션을 살펴 보았지만 처음에는 webapi를 사용하여 Identity Server에 대해 Authenticate를 호출하려고 시도했으며 서버에 대해 확인 되었기 때문에 해당 토큰을 유지하려고했습니다. 이 흐름은 잠재적으로 작동 할 수 있지만 많은 결함이 있습니다.

마지막으로 Javascript Client 샘플을 찾았을 때 적절한 흐름이 올바른 흐름을 얻었습니다. You Client가 로그인하고 토큰을 설정합니다. 그런 다음 웹 API가 OIdc 클라이언트를 사용하도록하여 IdentityServer에 대한 액세스 토큰인지 확인합니다.

스토어 및 마이그레이션에 연결
처음에는 마이그레이션에 대해 몇 가지 오해가있었습니다. 나는 마이그레이션을 실행하여 SQL을 생성하는 방법을 알아 내기 위해 컨텍스트를 사용하는 대신 내부적으로 dll에서 SQL을 생성했다는 인상을 받았습니다.

컴퓨터에서 사용하는 것이 중요한 마이그레이션을위한 두 가지 구문이 있습니다.

dotnet ef migrations add InitialIdentityServerMigration -c ApplicationDbContext

Add-Migration InitialIdentityServerDbMigration -c ApplicationDbContext

마이그레이션 후 매개 변수가 이름이라고 생각합니다. 이름이 필요한 이유 ApplicationDbContext는 확실하지 않습니다 . 생성하려는 코드 우선 DbContext입니다.

마이그레이션은 자동 마법을 사용하여 시작 구성 방법에서 연결 문자열을 찾습니다. 방금 서버 탐색기에서 연결을 사용했다고 가정했습니다.

여러 프로젝트가있는 경우 ApplicationDbContext가 시작으로 설정된 프로젝트가 있는지 확인하십시오.

권한 부여 및 인증을 구현할 때 움직이는 부분이 많이 있습니다.이 게시물이 누군가에게 도움이되기를 바랍니다. 인증을 완전히 이해하는 가장 쉬운 방법은 예제를 골라서 모든 것을 모아서 문서를 읽어 보는 것입니다.


답변

ASP.NET ID-이것은 Bearer 또는 기본 인증 여부에 관계없이 응용 프로그램을 인증하는 방식의 빌드이며 사용자 등록, 로그인, 암호 변경 등을 수행 할 수있는 기성 코드를 제공합니다.

이제 10 개의 서로 다른 응용 프로그램이 있으며 10 개의 모든 응용 프로그램에서 동일한 작업을 수행하는 것은 불가능합니다. 매우 연약하고 매우 나쁜 습관입니다.

이 문제를 해결하기 위해 우리가 할 수있는 일은 인증 및 승인을 중앙 집중화하는 것입니다. 따라서 변경 사항이있을 때마다 10 개 앱 모두에 영향을주지 않습니다.

ID 서버는 동일한 작업을 수행 할 수있는 기능을 제공합니다. 방금 Identity 서비스로 사용 된 하나의 샘플 웹 앱을 만들 수 있으며 사용자의 유효성을 검사하고 일부 JWT 액세스 토큰을 제공합니다.


답변

저는 항상 내장 된 ASP.NET Identity (그리고 이전에 Membership) 권한 부여 / 인증을 사용해 왔으며, 최근에 Auth0 ( https://auth0.com )을 구현했으며 다른 시도로 이것을 권장합니다.


답변

소셜 로그인은 Identity로 구현하기 어렵지 않지만 초기 설정이 포함되어 있으며 문서에서 온라인으로 찾은 단계가 동일하지 않을 수 있습니다. 일반적으로 설정하려는 플랫폼의 개발자 섹션에서 도움말을 찾을 수 있습니다. 소셜 로그인입니다. ID는 레거시 버전의 .net 프레임 워크에있는 기존 멤버십 기능을 대체하는 것입니다. 놀라운 사실은 이미 가지고있는 jwt 토큰을 웹 API에 전달하는 것과 같은 에지 사용 사례가 온라인 예제의 어느 곳에서도 다루지 않는다는 것입니다. pluralsight에서도이 작업을 수행하기 위해 자체 토큰 권한이 필요하지는 않지만 자체 호스팅 서버를 처리하지 않는 get 또는 post에서 데이터를 전달하는 방법에 대한 단일 예제를 찾지 못했습니다.


답변