2014-02-20 3 views
12

.net 및 NUGet에서 발견 된 성가신 일 중 하나는 기본적으로 설치된 버전이 무엇인지 전혀 알 수 없다는 것입니다. 기존 프로젝트에 물건을 추가하려고하면 정말 실망 스러울 수 있습니다 .....System.Web.Http.Owin WebApi2 설치 불황

여기 내 현재 딜레마가 있습니다.

MVC 만있는 MVC 5 프로젝트가 있습니다. 이 프로젝트는 방대하고 다른 프로젝트로 옮기는 작업에는 너무 많은 시간이 걸립니다. 그래서 NUGet을 열어 WebApi를 입력하고 함께 설치했습니다.

개인 계정이 설정된 빈 WebApi 프로젝트를 만들고 필 요한 다른 구성과 함께 시작 프로그램 코드를 현재 시작 프로그램에 복사했습니다.

그럼 내가 만든 깨끗한 프로젝트에서 바로 복사 한 AccountController를 만들었습니다. 그것은 다음과 같습니다 : 그것은 자신이 확실히 WebApi 버전 2+입니다 RoutePrefix을 사용하고 있기 때문에

[Authorize] 
[RoutePrefix("api/Account")] 
public class AccountController : ApiController 
{ 
    private const string LocalLoginProvider = "Local"; 

    public AccountController() 
     : this(Startup.UserManagerFactory(), Startup.OAuthOptions.AccessTokenFormat) 
    { 
    } 

    public AccountController(UserManager<IdentityUser> userManager, 
     ISecureDataFormat<AuthenticationTicket> accessTokenFormat) 
    { 
     UserManager = userManager; 
     AccessTokenFormat = accessTokenFormat; 
    } 

    public UserManager<IdentityUser> UserManager { get; private set; } 
    public ISecureDataFormat<AuthenticationTicket> AccessTokenFormat { get; private set; } 

