我可能过于复杂了,但我们使用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;
}
}
答案 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中。当浏览器首次到达您的应用程序页面时,将提示用户输入用户名和密码。