Пример #1
0
        public static AuthenticationTicket Read(BinaryReader reader)
        {
            if (reader.ReadInt32() != FormatVersion)
            {
                return(null);
            }

            string authenticationType = reader.ReadString();
            string nameClaimType      = reader.ReadString();
            string roleClaimType      = reader.ReadString();
            int    count  = reader.ReadInt32();
            var    claims = new Claim[count];

            for (int index = 0; index != count; ++index)
            {
                string type      = reader.ReadString();
                string value     = reader.ReadString();
                string valueType = reader.ReadString();
                string issuer    = reader.ReadString();
                claims[index] = new Claim(type, value, valueType, issuer);
            }
            var identity = new ClaimsIdentity(claims, authenticationType, nameClaimType, roleClaimType);
            AuthenticationExtra extra = ExtraSerializer.Read(reader);

            return(new AuthenticationTicket(identity, extra));
        }
Пример #2
0
 public FormsResponseSignInContext(IDictionary <string, object> environment, string authenticationType, ClaimsIdentity identity, AuthenticationExtra extra)
 {
     Environment        = environment;
     AuthenticationType = authenticationType;
     Identity           = identity;
     Extra = extra;
 }
 public FormsResponseSignInContext(IDictionary<string, object> environment, string authenticationType, ClaimsIdentity identity, IDictionary<string, string> extra)
 {
     Environment = environment;
     AuthenticationType = authenticationType;
     Identity = identity;
     Extra = new AuthenticationExtra(extra);
 }
Пример #4
0
        public Task Invoke(IDictionary <string, object> env)
        {
            var request  = new OwinRequest(env);
            var response = new OwinResponse(env);

            // The forms auth module has a bug where it null refs on a null Extra
            var headers = request.Get <IDictionary <string, string[]> >(Owin.Types.OwinConstants.RequestHeaders);

            var    cookies = request.GetCookies();
            string cookieValue;

            if (cookies != null && cookies.TryGetValue("jabbr.id", out cookieValue))
            {
                AuthenticationTicket ticket = _ticketHandler.Unprotect(cookieValue);
                if (ticket != null && ticket.Extra == null)
                {
                    var extra = new AuthenticationExtra();
                    extra.IsPersistent = true;
                    extra.IssuedUtc    = DateTime.UtcNow;
                    extra.ExpiresUtc   = DateTime.UtcNow.AddDays(30);

                    var newTicket = new AuthenticationTicket(ticket.Identity, extra);

                    var cookieBuilder = new StringBuilder();
                    foreach (var cookie in cookies)
                    {
                        string value = cookie.Value;

                        if (cookie.Key == "jabbr.id")
                        {
                            // Create a new ticket preserving the identity of the user
                            // so they don't get logged out
                            value = _ticketHandler.Protect(newTicket);
                            response.AddCookie("jabbr.id", value, new CookieOptions
                            {
                                Expires  = extra.ExpiresUtc.Value.UtcDateTime,
                                HttpOnly = true
                            });
                        }

                        if (cookieBuilder.Length > 0)
                        {
                            cookieBuilder.Append(";");
                        }

                        cookieBuilder.Append(cookie.Key)
                        .Append("=")
                        .Append(Uri.EscapeDataString(value));
                    }

                    headers["Cookie"] = new[] { cookieBuilder.ToString() };
                }
            }

            return(_next(env));
        }
Пример #5
0
 private static ExternalAccessToken Deserialize(AuthenticationExtra extra)
 {
     return(new ExternalAccessToken
     {
         LoginProvider = extra.Properties[LoginProvider],
         ProviderKey = extra.Properties[ProviderKey],
         DisplayName = extra.Properties[DisplayName],
         Expires = DateTime.ParseExact(extra.Properties[Expires], "u", CultureInfo.InvariantCulture)
     });
 }
Пример #6
0
        /// <summary></summary>
        /// <param name="context"></param>
        /// <param name="user"></param>
        /// <param name="extra"></param>
        public static void SignIn(this HttpContext context, ClaimsPrincipal user, AuthenticationExtra extra)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            OwinResponse response = GetOwinResponse(context);

            response.Grant(user, extra);
        }
Пример #7
0
        public Task Invoke(IDictionary <string, object> env)
        {
            var request  = new OwinRequest(env);
            var response = new OwinResponse(env);

            string cookieValue = request.Cookies["jabbr.id"];

            if (!String.IsNullOrEmpty(cookieValue))
            {
                AuthenticationTicket ticket = _ticketHandler.Unprotect(cookieValue);
                if (ticket != null && ticket.Extra == null)
                {
                    var extra = new AuthenticationExtra();
                    extra.IsPersistent = true;
                    extra.IssuedUtc    = DateTime.UtcNow;
                    extra.ExpiresUtc   = DateTime.UtcNow.AddDays(30);

                    var newTicket = new AuthenticationTicket(ticket.Identity, extra);

                    var cookieBuilder = new StringBuilder();
                    foreach (var cookie in request.Cookies)
                    {
                        string value = cookie.Value;

                        if (cookie.Key == "jabbr.id")
                        {
                            // Create a new ticket preserving the identity of the user
                            // so they don't get logged out
                            value = _ticketHandler.Protect(newTicket);
                            response.Cookies.Append("jabbr.id", value, new CookieOptions
                            {
                                Expires  = extra.ExpiresUtc.Value.UtcDateTime,
                                HttpOnly = true
                            });
                        }

                        if (cookieBuilder.Length > 0)
                        {
                            cookieBuilder.Append(";");
                        }

                        cookieBuilder.Append(cookie.Key)
                        .Append("=")
                        .Append(Uri.EscapeDataString(value));
                    }

                    request.Headers["Cookie"] = cookieBuilder.ToString();
                }
            }

            return(_next(env));
        }
