在asp.net Web api和angular js中使用的身份validation方法

我正在使用Web api和angular js创建一个网站,我对在我的网站上使用的身份validation感到非常困惑。

我创建了一个login.js ,其中有我的Login方法,它将我的用户名/ Emailid和密码发布到我的Web Api,web api中的方法将validation该用户。

码:

$scope.Login() { $.post("api/Authentication/Login",Username,Password) { } } 

Web api代码:

 [Route] Public Task Login([FromBody] username,password) { //method to authenticate user from database. //Now the tricky parts comes like after authenticating user should i //just store the user id in my session like this Session["userid]=id or //Should i go for storing whole user object in my cookie as i have read //that storing data in session is very bad idea and disaster too as session is very memory //and so i think i would go for cookie which will be saved on client side. //but what if cookie isnt supported by browser?? } 

Darin Dimitrov在回答和评论中指出,使用会话是灾难。 所以我决定按照这个答案使用cookie,并且Nop Commerce的一个电子商务网站也使用cookie来存储当前登录的客户对象,根据这个问题和答案问题

我在本课题中 遵循LukeP建议的代码,用于身份validation,并在整个应用程序中维护当前的登录用户对象。

我也读过关于asp.net声明身份但不知道我是否可以在我的asp.net web api和angular js中使用它。

所以有人能告诉我在asp.net web api和angular js中使用正确的身份validation方法以及在LukeP代码中使用web api和angular js进行的所有更改吗?

任何人都可以向我解释这个appraoch,我已经在上面提到了一些细节描述和一些代码,因为它可以帮助我和其他一些人,如果他们正在寻找相同的。

稍后我将提供100点赏金,以解决上述一些代码的问题。

最好的方法是使用令牌身份validation。 总之,它的工作原理如下:

  • 服务器上的POST /api/login路由接收用户名+密码,检查它们对数据库是否有效,然后生成并返回refresh token (可以是随机字符串或GUID)。 refresh token也存储在用户旁边的数据库中,覆盖先前的refresh token
  • 服务器上的GET /api/access-token路由接收用户名+ refresh token ,检查它们在数据库中是否匹配,然后生成并返回access token
  • 任何其他/api/*路由都要求有效的access token位于请求的标头中,否则它们会假定用户没有有效的登录名

access token是使用仅服务器知道的密钥加密的数据对象。 它应包含用户名,到期日期(通常距离生成令牌的时间约为10分钟),以及有关用户的任何权限或misc数据。 因为它是使用密钥加密的,所以攻击者无法伪造它。

您需要在服务器上实现这些路由。

如果您正在使用OWIN,以下是使用Microsoft.Owin.Security.OAuth NuGet包为您执行加密位的方法:

在你的启动配置中有这个:

 using System.Web.Http; using Microsoft.Owin; using Microsoft.Owin.Security.OAuth; using Owin; [assembly: OwinStartup(typeof(MyProject.Startup))] namespace MyProject { public class Startup { public static OAuthBearerAuthenticationOptions OAuthBearerOptions { get; private set; } public void Configuration(IAppBuilder app) { var config = new HttpConfiguration(); OAuthBearerOptions = new OAuthBearerAuthenticationOptions(); app.UseOAuthBearerAuthentication(OAuthBearerOptions); // Configure Web API to use only bearer token authentication. config.SuppressDefaultHostAuthentication(); config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType)); app.UseWebApi(config); } } } 

然后,您可以生成一个ticket (这是未加密的access token )并加密它,如下所示:

 var identity = new ClaimsIdentity(new[] { new Claim(ClaimTypes.Email, "users email"), // other business specific claims eg "IsAdmin" }); var ticket = new AuthenticationTicket(identity, new AuthenticationProperties( { ExpiresUtc = DateTime.UtcNow.AddMinutes(10) })); var accessToken = MyProject.Startup.OAuthBearerOptions.AccessTokenFormat.Protect(ticket); 

在Angular中,您需要设置一种登录方式,一种在到期时获取新access token的方法,以及在每个API请求的标头中传递access token的方法。 我建议将refresh tokenaccess token存储在本地存储(或旧浏览器的cookie)中,并使用$httpProvider.interceptors.push为每个$http调用添加拦截器。 然后,拦截器可以将访问令牌添加到标头中,如下所示: config.headers['Authorization'] = 'Bearer ' + accessToken;

以角度定义拦截器:

 angular.module('app').service('authenticationInterceptor', ['$q', function($q) { this.request = function(config) { var accessToken = // ... get the access token from local storage / cookie config.headers['Authorization'] = 'Bearer ' + accessToken; return config; }; }]); 

将其添加到$httpProvider

 angular.module('app').config(['$httpProvider', ($httpProvider: ng.IHttpProvider) => { $httpProvider.interceptors.push('authenticationInterceptor'); }]); 

这是一个非常广泛的问题,没有机会在单一答案中这样做。

我可以对你说的是“令牌认证”,Outh2应该可以胜任; 当我们谈论安全性时,这是使用Angular和WebAPI的最简单方法。 在这种情况下,Cookie不是正确的解决方案。

有关如何使用ASP.NET Web API 2,Owin和Identity实现完整的基于令牌的身份validation的详细信息,请查看此文章。 那篇文章在很多方面帮助了我。 最终,当您有一个示例解决方案时,您可以回到这里并要求更多“详细信息”。

顺便说一句,我在你的代码中读到了这个“评论”:

//现在棘手的部分就像validation用户之后我应该//只是将用户ID存储在我的会话中,就像这个Session [“userid] = id或//我应该把我的cookie中的整个用户对象存储起来

就个人而言,我认为会议是邪恶的。 我不是唯一的一个 。 无论如何,如果你想在web.api世界中使用“session”,它不是免费的,你必须激活它。 因此,如果出于任何原因需要使用它,请检查此项 。

希望能帮助到你 :)

最好的方法是使用json web token(JWT)……

Satellizer是一个很棒的库,可以添加到您的Angular应用程序https://github.com/sahat/satellizer

HTML

  

Don't have an account yet? Sign up

JS

 angular.module('MyApp') .controller('LoginCtrl', function($scope, $auth) { $scope.login = function() { $auth.login($scope.user) .then(function() { toastr.success('You have successfully signed in!'); $location.path('/'); }) .catch(function(error) { toastr.error(error.data.message, error.status); }); }; }); 

在服务器端,他们在https://github.com/sahat/satellizer/tree/master/examples/server/c%23上有一个C#示例