    // GET api/Account/UserInfo 
    [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)] 
    [Route("UserInfo")] 
    public UserInfoViewModel GetUserInfo() 
    { 
     ExternalLoginData externalLogin = ExternalLoginData.FromIdentity(User.Identity as ClaimsIdentity); 

     return new UserInfoViewModel 
     { 
      UserName = User.Identity.GetUserName(), 
      HasRegistered = externalLogin == null, 
      LoginProvider = externalLogin != null ? externalLogin.LoginProvider : null 
     }; 
    } 

    // POST api/Account/Logout 
    [Route("Logout")] 
    public IHttpActionResult Logout() 
    { 
     Authentication.SignOut(CookieAuthenticationDefaults.AuthenticationType); 
     return Ok(); 
    } 

    // GET api/Account/ManageInfo?returnUrl=%2F&generateState=true 
    [Route("ManageInfo")] 
    public async Task<ManageInfoViewModel> GetManageInfo(string returnUrl, bool generateState = false) 
    { 
     IdentityUser user = await UserManager.FindByIdAsync(User.Identity.GetUserId()); 

     if (user == null) 
     { 
      return null; 
     } 

     List<UserLoginInfoViewModel> logins = new List<UserLoginInfoViewModel>(); 

     foreach (IdentityUserLogin linkedAccount in user.Logins) 
     { 
      logins.Add(new UserLoginInfoViewModel 
      { 
       LoginProvider = linkedAccount.LoginProvider, 
       ProviderKey = linkedAccount.ProviderKey 
      }); 
     } 

     if (user.PasswordHash != null) 
     { 
      logins.Add(new UserLoginInfoViewModel 
      { 
       LoginProvider = LocalLoginProvider, 
       ProviderKey = user.UserName, 
      }); 
     } 

     return new ManageInfoViewModel 
     { 
      LocalLoginProvider = LocalLoginProvider, 
      UserName = user.UserName, 
      Logins = logins, 
      ExternalLoginProviders = GetExternalLogins(returnUrl, generateState) 
     }; 
    } 

    // POST api/Account/ChangePassword 
    [Route("ChangePassword")] 
    public async Task<IHttpActionResult> ChangePassword(ChangePasswordBindingModel model) 
    { 
     if (!ModelState.IsValid) 
     { 
      return BadRequest(ModelState); 
     } 

     IdentityResult result = await UserManager.ChangePasswordAsync(User.Identity.GetUserId(), model.OldPassword, 
      model.NewPassword); 
     IHttpActionResult errorResult = GetErrorResult(result); 

     if (errorResult != null) 
     { 
      return errorResult; 
     } 

     return Ok(); 
    } 

    // POST api/Account/SetPassword 
    [Route("SetPassword")] 
    public async Task<IHttpActionResult> SetPassword(SetPasswordBindingModel model) 
    { 
     if (!ModelState.IsValid) 
     { 
      return BadRequest(ModelState); 
     } 

     IdentityResult result = await UserManager.AddPasswordAsync(User.Identity.GetUserId(), model.NewPassword); 
     IHttpActionResult errorResult = GetErrorResult(result); 

     if (errorResult != null) 
     { 
      return errorResult; 
     } 

     return Ok(); 
    } 

    // POST api/Account/AddExternalLogin 
    [Route("AddExternalLogin")] 
    public async Task<IHttpActionResult> AddExternalLogin(AddExternalLoginBindingModel model) 
    { 
     if (!ModelState.IsValid) 
     { 
      return BadRequest(ModelState); 
     } 

     Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie); 

     AuthenticationTicket ticket = AccessTokenFormat.Unprotect(model.ExternalAccessToken); 

     if (ticket == null || ticket.Identity == null || (ticket.Properties != null 
      && ticket.Properties.ExpiresUtc.HasValue 
      && ticket.Properties.ExpiresUtc.Value < DateTimeOffset.UtcNow)) 
     { 
      return BadRequest("External login failure."); 
     } 

     ExternalLoginData externalData = ExternalLoginData.FromIdentity(ticket.Identity); 

     if (externalData == null) 
     { 
      return BadRequest("The external login is already associated with an account."); 
     } 

     IdentityResult result = await UserManager.AddLoginAsync(User.Identity.GetUserId(), 
      new UserLoginInfo(externalData.LoginProvider, externalData.ProviderKey)); 

     IHttpActionResult errorResult = GetErrorResult(result); 

     if (errorResult != null) 
     { 
      return errorResult; 
     } 

     return Ok(); 
    } 

    // POST api/Account/RemoveLogin 
    [Route("RemoveLogin")] 
    public async Task<IHttpActionResult> RemoveLogin(RemoveLoginBindingModel model) 
    { 
     if (!ModelState.IsValid) 
     { 
      return BadRequest(ModelState); 
     } 

     IdentityResult result; 

     if (model.LoginProvider == LocalLoginProvider) 
     { 
      result = await UserManager.RemovePasswordAsync(User.Identity.GetUserId()); 
     } 
     else 
     { 
      result = await UserManager.RemoveLoginAsync(User.Identity.GetUserId(), 
       new UserLoginInfo(model.LoginProvider, model.ProviderKey)); 
     } 

     IHttpActionResult errorResult = GetErrorResult(result); 

     if (errorResult != null) 
     { 
      return errorResult; 
     } 

     return Ok(); 
    } 

    // GET api/Account/ExternalLogin 
    [OverrideAuthentication] 
    [HostAuthentication(DefaultAuthenticationTypes.ExternalCookie)] 
    [AllowAnonymous] 
    [Route("ExternalLogin", Name = "ExternalLogin")] 
    public async Task<IHttpActionResult> GetExternalLogin(string provider, string error = null) 
    { 
     if (error != null) 
     { 
      return Redirect(Url.Content("~/") + "#error=" + Uri.EscapeDataString(error)); 
     } 

     if (!User.Identity.IsAuthenticated) 
     { 
      return new ChallengeResult(provider, this); 
     } 

     ExternalLoginData externalLogin = ExternalLoginData.FromIdentity(User.Identity as ClaimsIdentity); 

     if (externalLogin == null) 
     { 
      return InternalServerError(); 
     } 

     if (externalLogin.LoginProvider != provider) 
     { 
      Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie); 
      return new ChallengeResult(provider, this); 
     } 

     IdentityUser user = await UserManager.FindAsync(new UserLoginInfo(externalLogin.LoginProvider, 
      externalLogin.ProviderKey)); 

     bool hasRegistered = user != null; 

     if (hasRegistered) 
     { 
      Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie); 
      ClaimsIdentity oAuthIdentity = await UserManager.CreateIdentityAsync(user, 
       OAuthDefaults.AuthenticationType); 
      ClaimsIdentity cookieIdentity = await UserManager.CreateIdentityAsync(user, 
       CookieAuthenticationDefaults.AuthenticationType); 
      AuthenticationProperties properties = ApplicationOAuthProvider.CreateProperties(user.UserName); 
      Authentication.SignIn(properties, oAuthIdentity, cookieIdentity); 
     } 
     else 
     { 
      IEnumerable<Claim> claims = externalLogin.GetClaims(); 
      ClaimsIdentity identity = new ClaimsIdentity(claims, OAuthDefaults.AuthenticationType); 
      Authentication.SignIn(identity); 
     } 

     return Ok(); 
    } 

    // GET api/Account/ExternalLogins?returnUrl=%2F&generateState=true 
    [AllowAnonymous] 
    [Route("ExternalLogins")] 
    public IEnumerable<ExternalLoginViewModel> GetExternalLogins(string returnUrl, bool generateState = false) 
    { 
     IEnumerable<AuthenticationDescription> descriptions = Authentication.GetExternalAuthenticationTypes(); 
     List<ExternalLoginViewModel> logins = new List<ExternalLoginViewModel>(); 

     string state; 

     if (generateState) 
     { 
      const int strengthInBits = 256; 
      state = RandomOAuthStateGenerator.Generate(strengthInBits); 
     } 
     else 
     { 
      state = null; 
     } 

     foreach (AuthenticationDescription description in descriptions) 
     { 
      ExternalLoginViewModel login = new ExternalLoginViewModel 
      { 
       Name = description.Caption, 
       Url = Url.Route("ExternalLogin", new 
       { 
        provider = description.AuthenticationType, 
        response_type = "token", 
        client_id = Startup.PublicClientId, 
        redirect_uri = new Uri(Request.RequestUri, returnUrl).AbsoluteUri, 
        state = state 
       }), 
       State = state 
      }; 
      logins.Add(login); 
     } 

     return logins; 
    } 

    // POST api/Account/Register 
    [AllowAnonymous] 
    [Route("Register")] 
    public async Task<IHttpActionResult> Register(RegisterBindingModel model) 
    { 
     if (!ModelState.IsValid) 
     { 
      return BadRequest(ModelState); 
     } 

     IdentityUser user = new IdentityUser 
     { 
      UserName = model.UserName 
     }; 

     IdentityResult result = await UserManager.CreateAsync(user, model.Password); 
     IHttpActionResult errorResult = GetErrorResult(result); 

     if (errorResult != null) 
     { 
      return errorResult; 
     } 

     return Ok(); 
    } 

    // POST api/Account/RegisterExternal 
    [OverrideAuthentication] 
    [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)] 
    [Route("RegisterExternal")] 
    public async Task<IHttpActionResult> RegisterExternal(RegisterExternalBindingModel model) 
    { 
     if (!ModelState.IsValid) 
     { 
      return BadRequest(ModelState); 
     } 

     ExternalLoginData externalLogin = ExternalLoginData.FromIdentity(User.Identity as ClaimsIdentity); 

     if (externalLogin == null) 
     { 
      return InternalServerError(); 
     } 

     IdentityUser user = new IdentityUser 
     { 
      UserName = model.UserName 
     }; 
     user.Logins.Add(new IdentityUserLogin 
     { 
      LoginProvider = externalLogin.LoginProvider, 
      ProviderKey = externalLogin.ProviderKey 
     }); 
     IdentityResult result = await UserManager.CreateAsync(user); 
     IHttpActionResult errorResult = GetErrorResult(result); 

     if (errorResult != null) 
     { 
      return errorResult; 
     } 

     return Ok(); 
    } 

    protected override void Dispose(bool disposing) 
    { 
     if (disposing) 
     { 
      UserManager.Dispose(); 
     } 

     base.Dispose(disposing); 
    } 

    #region Helpers 

    private IAuthenticationManager Authentication 
    { 
     get { return Request.GetOwinContext().Authentication; } 
    } 

    private IHttpActionResult GetErrorResult(IdentityResult result) 
    { 
     if (result == null) 
     { 
      return InternalServerError(); 
     } 

     if (!result.Succeeded) 
     { 
      if (result.Errors != null) 
      { 
       foreach (string error in result.Errors) 
       { 
        ModelState.AddModelError("", error); 
       } 
      } 

      if (ModelState.IsValid) 
      { 
       // No ModelState errors are available to send, so just return an empty BadRequest. 
       return BadRequest(); 
      } 

      return BadRequest(ModelState); 
     } 

     return null; 
    } 

    private class ExternalLoginData 
    { 
     public string LoginProvider { get; set; } 
     public string ProviderKey { get; set; } 
     public string UserName { get; set; } 

     public IList<Claim> GetClaims() 
     { 
      IList<Claim> claims = new List<Claim>(); 
      claims.Add(new Claim(ClaimTypes.NameIdentifier, ProviderKey, null, LoginProvider)); 

      if (UserName != null) 
      { 
       claims.Add(new Claim(ClaimTypes.Name, UserName, null, LoginProvider)); 
      } 

      return claims; 
     } 

     public static ExternalLoginData FromIdentity(ClaimsIdentity identity) 
     { 
      if (identity == null) 
      { 
       return null; 
      } 

      Claim providerKeyClaim = identity.FindFirst(ClaimTypes.NameIdentifier); 

      if (providerKeyClaim == null || String.IsNullOrEmpty(providerKeyClaim.Issuer) 
       || String.IsNullOrEmpty(providerKeyClaim.Value)) 
      { 
       return null; 
      } 

      if (providerKeyClaim.Issuer == ClaimsIdentity.DefaultIssuer) 
      { 
       return null; 
      } 

      return new ExternalLoginData 
      { 
       LoginProvider = providerKeyClaim.Issuer, 
       ProviderKey = providerKeyClaim.Value, 
       UserName = identity.FindFirstValue(ClaimTypes.Name) 
      }; 
     } 
    } 

    private static class RandomOAuthStateGenerator 
    { 
     private static RandomNumberGenerator _random = new RNGCryptoServiceProvider(); 

     public static string Generate(int strengthInBits) 
     { 
      const int bitsPerByte = 8; 

      if (strengthInBits % bitsPerByte != 0) 
      { 
       throw new ArgumentException("strengthInBits must be evenly divisible by 8.", "strengthInBits"); 
      } 

      int strengthInBytes = strengthInBits/bitsPerByte; 

      byte[] data = new byte[strengthInBytes]; 
      _random.GetBytes(data); 
      return HttpServerUtility.UrlTokenEncode(data); 
     } 
    } 

    #endregion 
} 

을 이제, 우리는 볼 수 있습니다. 제 문제는 코드가 컴파일되지 않는다는 것입니다. 그것은 상태 : 형식 또는 네임 스페이스 이름 'HostAuthenticationAttribute이'을 (를) 찾을 수 없습니다

(당신은 using 지시문 또는 어셈블리 참조가?)

을 내 클린 프로젝트를 보면, 나는 것을 볼 수 있습니다 이 클래스는 System.Web.Http.Owin에 있습니다. 문제는 필자의 주 프로젝트에서이 참조가 없기 때문에 설치 방법을 모른다는 것입니다.

WebApi의 다른 버전을 설치하지 않으려 고 시도했습니다.

누가 이전에이 문제를 겪었습니까?

답변

34

WebAPI 프로젝트를 버전 2.0으로 업그레이드 할 때 동일한 오류가 발생했습니다. 너겟 패키지 Microsoft.AspNet.WebApi.Owin을 설치하면 누락 된 참조가 해결되었습니다.

Install-Package Microsoft.AspNet.WebApi.Owin