ASP.NET MVC-사용자 지정 IIdentity 또는 IPrincipal 설정


650

ASP.NET MVC 응용 프로그램에서 사용자 지정 IIdentity / IPrincipal을 설정하고 싶습니다. 더 쉽고 더 적합한 방법입니다. User.Identity.Idand과 같은 것을 호출 할 수 있도록 기본값을 확장하고 싶습니다 User.Identity.Role. 멋진 것은 아니며 몇 가지 추가 속성입니다.

나는 많은 기사와 질문을 읽었지만 실제로보다 어렵게 만들고 있다고 생각합니다. 나는 그것이 쉬울 것이라고 생각했다. 사용자가 로그온하면 사용자 지정 IIdentity를 설정하고 싶습니다. 그래서 나는 Application_PostAuthenticateRequest내 global.asax에서 구현 할 것이라고 생각했습니다 . 그러나 모든 요청에 ​​대해 호출되며 데이터베이스의 모든 데이터를 요청하고 사용자 정의 IPrincipal 객체를 넣는 모든 요청에 ​​대해 데이터베이스를 호출하고 싶지 않습니다. 그것은 또한 매우 불필요하고 느리고 잘못된 위치에 있습니다 (데이터베이스 호출). 그러나 나는 틀릴 수 있습니다. 아니면 그 데이터의 다른 곳은 어디입니까?

그래서 사용자가 로그인 할 때마다 세션에 필요한 변수를 추가 할 수 있다고 생각했는데 Application_PostAuthenticateRequest이벤트 처리기 의 사용자 정의 IIdentity에 추가했습니다 . 하지만, 내는 Context.Session것입니다 null그 길을 가야하는 것 또한되지 않도록,이.

나는 오늘 하루 동안이 일을하고 있는데 뭔가 빠진 것 같습니다. 너무 어렵지 않아야합니까? 나는 또한 이것과 함께 제공되는 모든 (반) 관련 것들에 약간 혼란스러워합니다. MembershipProvider, MembershipUser, RoleProvider, ProfileProvider, IPrincipal, IIdentity, FormsAuthentication... 암 i를 단 하나의 사람은 모두이 매우 혼란 발견?

누군가가 모든 추가 퍼지없이 IIdentity에 추가 데이터를 저장하는 간단하고 우아하고 효율적인 솔루션을 말해 줄 수 있다면 .. 그것은 좋을 것입니다! 나는 비슷한 질문이 있다는 것을 알고 있지만 필요한 대답이 거기에 있다면 간과해야합니다.


1
안녕하세요 도미, 그것은 사용자 ID와 같이 절대로 변경되지 않는 데이터를 저장하거나 사용자가 쿠키에 즉시 반영 해야하는 데이터를 변경 한 직후 쿠키를 업데이트하는 조합입니다. 사용자가 그렇게하면 쿠키를 새 데이터로 업데이트합니다. 그러나 자주 변경되는 데이터는 저장하지 않습니다.
Razzie

26
이 질문에는 36k 회의 견해와 많은 찬사가 있습니다. 이것이 정말로 일반적인 요구 사항입니까? 그렇다면 모든 '맞춤형 물건'보다 더 좋은 방법이 없습니까?
Simon_Weaver 12

2
@Simon_Weaver 암호화 된 쿠키의 추가 사용자 지정 정보를보다 쉽게 ​​지원하는 ASP.NET Identity가 있습니다.
John

1
난 당신이 게시처럼 많은 정보가있다, 당신과 동의 : MemberShip..., Principal, Identity. ASP.NET은 인증을 다루기위한이 방법을보다 쉽고 간단하며 최대 2 가지 방법으로 만들어야합니다.
광대역 :

1
@Simon_Weaver보다 간단하고 유연한 신원 시스템 IMHO에 대한 요구가 있음을 분명히 보여줍니다.
niico

답변:


838

내가하는 방법은 다음과 같습니다.

