使用Windows身份验证和OWIN的ASP.NET MVC5 / AngularJS / Web API应用程序

时间:2014-11-06 21:35:21

标签: asp.net-mvc angularjs windows-authentication owin

我可能过于复杂了,但我们使用Windows身份验证的AngularJS内部ASP.NET MVC5 SPA。此应用程序有一个SQL后端数据库,其中包含一个用户表,其中包含其帐户名以及它们在应用程序中各自的角色。我们将调用另一个也启用了Windows身份验证的Web API应用程序。

我曾尝试研究如何使用OWIN处理授权,但未找到有关OWIN和Windows身份验证的任何具体示例。出现的所有内容都使用带有用户名和密码的表单身份验证。

如何为我的应用程序使用OWIN和Windows Auth?这是我的OAuthAuthorizationServerProvider类的示例。

public class SimpleAuthorizationServerProvider : OAuthAuthorizationServerProvider
{
    public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
    {
        context.Validated();
        return;
    }

    public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });

        var container = UnityHelper.GetContainerInstance("***");
        var securityHelper = container.Resolve<ISecurityHelper>();

        User currentUser = securityHelper.GetCurrentUser(); // Validates user based on HttpContext.Current.User
        if (currentUser == null)
        {
            context.SetError("invalid_grant", "The user could not be found.");
            return;
        }

        var identity = new ClaimsIdentity(context.Options.AuthenticationType);
        identity.AddClaim(new Claim("sub", currentUser.AccountName));
        identity.AddClaim(new Claim("role", "user"));

        context.Validated(identity);
    }
}

更新 哎呀,我忘了提供更多关于我们想要完成的事情的信息。如果可能的话,我们希望使用不记名身份验证票证,这样我们就不必在每次调用web api方法时都查找用户及其角色。

更新2: 根据Andrew的要求,下面是我的_securityHelper类的TLDR版本,特别是GetCurrentUser()方法。你会注意到我试图打电话:

HttpContext.Current.GetOwinContext().Request.User.Identity.Name

这始终为用户返回 null

public class SecurityHelper : ISecurityHelper
{
    private readonly ISecurityGroupController _securityGroupController;
    private readonly IUserController _userController;
    private readonly IEmployeeController _employeeController;
    private readonly IFieldPermissionController _fieldPermissionController;
    private readonly IOACController _oacController;

    public SecurityHelper(ISecurityGroupController securityGroupController,
        IUserController userController,
        IEmployeeController employeeController,
        IFieldPermissionController fieldPermissionController,
        IOACController oacController)
    {
        _securityGroupController = securityGroupController;
        _userController = userController;
        _employeeController = employeeController;
        _fieldPermissionController = fieldPermissionController;
        _oacController = oacController;
    }

    // ... other methods

    public User GetCurrentUser()
    {
        User user = _userController.GetByAccountName(HttpContext.Current.GetOwinContext().Request.User.Identity.Name);
        if (user != null)
        {
            List<OAC> memberships = _oacController.GetMemberships(user.SourceId).ToList();
            if (IsTestModeEnabled() && ((user.OACMemberships != null && user.OACMemberships.Count == 0) || user.OACMemberships == null))
            {
                user.OACMemberships = memberships;
            }
            else if (!IsTestModeEnabled())
            {
                user.OACMemberships = memberships;
            }
        }

        return user;
    }
}

2 个答案:

答案 0 :(得分:5)

本系列文章将是一个很好的起点:http://bitoftech.net/2014/06/01/token-based-authentication-asp-net-web-api-2-owin-asp-net-identity/

值得注意的是,将是以下代码,它基本上将承载令牌存储在本地存储中并将其附加到头部。显然还有很多,包括表单和实际的服务器身份验证系统,但这应该会给你一个不错的开始。

服务器组件:

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        ConfigureOAuth(app);
    //Rest of code is here;
    }

    public void ConfigureOAuth(IAppBuilder app)
    {
        OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
        {
            AllowInsecureHttp = true,
            TokenEndpointPath = new PathString("/token"),
            AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
            Provider = new SimpleAuthorizationServerProvider()
        };

        // Token Generation
        app.UseOAuthAuthorizationServer(OAuthServerOptions);
        app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());

    }
}

以及以下客户端代码:

'use strict';
app.factory('authService', ['$http', '$q', 'localStorageService', function ($http, $q, localStorageService) {

    var serviceBase = 'http://ngauthenticationapi.azurewebsites.net/';
    var authServiceFactory = {};

    var _authentication = {
        isAuth: false,
        userName : ""
    };

    var _saveRegistration = function (registration) {

        _logOut();

        return $http.post(serviceBase + 'api/account/register', registration).then(function (response) {
            return response;
        });

    };

    var _login = function (loginData) {

        var data = "grant_type=password&username=" + loginData.userName + "&password=" + loginData.password;

        var deferred = $q.defer();

        $http.post(serviceBase + 'token', data, { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }).success(function (response) {

            localStorageService.set('authorizationData', { token: response.access_token, userName: loginData.userName });

            _authentication.isAuth = true;
            _authentication.userName = loginData.userName;

            deferred.resolve(response);

        }).error(function (err, status) {
            _logOut();
            deferred.reject(err);
        });

        return deferred.promise;

    };

    var _logOut = function () {

        localStorageService.remove('authorizationData');

        _authentication.isAuth = false;
        _authentication.userName = "";

    };

    var _fillAuthData = function () {

        var authData = localStorageService.get('authorizationData');
        if (authData)
        {
            _authentication.isAuth = true;
            _authentication.userName = authData.userName;
        }

    }

    authServiceFactory.saveRegistration = _saveRegistration;
    authServiceFactory.login = _login;
    authServiceFactory.logOut = _logOut;
    authServiceFactory.fillAuthData = _fillAuthData;
    authServiceFactory.authentication = _authentication;

    return authServiceFactory;
}]);

一起
'use strict';
app.factory('authInterceptorService', ['$q', '$location', 'localStorageService', function ($q, $location, localStorageService) {

    var authInterceptorServiceFactory = {};

    var _request = function (config) {

        config.headers = config.headers || {};

        var authData = localStorageService.get('authorizationData');
        if (authData) {
            config.headers.Authorization = 'Bearer ' + authData.token;
        }

        return config;
    }

    var _responseError = function (rejection) {
        if (rejection.status === 401) {
            $location.path('/login');
        }
        return $q.reject(rejection);
    }

    authInterceptorServiceFactory.request = _request;
    authInterceptorServiceFactory.responseError = _responseError;

    return authInterceptorServiceFactory;
}]);

答案 1 :(得分:1)

查看本文,了解在OWIN中启用Windows身份验证的步骤: http://www.asp.net/aspnet/overview/owin-and-katana/enabling-windows-authentication-in-katana

来自文章:

  

Katana目前不提供用于Windows身份验证的OWIN中间件,因为此功能已在服务器中提供。

链接文章介绍了如何启用Windows身份验证以进行开发。对于部署,这些设置位于身份验证下的IIS中。当浏览器首次到达您的应用程序页面时,将提示用户输入用户名和密码。

相关问题