我可能是过于复杂的事情,但是我们有一个使用
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
这对User总是返回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; } }
解决方法
本文系列将是一个开始的好地方:
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',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; }]);