C# 将Active Directory与SPA的Web API一起使用
我正在建立单页应用程序,我想知道用户的身份。我们的内部网中有Active Directory,但我对它知之甚少。我能够使用这样的代码来验证用户名和密码C# 将Active Directory与SPA的Web API一起使用,c#,active-directory,asp.net-web-api,single-page-application,owin,C#,Active Directory,Asp.net Web Api,Single Page Application,Owin,我正在建立单页应用程序,我想知道用户的身份。我们的内部网中有Active Directory,但我对它知之甚少。我能够使用这样的代码来验证用户名和密码 using(PrincipalContext pc = new PrincipalContext(ContextType.Domain, "YOURDOMAIN")) { bool isValid = pc.ValidateCredentials("myuser", "mypassword"); } 事实上,这正是我从Active Dire
using(PrincipalContext pc = new PrincipalContext(ContextType.Domain, "YOURDOMAIN"))
{
bool isValid = pc.ValidateCredentials("myuser", "mypassword");
}
事实上,这正是我从Active Directory方面所需要的一切。所以我可以用这段代码创建一些AuthorizationFilter,但这意味着用户名和密码必须在每个请求中。我想只发送一次用户名和密码,然后使用一些令牌进行授权。因此,在我的服务器端应用程序中应该有一些令牌提供者
我从头开始构建这个应用程序,以便使用最新的.net技术。我发现有些Owin中间件处理代币、cookies和OAuth。有什么能帮助我吗?< / P > < P>当然OAutha是一种方法,但是为什么不考虑旧的好形式认证呢?它非常适合这种情况-使用自定义提供程序,您可以在AD中对用户进行身份验证,然后所有连续的客户端请求都携带身份验证cookie,该cookie可用于对服务器调用进行身份验证
这个场景中的表单cookie扮演着你想象中的“令牌”角色。当我在搜索完全不同的东西时,我在CodePlex上发现了这个不可思议的项目:它正是我所寻找的 更新: 这个应用程序中对我有用的部分是DomainUserLoginProvider
public class DomanUserLoginProvider : ILoginProvider
{
public bool ValidateCredentials(string userName, string password, out ClaimsIdentity identity)
{
using (var pc = new PrincipalContext(ContextType.Domain, _domain))
{
bool isValid = pc.ValidateCredentials(userName, password);
if (isValid)
{
identity = new ClaimsIdentity(Startup.OAuthOptions.AuthenticationType);
identity.AddClaim(new Claim(ClaimTypes.Name, userName));
}
else
{
identity = null;
}
return isValid;
}
}
public DomanUserLoginProvider(string domain)
{
_domain = domain;
}
private readonly string _domain;
}
LoginProvider在AccountController的操作中用于验证凭据。这里还创建了AccessToken
[HttpPost, Route("Token")]
public IHttpActionResult Token(LoginViewModel login)
{
ClaimsIdentity identity;
if (!_loginProvider.ValidateCredentials(login.UserName, login.Password, out identity))
{
return BadRequest("Incorrect user or password");
}
var ticket = new AuthenticationTicket(identity, new AuthenticationProperties());
var currentUtc = new SystemClock().UtcNow;
ticket.Properties.IssuedUtc = currentUtc;
ticket.Properties.ExpiresUtc = currentUtc.Add(TimeSpan.FromMinutes(30));
return Ok(new LoginAccessViewModel
{
UserName = login.UserName,
AccessToken = Startup.OAuthOptions.AccessTokenFormat.Protect(ticket)
});
}
最后,将正确的中间件添加到Owin管道中
public partial class Startup
{
static Startup()
{
OAuthOptions = new OAuthAuthorizationServerOptions();
}
public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }
public static void ConfigureAuth(IAppBuilder app)
{
app.UseOAuthBearerTokens(OAuthOptions);
}
}
在客户端,您只需将带有凭据的请求发送到AccountController的令牌操作,就可以获得身份验证令牌。在浏览器中保存此令牌(“记住我”功能),并将Angular的$http服务设置为将令牌附加到每个请求
services.factory('$auth', ['$q', '$http', '$path', function ($q, $http, $path) {
var tokenUrl = $path('api/Account/Token');
function setupAuth(accessToken, remember) {
var header = 'Bearer ' + accessToken;
delete $http.defaults.headers.common['Authorization'];
$http.defaults.headers.common['Authorization'] = header;
sessionStorage['accessToken'] = accessToken;
if (remember) {
localStorage['accessToken'] = accessToken;
}
return header;
}
var self = {};
self.login = function(user, passw, rememberMe) {
var deferred = $q.defer();
$http.post(tokenUrl, { userName: user, password: passw })
.success(function (data) {
var header = setupAuth(data.accessToken, rememberMe);
deferred.resolve({
userName: data.userName,
Authorization: header
});
})
.error(function() {
deferred.reject();
});
return deferred.promise;
};
return self;
}]);
正如您提到的,我需要编写自定义成员资格提供程序,其中几乎所有方法都没有实现。当其他开发人员加入项目时,这可能会造成一些混乱。我讨厌这样的解释:“因为历史原因,有很多新的NotImplementedException()”:-)内置的ActiveDirectoryMembershipProvider会很好,您不必自己编写。如果您从上面的链接中获取相关部分,并解释该站点/代码如何解决您的原始问题,那就太好了。感谢您指向一个与.Net协同工作的优秀Spa应用程序的指针,根据Jason的要求,你能否添加一些背景信息,说明它是如何帮助你的。我用代码更新了答案,这是我问题的解决方案。因为你的声誉是666。啊。。。现在你很好。