IIdentity 대신 IPrincipal을 사용하기로 결정했습니다. IIdentity와 IPrincipal을 모두 구현할 필요가 없기 때문입니다.

  1. 인터페이스 만들기

    interface ICustomPrincipal : IPrincipal
    {
        int Id { get; set; }
        string FirstName { get; set; }
        string LastName { get; set; }
    }
  2. CustomPrincipal

    public class CustomPrincipal : ICustomPrincipal
    {
        public IIdentity Identity { get; private set; }
        public bool IsInRole(string role) { return false; }
    
        public CustomPrincipal(string email)
        {
            this.Identity = new GenericIdentity(email);
        }
    
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }
  3. CustomPrincipalSerializeModel-사용자 정의 정보를 FormsAuthenticationTicket 오브젝트의 userdata 필드에 직렬화하는 데 사용됩니다.

    public class CustomPrincipalSerializeModel
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }
  4. 로그인 방법-사용자 정의 정보로 쿠키 설정

    if (Membership.ValidateUser(viewModel.Email, viewModel.Password))
    {
        var user = userRepository.Users.Where(u => u.Email == viewModel.Email).First();
    
        CustomPrincipalSerializeModel serializeModel = new CustomPrincipalSerializeModel();
        serializeModel.Id = user.Id;
        serializeModel.FirstName = user.FirstName;
        serializeModel.LastName = user.LastName;
    
        JavaScriptSerializer serializer = new JavaScriptSerializer();
    
        string userData = serializer.Serialize(serializeModel);
    
        FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(
                 1,
                 viewModel.Email,
                 DateTime.Now,
                 DateTime.Now.AddMinutes(15),
                 false,
                 userData);
    
        string encTicket = FormsAuthentication.Encrypt(authTicket);
        HttpCookie faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
        Response.Cookies.Add(faCookie);
    
        return RedirectToAction("Index", "Home");
    }
  5. Global.asax.cs-쿠키를 읽고 HttpContext.User 객체를 대체합니다. PostAuthenticateRequest를 재정의하면됩니다.

    protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
    {
        HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
    
        if (authCookie != null)
        {
            FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
    
            JavaScriptSerializer serializer = new JavaScriptSerializer();
    
            CustomPrincipalSerializeModel serializeModel = serializer.Deserialize<CustomPrincipalSerializeModel>(authTicket.UserData);
    
            CustomPrincipal newUser = new CustomPrincipal(authTicket.Name);
            newUser.Id = serializeModel.Id;
            newUser.FirstName = serializeModel.FirstName;
            newUser.LastName = serializeModel.LastName;
    
            HttpContext.Current.User = newUser;
        }
    }
  6. 면도기 뷰에서 액세스

    @((User as CustomPrincipal).Id)
    @((User as CustomPrincipal).FirstName)
    @((User as CustomPrincipal).LastName)

그리고 코드에서 :

    (User as CustomPrincipal).Id
    (User as CustomPrincipal).FirstName
    (User as CustomPrincipal).LastName

코드가 자명하다고 생각합니다. 그렇지 않은 경우 알려주십시오.

또한보다 쉽게 ​​액세스 할 수 있도록 기본 컨트롤러를 만들고 반환 된 User 개체 (HttpContext.User)를 재정의 할 수 있습니다.

public class BaseController : Controller
{
    protected virtual new CustomPrincipal User
    {
        get { return HttpContext.User as CustomPrincipal; }
    }
}

그런 다음 각 컨트롤러에 대해

public class AccountController : BaseController
{
    // ...
}

다음과 같이 코드에서 사용자 정의 필드에 액세스 할 수 있습니다.

User.Id
User.FirstName
User.LastName

그러나 이것은 내부보기에서는 작동하지 않습니다. 이를 위해 사용자 정의 WebViewPage 구현을 작성해야합니다.

public abstract class BaseViewPage : WebViewPage
{
    public virtual new CustomPrincipal User
    {
        get { return base.User as CustomPrincipal; }
    }
}

public abstract class BaseViewPage<TModel> : WebViewPage<TModel>
{
    public virtual new CustomPrincipal User
    {
        get { return base.User as CustomPrincipal; }
    }
}

Views / web.config에서 기본 페이지 유형으로 설정하십시오.

<pages pageBaseType="Your.Namespace.BaseViewPage">
  <namespaces>
    <add namespace="System.Web.Mvc" />
    <add namespace="System.Web.Mvc.Ajax" />
    <add namespace="System.Web.Mvc.Html" />
    <add namespace="System.Web.Routing" />
  </namespaces>