Пример #8
0
 public GoogleAuthenticatedContext(
     IDictionary <string, object> environment,
     ClaimsIdentity identity,
     AuthenticationExtra extra,
     XElement responseMessage,
     IDictionary <string, string> attributeExchangeProperties)
     : base(environment)
 {
     Identity                    = identity;
     Extra                       = extra;
     ResponseMessage             = responseMessage;
     AttributeExchangeProperties = attributeExchangeProperties;
 }
Пример #9
0
 public GoogleAuthenticatedContext(
     IDictionary<string, object> environment,
     ClaimsIdentity identity,
     AuthenticationExtra extra,
     XElement responseMessage,
     IDictionary<string, string> attributeExchangeProperties)
     : base(environment)
 {
     Identity = identity;
     Extra = extra;
     ResponseMessage = responseMessage;
     AttributeExchangeProperties = attributeExchangeProperties;
 }
Пример #10
0
            private static AuthenticationExtra Serialize(ExternalAccessToken token)
            {
                AuthenticationExtra extra = new AuthenticationExtra();

                if (token == null)
                {
                    return(extra);
                }

                extra.Properties[LoginProvider] = token.LoginProvider ?? String.Empty;
                extra.Properties[ProviderKey]   = token.ProviderKey ?? String.Empty;
                extra.Properties[DisplayName]   = token.DisplayName ?? String.Empty;
                extra.Properties[Expires]       = token.Expires.ToString("u", CultureInfo.InvariantCulture);
                return(extra);
            }
Пример #11
0
            public ExternalAccessToken Unprotect(string protectedText)
            {
                AuthenticationTicket ticket = InnerHandler.Unprotect(protectedText);

                if (ticket == null)
                {
                    return(null);
                }

                AuthenticationExtra extra = ticket.Extra;

                if (extra == null)
                {
                    return(null);
                }

                return(Deserialize(extra));
            }
Пример #12
0
        protected override async Task ApplyResponseChallenge()
        {
            _logger.WriteVerbose("ApplyResponseChallenge");

            if (Response.StatusCode != 401)
            {
                return;
            }

            AuthenticationResponseChallenge challenge = Helper.LookupChallenge(Options.AuthenticationType, Options.AuthenticationMode);

            if (challenge != null)
            {
                string requestPrefix = Request.Scheme + "://" + Request.Host;

                string currentQueryString = Request.QueryString;
                string currentUri         = string.IsNullOrEmpty(currentQueryString)
                    ? requestPrefix + Request.PathBase + Request.Path
                    : requestPrefix + Request.PathBase + Request.Path + "?" + currentQueryString;

                string redirectUri = requestPrefix + Request.PathBase + Options.ReturnEndpointPath;

                AuthenticationExtra extra = challenge.Extra;
                if (string.IsNullOrEmpty(extra.RedirectUrl))
                {
                    extra.RedirectUrl = currentUri;
                }

                // OAuth2 10.12 CSRF
                GenerateCorrelationId(extra);

                string state = Options.StateDataHandler.Protect(extra);

                string authorizationEndpoint =
                    "https://www.facebook.com/dialog/oauth" +
                    "?response_type=code" +
                    "&client_id=" + Uri.EscapeDataString(Options.AppId ?? string.Empty) +
                    "&redirect_uri=" + Uri.EscapeDataString(redirectUri) +
                    "&scope=" + Uri.EscapeDataString(Options.Scope ?? string.Empty) +
                    "&state=" + Uri.EscapeDataString(state);

                Response.Redirect(authorizationEndpoint);
            }
        }
Пример #13
0
        protected void GenerateCorrelationId(AuthenticationExtra extra)
        {
            var correlationKey = Constants.CorrelationPrefix + BaseOptions.AuthenticationType;

            var nonceBytes = new byte[32];

            Random.GetBytes(nonceBytes);
            var correlationId = TextEncodings.Base64Url.Encode(nonceBytes);

            var cookieOptions = new CookieOptions
            {
                HttpOnly = true,
                Secure   = Request.IsSecure
            };

            extra.Properties[correlationKey] = correlationId;

            Response.AddCookie(correlationKey, correlationId, cookieOptions);
        }
