在AWS上运行时,OWIN TestServer授权失败

时间:2015-07-08 14:14:32

标签: amazon-web-services asp.net-web-api2 owin

我有一个使用OWIN承载令牌授权的WebApi应用程序。这是使用OWIN TestServer进行单元测试的。测试非常简单:它向服务器创建10个同时的授权请求,并验证每个请求是否收到响应。

测试在我的开发计算机上正常运行但在Amazon Web Services上失败并且跟踪堆栈跟踪:

MESSAGE:
System.AggregateException : One or more errors occurred.
  ----> System.Security.Cryptography.CryptographicException : Access is denied.

+++++++++++++++++++
STACK TRACE:
at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
at MyTestMethod()
--CryptographicException
at System.Security.Cryptography.ProtectedData.Protect(Byte[] userData, Byte[] optionalEntropy, DataProtectionScope scope)
at System.Security.Cryptography.DpapiDataProtector.ProviderProtect(Byte[] userData)
at Microsoft.Owin.Security.DataHandler.SecureDataFormat`1.Protect(TData data)
at Microsoft.Owin.Security.OAuth.OAuthAuthorizationServerHandler.<InvokeTokenEndpointAsync>d__22.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Owin.Security.OAuth.OAuthAuthorizationServerHandler.<InvokeAsync>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Owin.Security.Infrastructure.AuthenticationMiddleware`1.<Invoke>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Owin.Testing.OwinClientHandler.<>c__DisplayClass1.<<SendAsync>b__0>d__3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at Microsoft.Owin.Testing.OwinClientHandler.<SendAsync>d__6.MoveNext()

Google搜索此问题并未提供完全匹配。

测试方法:

    public void MyTestMethod()
    {
        const int loginNumber = 10;
        List<Tuple<string, string>> userList = new List<Tuple<string, string>>();

        for (int i = 0; i < loginNumber; ++i)
            userList.Add(new Tuple<string, string>("SomeName", "SomePassword"));

        using (var server = TestServer.Create<Startup>())
        {
            var loginTasks = userList.Select(item => server.CreateRequest("/token").And(x => x.Content = new FormUrlEncodedContent(new[]
            {
                new KeyValuePair<string, string>("username", item.Item1),
                new KeyValuePair<string, string>("password", item.Item2),
                new KeyValuePair<string, string>("grant_type", "password")
            })).PostAsync());

            HttpResponseMessage[] loginTasksResults = Task.WhenAll(loginTasks).Result; // AggregatedException here

            // ...
        }
    }

启动课程

public partial class Startup
{
    public void Configuration(IAppBuilder app)
    {
        ConfigureOAuth(app);

        HttpConfiguration config = new HttpConfiguration();
        WebApiConfig.Register(config);
        app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);

        NinjectWebCommon.Start();
        config.DependencyResolver = new NinjectDependencyResolver(NinjectWebCommon.bootstrapper.Kernel);

        app.UseWebApi(config);
        app.MapSignalR();
    }

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

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

授权提供商

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

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

        if (context.UserName == null || context.Password == null)
        {
            context.SetError("invalid_grant", "The user name or password is empty.");
            return;
        }

        string authenticationId = Guid.NewGuid().ToString("n");

        ClaimsIdentity oAuthIdentity = new ClaimsIdentity(context.Options.AuthenticationType);
        oAuthIdentity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
        oAuthIdentity.AddClaim(new Claim("sub", context.UserName));
        oAuthIdentity.AddClaim(new Claim("role", "user"));
        oAuthIdentity.AddClaim(new Claim("auth_id", authenticationId));

        context.Validated(oAuthIdentity);
    }
}

0 个答案:

没有答案