使用ASP.NET MVC和WebApi的Angular.js SPA安全性

时间:2016-03-16 00:25:44

标签: angularjs asp.net-mvc asp.net-web-api single-page-application

我正在使用Angular.js和ASP.NET构建SPA,我想知道保护它的最佳方法是什么。

这就是我需要的:

我想使用MVC框架仅将我的应用程序隐藏到已登录的用户。因此,用户在启动SPA之前要做的第一件事就是使用简单的登录表单登录网站。

当Angular应用程序启动时,它将使用REST请求与我的ApiController进行通信。

我还希望我的用户在20分钟不活动后自动注销。

我知道REST应该是无国籍的...但我无法确定如何在没有会话的情况下实现我所需要的所有内容......

但另一方面,我希望能够将我的WebAPI与未来的移动应用程序结合使用。我将不得不使用令牌进行此应用程序的身份验证。

对我来说,实现这种身份验证的最佳方式是什么?

谢谢你的时间!

2 个答案:

答案 0 :(得分:3)

我开发了一个完整的安全层,其条件与您的相同,请参阅本文here中详细解释的内容。

顺便说一句,令牌将在20分钟后自动失效,因为当您创建它时,您将立即设置它的到期日期;每次你要发出请求时,系统都会用当前日期检查令牌exp日期,如果时间过去则拒绝你的令牌。例如,这是一个带有令牌和刷新令牌设置的典型oauth服务器配置:

internal static OAuthAuthorizationServerOptions GetAuthorizationServerOptions(IComponentContext scope)
    {
        OAuthAuthorizationServerOptions oAuthServerOptions = new OAuthAuthorizationServerOptions
        {                
            AllowInsecureHttp = true,
            ApplicationCanDisplayErrors = true,
            TokenEndpointPath = new PathString(Constants.PublicAuth.OAUTH_TOKEN_PATH),
            AuthorizeEndpointPath = new PathString(Constants.ExternalAuth.AUTH_ENDPOINT),
            AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(Constants.PublicAuth.TOKEN_EXPIRATION_IN_MINUTES),
            Provider = scope.Resolve<AuthorizationServerProvider>(),
            AccessTokenFormat = new CustomJwtFormat(),
            RefreshTokenProvider = scope.Resolve<SimpleRefreshTokenProvider>()
        };
        return oAuthServerOptions;
    }

刷新令牌也非常有用,但您必须自己管理令牌替换;例如,在我们的应用程序中,我们通过单个服务传递每个API调用,如果服务器响应401 (unauthorized),它将尝试使用刷新令牌请求新令牌,然后它将再次尝试相同的调用。只有在第二次失败后,您才会被重定向到登录页面。

例如:

function executeCallWithAuth(method, url, payload, params) {
    var defer = $q.defer();
    debug.logf('{0}: {1}', method.toUpperCase(), url);
    $http({ method: method, url: url, data: payload, headers: createHeaders(), params: params }).then(
        function(results) { defer.resolve(results); }, 
        function(error) {
            if (error.status !== 401) defer.reject(error);
            else {
                debug.warn(`Call to: ${method}:${url} result in 401, try token refresh...`);
                auth.refreshToken().then(
                    function() {
                        debug.warn('Token refresh succesfully, retry api call...');
                        $http({ method: method, url: url, data: payload, headers: createHeaders() }).then(
                            function(results) { defer.resolve(results); },
                            function(errors) { defer.reject(errors); });
                    },
                    function(tokenError) {
                        debug.warn('Token refresh rejected, redirect to login.');
                        $state.go('login');
                        defer.reject(tokenError);
                    });
            }
        });

    return defer.promise;
}

    function createHeaders() {
    var headers = {
    };

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

    return headers;
}

使用Angular保护路线的最佳方法是“不要创建路线”。基本上,您需要加载用户配置文件,然后才能创建仅可以导航到的页面的路径。如果您没有为页面创建路线,则无需保护该页面:Angular会自动将用户发送到404。

答案 1 :(得分:0)

我会使用OAuth2保护您的WebAPI调用(您甚至可以使用随附的内置Identity 2.0提供程序)。保持WebAPI无状态,使用SSL(考虑使用过滤器强制它),并使用[Authorize]标签保护您的服务。在MVC方面,这将必须维护状态,并且您将希望登录表单从WebAPI层获取OAuth2令牌并将其传递给Angular。将此期限设置为20分钟。你也可以在这里使用cookies身份验证模型,因为它需要在MVC端是有状态的,但是Angular对WebAPI层进行的所有ajax调用都需要在授权请求头中将OAuth2令牌作为承载令牌传递。 / p>