private static TokenManager GetTokenManager()
        {
            var options       = CreateOptions();
            var claimsManager = CreateClaimsManager(options);

            var factory                = new LoggerFactory();
            var protector              = new EphemeralDataProtectionProvider(factory).CreateProtector("test");
            var codeSerializer         = new TokenDataSerializer <AuthorizationCode>(options, ArrayPool <char> .Shared);
            var codeDataFormat         = new SecureDataFormat <AuthorizationCode>(codeSerializer, protector);
            var refreshTokenSerializer = new TokenDataSerializer <RefreshToken>(options, ArrayPool <char> .Shared);
            var refreshTokenDataFormat = new SecureDataFormat <RefreshToken>(refreshTokenSerializer, protector);

            var timeStampManager   = new TimeStampManager();
            var credentialsPolicy  = GetCredentialsPolicy(options, timeStampManager);
            var codeIssuer         = new AuthorizationCodeIssuer(claimsManager, codeDataFormat, new ProtocolErrorProvider());
            var accessTokenIssuer  = new JwtAccessTokenIssuer(claimsManager, credentialsPolicy, new JwtSecurityTokenHandler(), options);
            var idTokenIssuer      = new JwtIdTokenIssuer(claimsManager, credentialsPolicy, new JwtSecurityTokenHandler(), options);
            var refreshTokenIssuer = new RefreshTokenIssuer(claimsManager, refreshTokenDataFormat);

            return(new TokenManager(
                       codeIssuer,
                       accessTokenIssuer,
                       idTokenIssuer,
                       refreshTokenIssuer,
                       new ProtocolErrorProvider()));
        }
예제 #2
0
        public DiscourseAuthenticationOptions()
        {
            CallbackPath = "/auth-discourse";

            _nonceCookieBuilder = new DiscourseNonceCookieBuilder(this)
            {
                Name         = ".CitizenFX.Discourse.Nonce.",
                HttpOnly     = true,
                SameSite     = SameSiteMode.None,
                SecurePolicy = CookieSecurePolicy.SameAsRequest,
                IsEssential  = true,
            };

            DataProtectionProvider = Microsoft.AspNetCore.DataProtection.DataProtectionProvider.Create("FXServer");

            var dataProtector = DataProtectionProvider.CreateProtector(
                typeof(DiscourseAuthenticationHandler).FullName,
                typeof(string).FullName,
                "DAO",
                "v1");

            StringDataFormat = new SecureDataFormat <string>(new StringSerializer(), dataProtector);

            StateDataFormat = new PropertiesDataFormat(dataProtector);
        }
예제 #3
0
        public void Configuration(IAppBuilder app)
        {
            var container = new Container();

            container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle();
            container.RegisterWebApiControllers(GlobalConfiguration.Configuration);

            var sdt =
                new SecureDataFormat <AuthenticationTicket>(
                    new TicketSerializer(),
                    new DpapiDataProtectionProvider().Create("ASP.NET Identity"),
                    TextEncodings.Base64
                    );

            container.Options.AllowOverridingRegistrations = true;

            container.Register <AccountController>(() => new AccountController(sdt), Lifestyle.Scoped);

            container.Options.AllowOverridingRegistrations = false;

            Services.Startup.RegisterComponents(container);

            // This is an extension method from the integration package.
            container.Verify();
            app.Use(async(context, next) =>
            {
                using (container.BeginExecutionContextScope())
                {
                    await next();
                }
            });
            GlobalConfiguration.Configuration.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container);
            ConfigureAuth(app);
        }
예제 #4
0
        public void OwinDataHandler(SecureDataFormat <AuthenticationProperties> secure)
        {
            AuthenticationProperties props = new AuthenticationProperties();

            string secured = secure.Protect(props);
            AuthenticationProperties unsecured = secure.Unprotect(secured);

            byte[] decoded = new byte[10];
        }
예제 #5
0
        public void ProtectDataRoundTrips()
        {
            var provider         = ServiceProvider.GetRequiredService <IDataProtectionProvider>();
            var prototector      = provider.CreateProtector("test");
            var secureDataFormat = new SecureDataFormat <string>(new StringSerializer(), prototector);

            string input         = "abcdefghijklmnopqrstuvwxyz0123456789";
            var    protectedData = secureDataFormat.Protect(input);
            var    result        = secureDataFormat.Unprotect(protectedData);

            Assert.Equal(input, result);
        }