</pages>

뷰에서 다음과 같이 액세스 할 수 있습니다.

@User.FirstName
@User.LastName

9
좋은 구현; 사용자 정의 주체를 RolePrincipal로 바꾸는 RoleManagerModule을주의하십시오. - 나에게 많은 고통 원인이 stackoverflow.com/questions/10742259/...
데이비드 Keaveny

9
확인 해결책을 찾았습니다. 이메일로 ""(빈 문자열)를 전달하는 else 스위치를 추가하면 Identity가 익명이됩니다.
Pierre-Alain Vigeant

3
DateTime.Now.AddMinutes (N) ... N 분 후에도 사용자를 로그 아웃하지 않도록하는 방법, 로그인 한 사용자를 유지할 수 있습니까 (예 : 사용자가 'Remember Me'를 확인할 때)?
1110

4
당신이 WebApiController를 사용하는 경우 설정해야합니다 Thread.CurrentPrincipal에서 Application_PostAuthenticateRequest가에 의존하지 않는 작업에 대한HttpContext.Current.User
조나단 Levison

3
@AbhinavGujjar FormsAuthentication.SignOut();는 나를 위해 잘 작동합니다.
LukeP

109

ASP.NET MVC에 대해서는 직접 말할 수 없지만 ASP.NET Web Forms의 FormsAuthenticationTicket경우 사용자가 인증되면 쿠키를 만들어 쿠키로 암호화하는 것이 요령입니다 . 이런 식으로 데이터베이스를 한 번만 호출하면 (또는 AD 또는 인증을 수행하는 데 사용하는 모든 것), 각 후속 요청은 쿠키에 저장된 티켓을 기반으로 인증됩니다.

이것에 대한 좋은 기사 : http://www.ondotnet.com/pub/a/dotnet/2004/02/02/effectiveformsauth.html (깨진 링크)

편집하다:

위의 링크가 끊어 졌으므로 위의 답변에서 LukeP의 솔루션을 추천합니다. https : //.com/a/10524305- 또한 허용 된 답변이 해당 답변으로 변경되도록 제안합니다.

편집 2 : 깨진 링크의 대안 : https://web.archive.org/web/20120422011422/http://ondotnet.com/pub/a/dotnet/2004/02/02/effectiveformsauth.html


PHP에서 왔을 때, 나는 항상 UserID와 같은 정보와 세션에서 제한된 액세스 권한을 부여하는 데 필요한 다른 정보를 넣었습니다. 클라이언트쪽에 저장하면 긴장이됩니다. 왜 문제가되지 않을까요?
John Zumbrum

@JohnZ-티켓 자체가 유선으로 전송되기 전에 서버에서 티켓이 암호화되므로 클라이언트가 티켓 내에 저장된 데이터에 액세스 할 수 없습니다. 세션 ID도 쿠키에 저장되므로 실제로 다른 것은 아닙니다.
John Rasch

3
당신이 여기 있다면 당신은 LukeP의 해결책을 봐야합니다
mynkow

2
나는 항상 이 방법으로 최대 쿠키 크기 ( stackoverflow.com/questions/8706924/… ) 를 초과 할 수있는 가능성에 대해 염려했습니다 . 나는를 사용하는 경향이 CacheA와 Session서버의 데이터를 유지하기 위해 교체. 이것이 결함이있는 접근법인지 말해 줄 수 있습니까?
레드 타즈

2
좋은 접근법. 이것에 대한 한 가지 잠재적 인 문제는 사용자 개체에 속성이 몇 개 이상 (특히 중첩 개체가있는 경우)있는 경우 암호화 된 값이 4KB를 초과하면 쿠키 생성이 자동으로 실패한다는 것입니다. 키 데이터 만 저장하면 괜찮지 만 나머지는 여전히 DB를 눌러야합니다. 다른 고려 사항은 사용자 개체에 서명 또는 논리 변경이있을 때 쿠키 데이터를 "업그레이드"하는 것입니다.
Geoffrey Hudik 2016 년

63

다음은 작업을 수행하는 예제입니다. bool isValid는 일부 데이터 저장소 (사용자 데이터베이스라고 함)를보고 설정됩니다. UserID는 내가 관리하는 ID입니다. 이메일 주소와 같은 추가 정보를 사용자 데이터에 추가 할 수 있습니다.

