C# WebApi2安装中的System.Web.Http.Owin问题
我在.net和NUGet中发现的一个恼人的事情是,我永远不知道默认情况下安装了什么版本的东西。 在尝试向现有项目添加内容时,这可能会非常令人沮丧 这就是我目前的困境 我有一个MVC5项目,上面只有MVC。这个项目是巨大的,将其转移到另一个项目的工作将花费太多的时间。 因此,我打开NUGet并键入WebApi,然后安装了附带的一个 然后,我创建了一个空白的WebApi项目,设置了个人帐户,并将启动代码与所需的任何其他配置一起复制到当前启动中 然后我开始创建AccountController,它是直接从我创建的clean项目复制的。看起来是这样的:C# WebApi2安装中的System.Web.Http.Owin问题,c#,asp.net-mvc,asp.net-web-api,C#,Asp.net Mvc,Asp.net Web Api,我在.net和NUGet中发现的一个恼人的事情是,我永远不知道默认情况下安装了什么版本的东西。 在尝试向现有项目添加内容时,这可能会非常令人沮丧 这就是我目前的困境 我有一个MVC5项目,上面只有MVC。这个项目是巨大的,将其转移到另一个项目的工作将花费太多的时间。 因此,我打开NUGet并键入WebApi,然后安装了附带的一个 然后,我创建了一个空白的WebApi项目,设置了个人帐户,并将启动代码与所需的任何其他配置一起复制到当前启动中 然后我开始创建AccountController,它是直
[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
}
[授权]
[RoutePrefix(“api/账户”)]
公共类AccountController:ApicController
{
私有常量字符串LocalLoginProvider=“Local”;
公共账户控制员()
:这(Startup.UserManagerFactory()、Startup.OAuthOptions.AccessTokenFormat)
{
}
公共帐户控制器(用户管理器用户管理器,
ISecureDataFormat访问令牌格式)
{
UserManager=UserManager;
AccessTokenFormat=AccessTokenFormat;
}
公共用户管理器用户管理器{get;private set;}
公共ISecureDataFormat AccessTokenFormat{get;private set;}
//获取api/帐户/用户信息
[主机身份验证(DefaultAuthenticationTypes.ExternalBearer)]
[路线(“用户信息”)]
public UserInfoViewModel GetUserInfo()
{
ExternalLoginData externalLogin=ExternalLoginData.FromIdentity(User.Identity作为索赔实体);
返回新的UserInfoViewModel
{
UserName=User.Identity.GetUserName(),
HasRegistered=externalLogin==null,
LoginProvider=externalLogin!=null?externalLogin.LoginProvider:null
};
}
//发布api/帐户/注销
[路线(“注销”)]
公共IHttpActionResult注销()
{
Authentication.SignOut(CookieAuthenticationDefaults.AuthenticationType);
返回Ok();
}
//获取api/Account/ManageInfo?返回URL=%2F&generateState=true
[路线(“管理信息”)]
公共异步任务GetManageInfo(字符串returnUrl,bool generateState=false)
{
IdentityUser user=wait UserManager.FindByIdAsync(user.Identity.GetUserId());
if(user==null)
{
返回null;
}
列表登录名=新列表();
foreach(user.Logins中的IdentityUserLogin linkedAccount)
{
添加(新的UserLoginInfoViewModel)
{
LoginProvider=linkedAccount.LoginProvider,
ProviderKey=linkedAccount.ProviderKey
});
}
if(user.PasswordHash!=null)
{
添加(新的UserLoginInfoViewModel)
{
LoginProvider=LocalLoginProvider,
ProviderKey=user.UserName,
});
}
返回新的ManageInfoViewModel
{
LocalLoginProvider=LocalLoginProvider,
UserName=user.UserName,
登录=登录,
ExternalLoginProviders=GetExternalLogins(返回URL,GenerateEstate)
};
}
//发布api/帐户/更改密码
[路线(“更改密码”)]
公共异步任务ChangePassword(ChangePasswordBindingModel模型)
{
如果(!ModelState.IsValid)
{
返回请求(ModelState);
}
IdentityResult结果=等待UserManager.ChangePasswordAsync(User.Identity.GetUserId(),model.OldPassword,
新密码);
IHttpActionResult errorResult=GetErrorResult(结果);
if(errorResult!=null)
{
返回错误结果;
}
返回Ok();
}
//发布api/帐户/设置密码
[路由(“设置密码”)]
公共异步任务SetPassword(SetPasswordBindingModel模型)
{
如果(!ModelState.IsValid)
{
返回请求(ModelState);
}
IdentityResult result=await UserManager.AddPasswordAsync(User.Identity.GetUserId(),model.NewPassword);
IHttpActionResult errorResult=GetErrorResult(结果);
if(errorResult!=null)
{
返回错误结果;
}
返回Ok();
}
//发布api/账户/附录
[路线(“AddExternalLogin”)]
公共异步任务AddExternalLogin(AddExternalLoginBindingModel模型)
{
如果(!ModelState.IsValid)
{
返回请求(ModelState);
}
Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie);
AuthenticationTicket票证=AccessTokenFormat.Unprotect(model.ExternalAccessToken);
if(ticket==null | | | ticket.Identity==null | | |(ticket.Properties!=null
&&ticket.Properties.ExpiresUtc.HasValue
&&ticket.Properties.ExpiresUtc.ValueInstall-Package Microsoft.AspNet.WebApi.Owin