예제 #6
0
        public void OwinDataHandler(ITextEncoder encoder, SecureDataFormat <AuthenticationProperties> secure)
        {
            AuthenticationProperties props = new AuthenticationProperties();

            string secured = secure.Protect(props);
            AuthenticationProperties unsecured = secure.Unprotect(secured);

            byte[] decoded = new byte[10];
            string encoded = encoder.Encode(decoded);

            decoded = encoder.Decode(encoded);
        }
예제 #7
0
        public void UnprotectWithDifferentPurposeFails()
        {
            var provider         = ServiceProvider.GetRequiredService <IDataProtectionProvider>();
            var prototector      = provider.CreateProtector("test");
            var secureDataFormat = new SecureDataFormat <string>(new StringSerializer(), prototector);

            string input         = "abcdefghijklmnopqrstuvwxyz0123456789";
            string purpose       = "purpose1";
            var    protectedData = secureDataFormat.Protect(input, purpose);
            var    result        = secureDataFormat.Unprotect(protectedData); // Null other purpose

            Assert.Null(result);

            result = secureDataFormat.Unprotect(protectedData, "purpose2");
            Assert.Null(result);
        }
        public async Task JwtRefreshTokenIssuer_ExchangeRefreshTokenAsync_ReadTheRefreshTokenCorrectly()
        {
            // Arrange
            var options   = GetOptions();
            var protector = new EphemeralDataProtectionProvider(new LoggerFactory()).CreateProtector("test");
            var refreshTokenSerializer = new TokenDataSerializer <RefreshToken>(options, ArrayPool <char> .Shared);
            var dataFormat             = new SecureDataFormat <RefreshToken>(refreshTokenSerializer, protector);

            var expectedDateTime = new DateTimeOffset(2000, 01, 01, 0, 0, 0, TimeSpan.FromHours(1));
            var now         = DateTimeOffset.UtcNow;
            var expires     = new DateTimeOffset(now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second, TimeSpan.Zero);
            var timeManager = GetTimeManager(expectedDateTime, expires, expectedDateTime);

            var issuer  = new RefreshTokenIssuer(GetClaimsManager(timeManager), dataFormat);
            var context = GetTokenGenerationContext(
                new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim(ClaimTypes.NameIdentifier, "user") })),
                new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim(IdentityServiceClaimTypes.ClientId, "clientId") })));

            context.InitializeForToken(TokenTypes.RefreshToken);

            await issuer.IssueRefreshTokenAsync(context);

            var message = new OpenIdConnectMessage();

            message.ClientId     = "clientId";
            message.RefreshToken = context.RefreshToken.SerializedValue;

            // Act
            var grant = await issuer.ExchangeRefreshTokenAsync(message);

            // Assert
            Assert.NotNull(grant);
            Assert.NotNull(grant.Token);
            var refreshToken = Assert.IsType <RefreshToken>(grant.Token);

            Assert.Equal("clientId", refreshToken.ClientId);
            Assert.Equal("user", refreshToken.UserId);

            Assert.Equal(expectedDateTime, refreshToken.IssuedAt);
            Assert.Equal(expires, refreshToken.Expires);
            Assert.Equal(expectedDateTime, refreshToken.NotBefore);

            Assert.Equal(new[] { "openid profile" }, refreshToken.Scopes.ToArray());
        }
        public static void Initialize(IAppBuilder app)
        {
            var container = new Container();

            container.Options.DefaultScopedLifestyle = new WebApiRequestLifestyle();
            container.RegisterWebApiControllers(GlobalConfiguration.Configuration);
            container.Options.AllowOverridingRegistrations = true;


            //container.Register<IAuthenticationManager>(() => AdvancedExtensions.IsVerifying(container) ? new OwinContext(new Dictionary<string, object>()).Authentication : HttpContext.Current.GetOwinContext().Authentication);

            ApplicationUserManager um = new ApplicationUserManager(new UserStore <ApplicationUser>(new ApplicationDbContext("DefaultConnection")));
            //ApplicationSignInManager sm = new ApplicationSignInManager(um, container.GetInstance<IAuthenticationManager>());
            SecureDataFormat <AuthenticationTicket> sdt = new SecureDataFormat <AuthenticationTicket>(
                new TicketSerializer(),
                new DpapiDataProtectionProvider().Create("ASP.NET Identity"),
                TextEncodings.Base64);

            container.Register <AccountController>(() => new AccountController(um, sdt), Lifestyle.Scoped);

            //container.Register<ApplicationSignInManager>(() => new ApplicationSignInManager(um, container.GetInstance<IAuthenticationManager>()), Lifestyle.Scoped);
            //container.Register<LoginController>(() => new LoginController(um, sm), Lifestyle.Scoped);
            container.Options.AllowOverridingRegistrations = false;

            container.RegisterWebApiRequest <ApplicationDbContext>(() => new ApplicationDbContext("DefaultConnection"));
            container.Register(typeof(IRepository <>), typeof(GenericRepository <>), Lifestyle.Scoped);

            container.Verify();

            app.Use(async(context, next) => {
                using (container.BeginExecutionContextScope()) {
                    await next();
                }
            });
            GlobalConfiguration.Configuration.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container);
        }