protected void btnLogin_Click(object sender, EventArgs e)
{         
    //Hard Coded for the moment
    bool isValid=true;
    if (isValid) 
    {
         string userData = String.Empty;
         userData = userData + "UserID=" + userID;
         FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, username, DateTime.Now, DateTime.Now.AddMinutes(30), true, userData);
         string encTicket = FormsAuthentication.Encrypt(ticket);
         HttpCookie faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
         Response.Cookies.Add(faCookie);
         //And send the user where they were heading
         string redirectUrl = FormsAuthentication.GetRedirectUrl(username, false);
         Response.Redirect(redirectUrl);
     }
}

golbal asax에서 다음 코드를 추가하여 정보를 검색하십시오.

protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
    HttpCookie authCookie = Request.Cookies[
             FormsAuthentication.FormsCookieName];
    if(authCookie != null)
    {
        //Extract the forms authentication cookie
        FormsAuthenticationTicket authTicket = 
               FormsAuthentication.Decrypt(authCookie.Value);
        // Create an Identity object
        //CustomIdentity implements System.Web.Security.IIdentity
        CustomIdentity id = GetUserIdentity(authTicket.Name);
        //CustomPrincipal implements System.Web.Security.IPrincipal
        CustomPrincipal newUser = new CustomPrincipal();
        Context.User = newUser;
    }
}

나중에 정보를 사용하려는 경우 다음과 같이 사용자 지정 주체에 액세스 할 수 있습니다.

(CustomPrincipal)this.User
or 
(CustomPrincipal)this.Context.User

이를 통해 사용자 정의 사용자 정보에 액세스 할 수 있습니다.


2
참고-그것은 Request.Cookies [] (복수)
Dan Esparza

10
Thread.CurrentPrincipal 및 Context.User를 CustomPrincipal로 설정하는 것을 잊지 마십시오.
Russ Cam

6
GetUserIdentity ()는 어디에서 왔습니까?
Ryan

의견에서 언급했듯이 System.Web.Security.IIdentity의 구현을 제공합니다. 해당 인터페이스에 대한 Google
Sriwantha Attanayake

16

MVC는 컨트롤러 클래스에서 중단되는 OnAuthorize 메소드를 제공합니다. 또는 사용자 정의 조치 필터를 사용하여 권한 부여를 수행 할 수 있습니다. MVC를 사용하면 쉽게 할 수 있습니다. 여기에 대한 블로그 게시물을 게시했습니다. http://www.bradygaster.com/post/custom-authentication-with-mvc-3.0


그러나 세션이 유실 될 수 있으며 사용자는 여전히 인증합니다. 아니 ?
Dragouf

@ brady gaster, 귀하의 블로그 게시물 (감사합니다!)을 읽었습니다. 왜 누군가가 global.asax 항목 "... AuthenticateRequest (..)"를 통해 귀하의 게시물에 언급 된 "OnAuthorize ()"재정의를 사용합니까? 대답? 기본 사용자를 설정할 때 하나가 다른 것보다 선호됩니까?
RayLoveless

10

뷰에서 사용하기 위해 일부 메소드를 @User에 연결 해야하는 경우 해결책이 있습니다. 심각한 멤버쉽 사용자 정의에 대한 솔루션은 없지만 원래 질문이 뷰에만 필요한 경우에는 충분할 것입니다. 아래는 authorizefilter에서 반환 된 변수를 확인하는 데 사용되었으며 일부 링크가 표시 될지 여부를 확인하는 데 사용되었습니다 (모든 종류의 권한 부여 논리 또는 액세스 권한 부여가 아님).

using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Security.Principal;

    namespace SomeSite.Web.Helpers
    {
        public static class UserHelpers
        {
            public static bool IsEditor(this IPrincipal user)
            {
                return null; //Do some stuff
            }
        }
    }

그런 다음 web.config 영역에 참조를 추가하고보기에서 아래와 같이 호출하십시오.

@User.IsEditor()

1
귀하의 솔루션에서 우리는 매번 데이터베이스 호출을 다시 수행해야합니다. 사용자 개체에는 사용자 지정 속성이 없기 때문입니다. 그것은 단지 이름과 IsAuthanticated있다
oneNiceFriend