Пример #14
0
        public AuthenticationTicket Unprotect(string protectedText)
        {
            var expectedIssuer     = MetadataResolver.GetIssuer(Tenant);
            var validSigningTokens = MetadataResolver.GetSigningTokens(Tenant);

            var tokenHandler = new JwtSecurityTokenHandler()
            {
                CertificateValidator = X509CertificateValidator.None
            };

            var validationParameters = new TokenValidationParameters
            {
                AllowedAudience = Audience,
                ValidIssuer     = expectedIssuer,
                SigningTokens   = validSigningTokens
            };

            ClaimsPrincipal claimsPrincipal = tokenHandler.ValidateToken(protectedText, validationParameters);
            var             claimsIdentity  = (ClaimsIdentity)claimsPrincipal.Identity;

            var authenticationExtra = new AuthenticationExtra(new Dictionary <string, string>());

            if (claimsIdentity.Claims.Any(c => c.Type == "exp"))
            {
                var expiryClaim = (from c in claimsIdentity.Claims where c.Type == "exp" select c.Value).Single();
                authenticationExtra.ExpiresUtc = _epoch.AddSeconds(Convert.ToInt64(expiryClaim));
            }

            if (claimsIdentity.Claims.Any(c => c.Type == "iat"))
            {
                var issued = (from c in claimsIdentity.Claims where c.Type == "iat" select c.Value).Single();
                authenticationExtra.IssuedUtc = _epoch.AddSeconds(Convert.ToInt64(issued));
            }

            return(new AuthenticationTicket(claimsIdentity, authenticationExtra));
        }
        /// <summary></summary>
        /// <param name="context"></param>
        /// <param name="authenticationType"> </param>
        /// <param name="claims"></param>
        /// <param name="nameClaimType"></param>
        /// <param name="roleClaimType"></param>
        /// <param name="isPersistent"></param>
        /// <exception cref="ArgumentNullException"></exception>
        public static void SignIn(this HttpContextBase context, string authenticationType, IEnumerable <Claim> claims, string nameClaimType, string roleClaimType, bool isPersistent)
        {
            if (authenticationType == null)
            {
                throw new ArgumentNullException("authenticationType");
            }
            if (claims == null)
            {
                throw new ArgumentNullException("claims");
            }
            if (nameClaimType == null)
            {
                throw new ArgumentNullException("nameClaimType");
            }
            if (roleClaimType == null)
            {
                throw new ArgumentNullException("roleClaimType");
            }
            var extra = new AuthenticationExtra {
                IsPersistent = isPersistent
            };

            context.SignIn(new ClaimsPrincipal(new ClaimsIdentity(claims, authenticationType, nameClaimType, roleClaimType)), extra);
        }
Пример #16
0
        protected bool ValidateCorrelationId(AuthenticationExtra extra, ILogger logger)
        {
            var correlationKey = Constants.CorrelationPrefix + BaseOptions.AuthenticationType;

            string correlationCookie;

            if (!Request.GetCookies().TryGetValue(
                    correlationKey,
                    out correlationCookie))
            {
                logger.WriteWarning(string.Format("{0} cookie not found", correlationKey));
                return(false);
            }

            Response.DeleteCookie(correlationKey);

            string correlationExtra;

            if (!extra.Properties.TryGetValue(
                    correlationKey,
                    out correlationExtra))
            {
                logger.WriteWarning(string.Format("{0} state property not found", correlationKey));
                return(false);
            }

            extra.Properties.Remove(correlationKey);

            if (!string.Equals(correlationCookie, correlationExtra, StringComparison.Ordinal))
            {
                logger.WriteWarning(string.Format("{0} correlation cookie and state property mismatch", correlationKey));
                return(false);
            }

            return(true);
        }
Пример #17
0
 public void Grant(ClaimsIdentity identity, AuthenticationExtra extra)
 {
     AuthenticationResponseGrant = new AuthenticationResponseGrant(identity, extra);
 }