예제 #10
0
    public async Task CanFetchUserDetails()
    {
        var verifyCredentialsEndpoint      = "https://api.twitter.com/1.1/account/verify_credentials.json";
        var finalVerifyCredentialsEndpoint = string.Empty;
        var finalAuthorizationParameter    = string.Empty;
        var stateFormat = new SecureDataFormat <RequestToken>(new RequestTokenSerializer(), new EphemeralDataProtectionProvider(NullLoggerFactory.Instance).CreateProtector("TwitterTest"));

        using var host = await CreateHost((options) =>
        {
            options.ConsumerKey            = "Test App Id";
            options.ConsumerSecret         = "PLACEHOLDER";
            options.RetrieveUserDetails    = true;
            options.StateDataFormat        = stateFormat;
            options.BackchannelHttpHandler = new TestHttpMessageHandler
            {
                Sender = req =>
                {
                    if (req.RequestUri.GetComponents(UriComponents.SchemeAndServer | UriComponents.Path, UriFormat.UriEscaped) == "https://api.twitter.com/oauth/access_token")
                    {
                        var res     = new HttpResponseMessage(HttpStatusCode.OK);
                        var content = new Dictionary <string, string>()
                        {
                            ["oauth_token"]        = "Test Access Token",
                            ["oauth_token_secret"] = "PLACEHOLDER",
                            ["user_id"]            = "123456",
                            ["screen_name"]        = "@dotnet"
                        };
                        res.Content = new FormUrlEncodedContent(content);
                        return(res);
                    }
                    if (req.RequestUri.GetComponents(UriComponents.SchemeAndServer | UriComponents.Path, UriFormat.UriEscaped) ==
                        new Uri(verifyCredentialsEndpoint).GetComponents(UriComponents.SchemeAndServer | UriComponents.Path, UriFormat.UriEscaped))
                    {
                        finalVerifyCredentialsEndpoint = req.RequestUri.ToString();
                        finalAuthorizationParameter    = req.Headers.Authorization.Parameter;
                        var res           = new HttpResponseMessage(HttpStatusCode.OK);
                        var graphResponse = "{ \"email\": \"Test email\" }";
                        res.Content       = new StringContent(graphResponse, Encoding.UTF8);
                        return(res);
                    }
                    return(null);
                }
            };
        });

        var token = new RequestToken()
        {
            Token       = "TestToken",
            TokenSecret = "PLACEHOLDER",
            Properties  = new()
        };

        var correlationKey   = ".xsrf";
        var correlationValue = "TestCorrelationId";

        token.Properties.Items.Add(correlationKey, correlationValue);
        token.Properties.RedirectUri = "/me";
        var state = stateFormat.Protect(token);

        using var server = host.GetTestServer();
        var transaction = await server.SendAsync(
            "https://example.com/signin-twitter?oauth_token=TestToken&oauth_verifier=TestVerifier",
            $".AspNetCore.Correlation.{correlationValue}=N;__TwitterState={UrlEncoder.Default.Encode(state)}");

        Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
        Assert.Equal("/me", transaction.Response.Headers.GetValues("Location").First());

        Assert.Equal(1, finalVerifyCredentialsEndpoint.Count(c => c == '?'));
        Assert.Contains("include_email=true", finalVerifyCredentialsEndpoint);

        Assert.Contains("oauth_consumer_key=", finalAuthorizationParameter);
        Assert.Contains("oauth_nonce=", finalAuthorizationParameter);
        Assert.Contains("oauth_signature=", finalAuthorizationParameter);
        Assert.Contains("oauth_signature_method=", finalAuthorizationParameter);
        Assert.Contains("oauth_timestamp=", finalAuthorizationParameter);
        Assert.Contains("oauth_token=", finalAuthorizationParameter);
        Assert.Contains("oauth_version=", finalAuthorizationParameter);

        var authCookie = transaction.AuthenticationCookieValue;

        transaction = await server.SendAsync("https://example.com/me", authCookie);

        Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode);
        var expectedIssuer = TwitterDefaults.AuthenticationScheme;

        Assert.Equal("@dotnet", transaction.FindClaimValue(ClaimTypes.Name, expectedIssuer));
        Assert.Equal("123456", transaction.FindClaimValue(ClaimTypes.NameIdentifier, expectedIssuer));
        Assert.Equal("123456", transaction.FindClaimValue("urn:twitter:userid", expectedIssuer));
        Assert.Equal("@dotnet", transaction.FindClaimValue("urn:twitter:screenname", expectedIssuer));
        Assert.Equal("Test email", transaction.FindClaimValue(ClaimTypes.Email, expectedIssuer));
    }
