将Active Directory与Web API用于SPA

Luk*_*rkl 16 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");
}
Run Code Online (Sandbox Code Playgroud)

事实上,这就是我从Active Directory方面需要的一切.所以我可以使用此代码创建一些AuthorizationFilter,但这意味着用户名和密码必须在每个请求中.我只想发送一次用户名和密码,然后使用一些令牌进行授权.所以在我的服务器端应用程序中应该有一些令牌提供程序.

我从头开始构建这个应用程序,所以我可以使用最新的.net技术.我发现有一些Owin中间件正在处理令牌,cookie和OAuth.这有什么可以帮助我吗?

Luk*_*rkl 23

当我在寻找完全不同的东西时,我在CodePlex上找到了这个令人难以置信的项目:https://angularapp.codeplex.com/这正是我想要的.

更新:

这个应用程序对我有用的部分是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;
}
Run Code Online (Sandbox Code Playgroud)

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)
    });
}
Run Code Online (Sandbox Code Playgroud)

最后但并非最不重要的是,将正确的中间件添加到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);
    }
}
Run Code Online (Sandbox Code Playgroud)

在客户端,您只需将带有凭据的请求发送到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;
}]);
Run Code Online (Sandbox Code Playgroud)

  • 如果您从上面的链接中获取相关部分并解释该站点/代码如何解决您的原始问题,那将是很好的. (2认同)
  • 我用代码更新了答案,这是我的问题的解决方案. (2认同)