그것은 전적으로 구현과 원하는 행동에 달려 있습니다. 내 샘플에는 0 줄의 데이터베이스 또는 역할 논리가 포함되어 있습니다. IsInRole을 사용하면 쿠키에 캐시 될 수 있습니다. 또는 자체 캐싱 로직을 구현합니다.
기본

3

LukeP의 답변을 기반으로 하고 설정 timeout하고 requireSSL협력 할 방법을 추가하십시오 Web.config.

참조 링크

LukeP의 수정 된 코드

1을 timeout기준으로 설정 합니다 Web.Config. FormsAuthentication.Timeout은 Web.config의에 정의 된 시간 초과 값을 얻을 것이다. 다음을 함수로 감싸서 ticket다시 반환합니다 .

int version = 1;
DateTime now = DateTime.Now;

// respect to the `timeout` in Web.config.
TimeSpan timeout = FormsAuthentication.Timeout;
DateTime expire = now.Add(timeout);
bool isPersist = false;

FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
     version,          
     name,
     now,
     expire,
     isPersist,
     userData);

2, 구성에 따라 쿠키를 보안 또는 비보안으로 RequireSSL구성하십시오.

HttpCookie faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
// respect to `RequreSSL` in `Web.Config`
bool bSSL = FormsAuthentication.RequireSSL;
faCookie.Secure = bSSL;

3

좋아, 그래서 나는이 아주 오래된 질문을 끌어서 심각한 암호 보관 인입니다. 그러나 이것에 대한 훨씬 간단한 접근 방식이 있습니다. 위의 @Baserz가 다루었습니다. 그리고 그것은 C # 확장 방법과 캐싱 (세션을 사용하지 마십시오)의 조합을 사용하는 것입니다.

실제로 Microsoft는 이미 Microsoft.AspNet.Identity.IdentityExtensions네임 스페이스 에 여러 가지 확장을 제공했습니다 . 예를 들어, GetUserId()사용자 ID를 반환하는 확장 메서드입니다. IPrincipal을 기반으로 클레임을 반환하는 GetUserName()및 도 있습니다 FindFirstValue().

따라서 네임 스페이스 만 포함하고 User.Identity.GetUserName()ASP.NET Identity에서 구성한대로 사용자 이름을 얻기 위해 호출 하면됩니다.

이전 ASP.NET ID가 오픈 소스가 아니기 때문에 캐시되어 있는지 확실하지 않으며 리버스 엔지니어링하지 않아도됩니다. 그러나 그렇지 않은 경우 고유 한 확장 방법을 작성하면 특정 시간 동안이 결과가 캐시됩니다.


왜 "세션을 사용하지 마십시오"?
Alex

@jitbit-세션이 신뢰할 수없고 안전하지 않기 때문에. 같은 이유로 보안 목적으로 세션을 사용해서는 안됩니다.
Erik Funkenbusch 2016 년

세션을 다시 채우면 (신뢰할 수없는 경우) "신뢰할 수 없음"을 해결할 수 있습니다. "안전하지 않은"-세션 하이재킹을 방지하는 방법이 있습니다 (HTTPS 전용 + 기타 방법 사용). 그러나 나는 실제로 당신에게 동의합니다. 그러면 어디서 캐시하겠습니까? 같은 정보 IsUserAdministrator또는 UserEmail등? 당신은 생각하고 HttpRuntime.Cache있습니까?
Alex

@jitbit-하나의 옵션이거나 다른 캐시 솔루션이 있습니다. 일정 기간이 지나면 캐시 항목을 만료해야합니다. 쿠키를 수동으로 변경하고 세션 ID를 추측 할 수 있으므로 안전하지 않은 로컬 시스템에도 적용됩니다. 중간에있는 사람 만이 유일한 관심사가 아닙니다.
Erik Funkenbusch 2016 년

2

페이지 뒤 코드의 액세스를 단순화하려면 MVC가 아닌 Web Forms 사용자를위한 LukeP 코드 외에도 아래 코드를 기본 페이지에 추가하고 모든 페이지에서 기본 페이지를 파생하십시오.