예제 #11
0
    public async Task CanSignIn()
    {
        var stateFormat = new SecureDataFormat <RequestToken>(new RequestTokenSerializer(), new EphemeralDataProtectionProvider(NullLoggerFactory.Instance).CreateProtector("TwitterTest"));

        using var host = await CreateHost((options) =>
        {
            options.ConsumerKey            = "Test App Id";
            options.ConsumerSecret         = "PLACEHOLDER";
            options.SaveTokens             = true;
            options.StateDataFormat        = stateFormat;
            options.BackchannelHttpHandler = new TestHttpMessageHandler
            {
                Sender = req =>
                {
                    if (req.RequestUri.GetComponents(UriComponents.SchemeAndServer | UriComponents.Path, UriFormat.UriEscaped) == "https://api.twitter.com/oauth/access_token")
                    {
                        var res     = new HttpResponseMessage(HttpStatusCode.OK);
                        var content = new Dictionary <string, string>()
                        {
                            ["oauth_token"]        = "Test Access Token",
                            ["oauth_token_secret"] = "PLACEHOLDER",
                            ["user_id"]            = "123456",
                            ["screen_name"]        = "@dotnet"
                        };
                        res.Content = new FormUrlEncodedContent(content);
                        return(res);
                    }
                    return(null);
                }
            };
        });

        var token = new RequestToken()
        {
            Token       = "TestToken",
            TokenSecret = "PLACEHOLDER",
            Properties  = new()
        };

        var correlationKey   = ".xsrf";
        var correlationValue = "TestCorrelationId";

        token.Properties.Items.Add(correlationKey, correlationValue);
        token.Properties.RedirectUri = "/me";
        var state = stateFormat.Protect(token);

        using var server = host.GetTestServer();
        var transaction = await server.SendAsync(
            "https://example.com/signin-twitter?oauth_token=TestToken&oauth_verifier=TestVerifier",
            $".AspNetCore.Correlation.{correlationValue}=N;__TwitterState={UrlEncoder.Default.Encode(state)}");

        Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
        Assert.Equal("/me", transaction.Response.Headers.GetValues("Location").First());

        var authCookie = transaction.AuthenticationCookieValue;

        transaction = await server.SendAsync("https://example.com/me", authCookie);

        Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode);
        var expectedIssuer = TwitterDefaults.AuthenticationScheme;

        Assert.Equal("@dotnet", transaction.FindClaimValue(ClaimTypes.Name, expectedIssuer));
        Assert.Equal("123456", transaction.FindClaimValue(ClaimTypes.NameIdentifier, expectedIssuer));
        Assert.Equal("123456", transaction.FindClaimValue("urn:twitter:userid", expectedIssuer));
        Assert.Equal("@dotnet", transaction.FindClaimValue("urn:twitter:screenname", expectedIssuer));

        transaction = await server.SendAsync("https://example.com/tokens", authCookie);

        Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode);
        Assert.Equal("Test Access Token", transaction.FindTokenValue("access_token"));
        Assert.Equal("PLACEHOLDER", transaction.FindTokenValue("access_token_secret"));
    }