Пример #18
0
        private async Task <RequestToken> ObtainRequestToken(string consumerKey, string consumerSecret, string callBackUri, AuthenticationExtra extra)
        {
            _logger.WriteVerbose("ObtainRequestToken");

            var obtainRequestTokenRequest = CreateTwitterWebRequest(RequestTokenEndpoint);

            var nonce = Guid.NewGuid().ToString("N");

            var authorizationParts = new SortedDictionary <string, string>
            {
                { "oauth_callback", callBackUri },
                { "oauth_consumer_key", consumerKey },
                { "oauth_nonce", nonce },
                { "oauth_signature_method", "HMAC-SHA1" },
                { "oauth_timestamp", GenerateTimeStamp() },
                { "oauth_version", "1.0" }
            };

            var parameterBuilder = new StringBuilder();

            foreach (var authorizationKey in authorizationParts)
            {
                parameterBuilder.AppendFormat("{0}={1}&", Uri.EscapeDataString(authorizationKey.Key), Uri.EscapeDataString(authorizationKey.Value));
            }
            parameterBuilder.Length--;
            var parameterString = parameterBuilder.ToString();

            var canonicalizedRequestBuilder = new StringBuilder();

            canonicalizedRequestBuilder.Append(obtainRequestTokenRequest.Method);
            canonicalizedRequestBuilder.Append("&");
            canonicalizedRequestBuilder.Append(Uri.EscapeDataString(obtainRequestTokenRequest.RequestUri.ToString()));
            canonicalizedRequestBuilder.Append("&");
            canonicalizedRequestBuilder.Append(Uri.EscapeDataString(parameterString));

            var signature = ComputeSignature(consumerSecret, null, canonicalizedRequestBuilder.ToString());

            authorizationParts.Add("oauth_signature", signature);

            var authorizationHeaderBuilder = new StringBuilder();

            authorizationHeaderBuilder.Append("OAuth ");
            foreach (var authorizationPart in authorizationParts)
            {
                authorizationHeaderBuilder.AppendFormat(
                    "{0}=\"{1}\", ", authorizationPart.Key, Uri.EscapeDataString(authorizationPart.Value));
            }
            authorizationHeaderBuilder.Length = authorizationHeaderBuilder.Length - 2;

            obtainRequestTokenRequest.Headers.Add("Authorization", authorizationHeaderBuilder.ToString());

            // TODO : Error handling
            var obtainRequestTokenResponse = await obtainRequestTokenRequest.GetResponseAsync() as HttpWebResponse;

            using (var reader = new StreamReader(obtainRequestTokenResponse.GetResponseStream()))
            {
                string responseText = await reader.ReadToEndAsync();

                responseText = responseText.Replace('+', ' ');
                var responseParameters = responseText.Split('&').Select(responseParameter => responseParameter.Split('=')).ToDictionary(brokenParameter => brokenParameter[0], brokenParameter => brokenParameter[1]);

                if (responseParameters.ContainsKey("oauth_callback_confirmed") ||
                    string.Equals(responseParameters["oauth_callback_confirmed"], "true", StringComparison.InvariantCulture))
                {
                    return(new RequestToken {
                        Token = Uri.UnescapeDataString(responseParameters["oauth_token"]), TokenSecret = Uri.UnescapeDataString(responseParameters["oauth_token_secret"]), CallbackConfirmed = true, Extra = extra
                    });
                }
            }

            return(new RequestToken());
        }