Public Overridable Shadows ReadOnly Property User() As CustomPrincipal
    Get
        Return DirectCast(MyBase.User, CustomPrincipal)
    End Get
End Property

따라서 코드 뒤에서 간단하게 액세스 할 수 있습니다.

User.FirstName or User.LastName

Web Form 시나리오에서 누락 된 것은 페이지와 연결되지 않은 코드에서 동일한 동작을 얻는 방법입니다. 예를 들어 httpmodules 에서 항상 각 클래스에 캐스트를 추가해야합니까 아니면 더 똑똑한 방법이 있습니까?

내 사용자 정의 사용자에 대한 기초로 예제를 사용하기 때문에 귀하의 답변을 주셔서 감사합니다 LukeP에 감사합니다 (지금 가지고있는 User.Roles, User.Tasks, User.HasPath(int), User.Settings.Timeout그리고 다른 많은 좋은 것들)


0

LukeP가 제안한 솔루션을 시도했지만 Authorize 속성을 지원하지 않는 것으로 나타났습니다. 그래서 조금 수정했습니다.

public class UserExBusinessInfo
{
    public int BusinessID { get; set; }
    public string Name { get; set; }
}

public class UserExInfo
{
    public IEnumerable<UserExBusinessInfo> BusinessInfo { get; set; }
    public int? CurrentBusinessID { get; set; }
}

public class PrincipalEx : ClaimsPrincipal
{
    private readonly UserExInfo userExInfo;
    public UserExInfo UserExInfo => userExInfo;

    public PrincipalEx(IPrincipal baseModel, UserExInfo userExInfo)
        : base(baseModel)
    {
        this.userExInfo = userExInfo;
    }
}

public class PrincipalExSerializeModel
{
    public UserExInfo UserExInfo { get; set; }
}

public static class IPrincipalHelpers
{
    public static UserExInfo ExInfo(this IPrincipal @this) => (@this as PrincipalEx)?.UserExInfo;
}


    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Login(LoginModel details, string returnUrl)
    {
        if (ModelState.IsValid)
        {
            AppUser user = await UserManager.FindAsync(details.Name, details.Password);

            if (user == null)
            {
                ModelState.AddModelError("", "Invalid name or password.");
            }
            else
            {
                ClaimsIdentity ident = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
                AuthManager.SignOut();
                AuthManager.SignIn(new AuthenticationProperties { IsPersistent = false }, ident);

                user.LastLoginDate = DateTime.UtcNow;
                await UserManager.UpdateAsync(user);

                PrincipalExSerializeModel serializeModel = new PrincipalExSerializeModel();
                serializeModel.UserExInfo = new UserExInfo()
                {
                    BusinessInfo = await
                        db.Businesses
                        .Where(b => user.Id.Equals(b.AspNetUserID))
                        .Select(b => new UserExBusinessInfo { BusinessID = b.BusinessID, Name = b.Name })
                        .ToListAsync()
                };

                JavaScriptSerializer serializer = new JavaScriptSerializer();

                string userData = serializer.Serialize(serializeModel);

                FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(
                         1,
                         details.Name,
                         DateTime.Now,
                         DateTime.Now.AddMinutes(15),
                         false,
                         userData);

                string encTicket = FormsAuthentication.Encrypt(authTicket);
                HttpCookie faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
                Response.Cookies.Add(faCookie);

                return RedirectToLocal(returnUrl);
            }
        }
        return View(details);
    }

그리고 마지막으로 Global.asax.cs에서

    protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
    {
        HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];

        if (authCookie != null)
        {
            FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
            JavaScriptSerializer serializer = new JavaScriptSerializer();
            PrincipalExSerializeModel serializeModel = serializer.Deserialize<PrincipalExSerializeModel>(authTicket.UserData);
            PrincipalEx newUser = new PrincipalEx(HttpContext.Current.User, serializeModel.UserExInfo);
            HttpContext.Current.User = newUser;
        }
    }

이제 간단히 호출하여 뷰 및 컨트롤러의 데이터에 액세스 할 수 있습니다

User.ExInfo()

로그 아웃하려면 전화

AuthManager.SignOut();

여기서 AuthManager는

HttpContext.GetOwinContext().Authentication
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.