Пример #19
0
        protected override async Task <AuthenticationTicket> AuthenticateCore()
        {
            _logger.WriteVerbose("AuthenticateCore");

            AuthenticationExtra extra = null;

            try
            {
                IDictionary <string, string[]> query = Request.GetQuery();
                var protectedRequestToken            = Request.GetCookies()[StateCookie];

                var requestToken = _tokenProtectionHandler.Unprotect(protectedRequestToken);

                if (requestToken == null)
                {
                    _logger.WriteWarning("Invalid state", null);
                    return(null);
                }

                extra = requestToken.Extra;

                if (!query.ContainsKey("oauth_token"))
                {
                    _logger.WriteWarning("Missing oauth_token", null);
                    return(new AuthenticationTicket(null, extra));
                }

                if (!query.ContainsKey("oauth_verifier"))
                {
                    _logger.WriteWarning("Missing oauth_verifier", null);
                    return(new AuthenticationTicket(null, extra));
                }

                var    returnedToken = query["oauth_token"].FirstOrDefault();
                string oauthVerifier = query["oauth_verifier"].FirstOrDefault();

                if (returnedToken != requestToken.Token)
                {
                    _logger.WriteWarning("Unmatched token", null);
                    return(new AuthenticationTicket(null, extra));
                }

                if (string.IsNullOrWhiteSpace(oauthVerifier))
                {
                    _logger.WriteWarning("Blank oauth_verifier", null);
                    return(new AuthenticationTicket(null, extra));
                }

                var accessToken = await ObtainAccessToken(Options.ConsumerKey, Options.ConsumerSecret, requestToken, oauthVerifier);

                var context = new TwitterAuthenticatedContext(Request.Environment, accessToken.UserId, accessToken.ScreenName);
                context.Identity = new ClaimsIdentity(
                    new[]
                {
                    new Claim(ClaimTypes.NameIdentifier, accessToken.UserId, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationType),
                    new Claim(ClaimTypes.Name, accessToken.ScreenName, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationType),
                    new Claim("urn:twitter:userid", accessToken.UserId, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationType),
                    new Claim("urn:twitter:screenname", accessToken.ScreenName, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationType),
                },
                    Options.AuthenticationType,
                    ClaimsIdentity.DefaultNameClaimType,
                    ClaimsIdentity.DefaultRoleClaimType);
                context.Extra = requestToken.Extra;

                Response.DeleteCookie(StateCookie);

                await Options.Provider.Authenticated(context);

                return(new AuthenticationTicket(context.Identity, context.Extra));
            }
            catch (Exception ex)
            {
                _logger.WriteError("Authentication failed", ex);
                return(new AuthenticationTicket(null, extra));
            }
        }
        protected override async Task <AuthenticationTicket> AuthenticateCore()
        {
            _logger.WriteVerbose("AuthenticateCore");

            AuthenticationExtra extra = null;

            try
            {
                string code  = null;
                string state = null;

                IDictionary <string, string[]> query = Request.GetQuery();
                string[] values;
                if (query.TryGetValue("code", out values) && values != null && values.Length == 1)
                {
                    code = values[0];
                }
                if (query.TryGetValue("state", out values) && values != null && values.Length == 1)
                {
                    state = values[0];
                }

                extra = Options.StateDataHandler.Unprotect(state);
                if (extra == null)
                {
                    return(null);
                }

                // OAuth2 10.12 CSRF
                if (!ValidateCorrelationId(extra, _logger))
                {
                    return(new AuthenticationTicket(null, extra));
                }

                var tokenRequestParameters = string.Format(
                    CultureInfo.InvariantCulture,
                    "client_id={0}&redirect_uri={1}&client_secret={2}&code={3}&grant_type=authorization_code",
                    Uri.EscapeDataString(Options.ClientId),
                    Uri.EscapeDataString(GenerateRedirectUri()),
                    Uri.EscapeDataString(Options.ClientSecret),
                    code);

                WebRequest tokenRequest = WebRequest.Create(TokenEndpoint);
                tokenRequest.Method        = "POST";
                tokenRequest.ContentType   = "application/x-www-form-urlencoded";
                tokenRequest.ContentLength = tokenRequestParameters.Length;
                tokenRequest.Timeout       = Options.BackChannelRequestTimeOut;
                using (var bodyStream = new StreamWriter(tokenRequest.GetRequestStream()))
                {
                    bodyStream.Write(tokenRequestParameters);
                }

                WebResponse tokenResponse = await tokenRequest.GetResponseAsync();

                string accessToken = null;

                using (var reader = new StreamReader(tokenResponse.GetResponseStream()))
                {
                    string oauthTokenResponse = await reader.ReadToEndAsync();

                    JObject oauth2Token = JObject.Parse(oauthTokenResponse);
                    accessToken = oauth2Token["access_token"].Value <string>();
                }

                if (string.IsNullOrWhiteSpace(accessToken))
                {
                    _logger.WriteWarning("Access token was not found");
                    return(new AuthenticationTicket(null, extra));
                }

                JObject accountInformation;
                var     accountInformationRequest = WebRequest.Create(GraphApiEndpoint + "?access_token=" + Uri.EscapeDataString(accessToken));
                accountInformationRequest.Timeout = Options.BackChannelRequestTimeOut;
                var accountInformationResponse = await accountInformationRequest.GetResponseAsync();

                using (var reader = new StreamReader(accountInformationResponse.GetResponseStream()))
                {
                    accountInformation = JObject.Parse(await reader.ReadToEndAsync());
                }

                var context = new MicrosoftAccountAuthenticatedContext(Request.Environment, accountInformation, accessToken);
                context.Identity = new ClaimsIdentity(
                    new[]
                {
                    new Claim(ClaimTypes.NameIdentifier, context.Id, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationType),
                    new Claim(ClaimTypes.Name, context.Name, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationType),
                    new Claim("urn:microsoftaccount:id", context.Id, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationType),
                    new Claim("urn:microsoftaccount:name", context.Name, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationType),
                },
                    Options.AuthenticationType,
                    ClaimsIdentity.DefaultNameClaimType,
                    ClaimsIdentity.DefaultRoleClaimType);
                if (!string.IsNullOrWhiteSpace(context.Email))
                {
                    context.Identity.AddClaim(new Claim(ClaimTypes.Email, context.Email, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationType));
                }

                await Options.Provider.Authenticated(context);

                context.Extra = extra;

                return(new AuthenticationTicket(context.Identity, context.Extra));
            }
            catch (Exception ex)
            {
                _logger.WriteWarning("Authentication failed", ex);
                return(new AuthenticationTicket(null, extra));
            }
        }
Пример #21
0
        protected override async Task <AuthenticationTicket> AuthenticateCore()
        {
            _logger.WriteVerbose("AuthenticateCore");

            AuthenticationExtra extra = null;

            try
            {
                string code  = null;
                string state = null;

                IDictionary <string, string[]> query = Request.GetQuery();
                string[] values;
                if (query.TryGetValue("code", out values) && values != null && values.Length == 1)
                {
                    code = values[0];
                }
                if (query.TryGetValue("state", out values) && values != null && values.Length == 1)
                {
                    state = values[0];
                }

                extra = Options.StateDataHandler.Unprotect(state);
                if (extra == null)
                {
                    return(null);
                }

                // OAuth2 10.12 CSRF
                if (!ValidateCorrelationId(extra, _logger))
                {
                    return(new AuthenticationTicket(null, extra));
                }

                string tokenEndpoint =
                    "https://graph.facebook.com/oauth/access_token";

                string requestPrefix = Request.Scheme + "://" + Request.Host;
                string redirectUri   = requestPrefix + Request.PathBase + Options.ReturnEndpointPath;

                string tokenRequest = "grant_type=authorization_code" +
                                      "&code=" + Uri.EscapeDataString(code) +
                                      "&redirect_uri=" + Uri.EscapeDataString(redirectUri) +
                                      "&client_id=" + Uri.EscapeDataString(Options.AppId) +
                                      "&client_secret=" + Uri.EscapeDataString(Options.AppSecret);

                WebRequest  webRequest  = WebRequest.Create(tokenEndpoint + "?" + tokenRequest);
                WebResponse webResponse = await webRequest.GetResponseAsync();

                NameValueCollection form;
                using (var reader = new StreamReader(webResponse.GetResponseStream()))
                {
                    string text = await reader.ReadToEndAsync();

                    form = WebHelpers.ParseNameValueCollection(text);
                }

                string accessToken = form["access_token"];
                string expires     = form["expires"];

                string graphApiEndpoint =
                    "https://graph.facebook.com/me";

                webRequest  = WebRequest.Create(graphApiEndpoint + "?access_token=" + Uri.EscapeDataString(accessToken));
                webResponse = await webRequest.GetResponseAsync();

                JObject user;
                using (var reader = new StreamReader(webResponse.GetResponseStream()))
                {
                    user = JObject.Parse(await reader.ReadToEndAsync());
                }

                var context = new FacebookAuthenticatedContext(Request.Environment, user, accessToken);
                context.Identity = new ClaimsIdentity(
                    Options.AuthenticationType,
                    ClaimsIdentity.DefaultNameClaimType,
                    ClaimsIdentity.DefaultRoleClaimType);
                if (!string.IsNullOrEmpty(context.Id))
                {
                    context.Identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, context.Id, XmlSchemaString, Options.AuthenticationType));
                }
                if (!string.IsNullOrEmpty(context.Username))
                {
                    context.Identity.AddClaim(new Claim(ClaimsIdentity.DefaultNameClaimType, context.Username, XmlSchemaString, Options.AuthenticationType));
                }
                if (!string.IsNullOrEmpty(context.Email))
                {
                    context.Identity.AddClaim(new Claim(ClaimTypes.Email, context.Email, XmlSchemaString, Options.AuthenticationType));
                }
                if (!string.IsNullOrEmpty(context.Name))
                {
                    context.Identity.AddClaim(new Claim("urn:facebook:name", context.Name, XmlSchemaString, Options.AuthenticationType));
                }
                if (!string.IsNullOrEmpty(context.Link))
                {
                    context.Identity.AddClaim(new Claim("urn:facebook:link", context.Link, XmlSchemaString, Options.AuthenticationType));
                }
                context.Extra = extra;

                await Options.Provider.Authenticated(context);

                return(new AuthenticationTicket(context.Identity, context.Extra));
            }
            catch (Exception ex)
            {
                _logger.WriteError(ex.Message);
            }
            return(new AuthenticationTicket(null, extra));
        }
Пример #22
0
 public void Issue(ClaimsIdentity identity, AuthenticationExtra extra)
 {
     Identity    = identity;
     Extra       = extra;
     TokenIssued = true;
 }
Пример #23
0
        protected override async Task <AuthenticationTicket> AuthenticateCore()
        {
            _logger.WriteVerbose("AuthenticateCore");

            AuthenticationExtra extra = null;

            try
            {
                IDictionary <string, string[]> query = Request.GetQuery();

                extra = UnpackStateParameter(query);
                if (extra == null)
                {
                    _logger.WriteWarning("Invalid return state", null);
                    return(null);
                }

                // Anti-CSRF
                if (!ValidateCorrelationId(extra, _logger))
                {
                    return(new AuthenticationTicket(null, extra));
                }

                var message = await ParseRequestMessage(query);

                bool messageValidated = false;

                Property mode;
                if (!message.Properties.TryGetValue("mode.http://specs.openid.net/auth/2.0", out mode))
                {
                    _logger.WriteWarning("Missing mode parameter", null);
                    return(new AuthenticationTicket(null, extra));
                }

                if (string.Equals("cancel", mode.Value, StringComparison.Ordinal))
                {
                    _logger.WriteWarning("User cancelled signin request", null);
                    return(new AuthenticationTicket(null, extra));
                }

                if (string.Equals("id_res", mode.Value, StringComparison.Ordinal))
                {
                    mode.Value = "check_authentication";

                    WebRequest verifyRequest = WebRequest.Create("https://www.google.com/accounts/o8/ud");
                    verifyRequest.Method      = "POST";
                    verifyRequest.ContentType = "application/x-www-form-urlencoded";
                    using (var writer = new StreamWriter(await verifyRequest.GetRequestStreamAsync()))
                    {
                        string body = message.ToFormUrlEncoded();
                        await writer.WriteAsync(body);
                    }
                    WebResponse verifyResponse = await verifyRequest.GetResponseAsync();

                    using (var reader = new StreamReader(verifyResponse.GetResponseStream()))
                    {
                        var    verifyBody = new Dictionary <string, string[]>();
                        string body       = await reader.ReadToEndAsync();

                        foreach (var line in body.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries))
                        {
                            int delimiter = line.IndexOf(':');
                            if (delimiter != -1)
                            {
                                verifyBody.Add("openid." + line.Substring(0, delimiter), new[] { line.Substring(delimiter + 1) });
                            }
                        }
                        var      verifyMessage = new Message(verifyBody, strict: false);
                        Property isValid;
                        if (verifyMessage.Properties.TryGetValue("is_valid.http://specs.openid.net/auth/2.0", out isValid))
                        {
                            if (string.Equals("true", isValid.Value, StringComparison.Ordinal))
                            {
                                messageValidated = true;
                            }
                            else
                            {
                                messageValidated = false;
                            }
                        }
                    }
                }

                // http://openid.net/specs/openid-authentication-2_0.html#verify_return_to
                // To verify that the "openid.return_to" URL matches the URL that is processing this assertion:
                // * The URL scheme, authority, and path MUST be the same between the two URLs.
                // * Any query parameters that are present in the "openid.return_to" URL MUST also
                //   be present with the same values in the URL of the HTTP request the RP received.
                if (messageValidated)
                {
                    // locate the required return_to parameter
                    string actualReturnTo;
                    if (!message.TryGetValue("return_to.http://specs.openid.net/auth/2.0", out actualReturnTo))
                    {
                        _logger.WriteWarning("openid.return_to parameter missing at return address");
                        messageValidated = false;
                    }
                    else
                    {
                        // create the expected return_to parameter based on the URL that is processing
                        // the assertion, plus exactly and only the the query string parameter (state)
                        // that this RP must have received
                        string expectedReturnTo = BuildReturnTo(GetStateParameter(query));

                        if (!string.Equals(actualReturnTo, expectedReturnTo, StringComparison.Ordinal))
                        {
                            _logger.WriteWarning("openid.return_to parameter not equal to expected value based on return address");
                            messageValidated = false;
                        }
                    }
                }

                if (messageValidated)
                {
                    IDictionary <string, string> attributeExchangeProperties = new Dictionary <string, string>();
                    foreach (var typeProperty in message.Properties.Values)
                    {
                        if (typeProperty.Namespace == "http://openid.net/srv/ax/1.0" &&
                            typeProperty.Name.StartsWith("type."))
                        {
                            string   qname = "value." + typeProperty.Name.Substring("type.".Length) + "http://openid.net/srv/ax/1.0";
                            Property valueProperty;
                            if (message.Properties.TryGetValue(qname, out valueProperty))
                            {
                                attributeExchangeProperties.Add(typeProperty.Value, valueProperty.Value);
                            }
                        }
                    }

                    var responseNamespaces = new object[]
                    {
                        new XAttribute(XNamespace.Xmlns + "openid", "http://specs.openid.net/auth/2.0"),
                        new XAttribute(XNamespace.Xmlns + "openid.ax", "http://openid.net/srv/ax/1.0")
                    };

                    IEnumerable <object> responseProperties = message.Properties
                                                              .Where(p => p.Value.Namespace != null)
                                                              .Select(p => (object)new XElement(XName.Get(p.Value.Name.Substring(0, p.Value.Name.Length - 1), p.Value.Namespace), p.Value.Value));

                    var responseMessage = new XElement("response", responseNamespaces.Concat(responseProperties).ToArray());

                    var      identity  = new ClaimsIdentity(Options.AuthenticationType);
                    XElement claimedId = responseMessage.Element(XName.Get("claimed_id", "http://specs.openid.net/auth/2.0"));
                    if (claimedId != null)
                    {
                        identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, claimedId.Value, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationType));
                    }

                    string firstValue;
                    if (attributeExchangeProperties.TryGetValue("http://axschema.org/namePerson/first", out firstValue))
                    {
                        identity.AddClaim(new Claim(ClaimTypes.GivenName, firstValue, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationType));
                    }
                    string lastValue;
                    if (attributeExchangeProperties.TryGetValue("http://axschema.org/namePerson/last", out lastValue))
                    {
                        identity.AddClaim(new Claim(ClaimTypes.Surname, lastValue, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationType));
                    }
                    string nameValue;
                    if (attributeExchangeProperties.TryGetValue("http://axschema.org/namePerson", out nameValue))
                    {
                        identity.AddClaim(new Claim(ClaimTypes.Name, nameValue, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationType));
                    }
                    else if (!string.IsNullOrEmpty(firstValue) && !string.IsNullOrEmpty(lastValue))
                    {
                        identity.AddClaim(new Claim(ClaimTypes.Name, firstValue + " " + lastValue, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationType));
                    }
                    else if (!string.IsNullOrEmpty(firstValue))
                    {
                        identity.AddClaim(new Claim(ClaimTypes.Name, firstValue, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationType));
                    }
                    else if (!string.IsNullOrEmpty(lastValue))
                    {
                        identity.AddClaim(new Claim(ClaimTypes.Name, lastValue, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationType));
                    }
                    string emailValue;
                    if (attributeExchangeProperties.TryGetValue("http://axschema.org/contact/email", out emailValue))
                    {
                        identity.AddClaim(new Claim(ClaimTypes.Email, emailValue, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationType));
                    }

                    var context = new GoogleAuthenticatedContext(
                        Request.Environment,
                        identity,
                        extra,
                        responseMessage,
                        attributeExchangeProperties);

                    await Options.Provider.Authenticated(context);

                    return(new AuthenticationTicket(context.Identity, context.Extra));
                }

                return(new AuthenticationTicket(null, extra));
            }
            catch (Exception ex)
            {
                _logger.WriteError("Authentication failed", ex);
                return(new AuthenticationTicket(null, extra));
            }
        }
Пример #24
0
        /// <summary></summary>
        /// <param name="context"></param>
        /// <param name="authenticationTypes"></param>
        /// <param name="extra"></param>
        public static void Challenge(this HttpContextBase context, string[] authenticationTypes, AuthenticationExtra extra)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }
            if (extra == null)
            {
                throw new ArgumentNullException("extra");
            }

            OwinResponse response = GetOwinResponse(context);

            response.Challenge(authenticationTypes, extra);
        }
Пример #25
0
        protected void GenerateCorrelationId(AuthenticationExtra extra)
        {
            var correlationKey = Constants.CorrelationPrefix + BaseOptions.AuthenticationType;

            var nonceBytes = new byte[32];
            Random.GetBytes(nonceBytes);
            var correlationId = TextEncodings.Base64Url.Encode(nonceBytes);

            var cookieOptions = new CookieOptions
            {
                HttpOnly = true,
                Secure = Request.IsSecure
            };

            extra.Properties[correlationKey] = correlationId;

            Response.AddCookie(correlationKey, correlationId, cookieOptions);
        }
Пример #26
0
        protected override async Task <AuthenticationTicket> AuthenticateCore()
        {
            Logger.WriteVerbose("AuthenticateCore");
            AuthenticationExtra extra = null;

            try
            {
                var      query = this.Request.GetQuery();
                string[] lookup;
                string   code  = null;
                string   state = null;

                if (query.TryGetValue("code", out lookup) &&
                    lookup != null &&
                    lookup.Length == 1)
                {
                    code = lookup[0];
                }

                if (code == null)
                {
                    return(null);
                }

                if (query.TryGetValue("state", out lookup) &&
                    lookup != null &&
                    lookup.Length == 1)
                {
                    state = lookup[0];
                }

                extra = Options.StateDataHandler.Unprotect(state);

                if (extra == null)
                {
                    return(null);
                }

                if (ValidateCorrelationId(extra, Logger))
                {
                    var accessToken = await GetAccessToken(code);

                    if (accessToken != null)
                    {
                        var userInfo = await GetUserInfo(accessToken);

                        var authenticatedContext = new OAuth2AuthenticatedContext(
                            accessToken,
                            userInfo.UserId,
                            userInfo.UserName,
                            Request.Environment)
                        {
                            Identity = new ClaimsIdentity(
                                Options.AuthenticationType,
                                "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name",
                                "http://schemas.microsoft.com/ws/2008/06/identity/claims/role"),
                            Extra = extra
                        };

                        if (!string.IsNullOrWhiteSpace(authenticatedContext.UserId))
                        {
                            authenticatedContext.Identity.AddClaim(
                                new Claim(
                                    "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier",
                                    authenticatedContext.UserId,
                                    "http://www.w3.org/2001/XMLSchema#string",
                                    Options.AuthenticationType));
                        }

                        if (!string.IsNullOrWhiteSpace(authenticatedContext.UserName))
                        {
                            authenticatedContext.Identity.AddClaim(
                                new Claim(
                                    "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name",
                                    authenticatedContext.UserName,
                                    "http://www.w3.org/2001/XMLSchema#string",
                                    Options.AuthenticationType));
                        }

                        await Options.Provider.Authenticated(authenticatedContext);

                        return(new AuthenticationTicket(
                                   authenticatedContext.Identity,
                                   authenticatedContext.Extra));
                    }
                }
            }
            catch (Exception e)
            {
                Logger.WriteError(e.Message);
            }

            return(new AuthenticationTicket(null, extra));
        }
Пример #27
0
 public void Issue(ClaimsIdentity identity, AuthenticationExtra extra)
 {
     Identity = identity;
     Extra = extra;
     TokenIssued = true;
 }
Пример #28
0
        public static void SignIn(this IAuthenticationManager authenticationManager, ClaimsIdentity identity)
        {
            var extra = new AuthenticationExtra();

            authenticationManager.SignIn(extra, identity);
        }
Пример #29
0
 public void Grant(ClaimsPrincipal principal, AuthenticationExtra extra)
 {
     AuthenticationResponseGrant = new AuthenticationResponseGrant(principal, extra);
 }
Пример #30
0
        protected bool ValidateCorrelationId(AuthenticationExtra extra, ILogger logger)
        {
            var correlationKey = Constants.CorrelationPrefix + BaseOptions.AuthenticationType;

            string correlationCookie;
            if (!Request.GetCookies().TryGetValue(
                correlationKey,
                out correlationCookie))
            {
                logger.WriteWarning(string.Format("{0} cookie not found", correlationKey));
                return false;
            }

            Response.DeleteCookie(correlationKey);

            string correlationExtra;
            if (!extra.Properties.TryGetValue(
                correlationKey,
                out correlationExtra))
            {
                logger.WriteWarning(string.Format("{0} state property not found", correlationKey));
                return false;
            }

            extra.Properties.Remove(correlationKey);

            if (!string.Equals(correlationCookie, correlationExtra, StringComparison.Ordinal))
            {
                logger.WriteWarning(string.Format("{0} correlation cookie and state property mismatch", correlationKey));
                return false;
            }

            return true;
        }
Пример #31
0
 public void Challenge(string[] authenticationTypes, AuthenticationExtra extra)
 {
     StatusCode = 401;
     AuthenticationResponseChallenge = new AuthenticationResponseChallenge(authenticationTypes, extra);
 }