From 1bfbe6fc59114004c74ea92c7b6a75a1518c631a Mon Sep 17 00:00:00 2001 From: Tim Stone Date: Sun, 23 Aug 2015 16:52:49 -0400 Subject: [PATCH 1/5] Rename UserOpenIds to the more-generic UserAuthClaims --- .../Models/TestUser.cs | 4 +-- .../Controllers/AccountController.cs | 12 +++---- .../Controllers/AdminController.cs | 20 +++++------ App/StackExchange.DataExplorer/Models/User.cs | 12 +++---- .../{UserOpenId.cs => UserAuthClaim.cs} | 35 +++++++++++-------- .../Models/_Database.Specific.cs | 2 +- .../StackExchange.DataExplorer.csproj | 2 +- .../Views/User/Show.cshtml | 4 +-- Migrations/055 - Make UserOpenIds generic.sql | 33 +++++++++++++++++ 9 files changed, 82 insertions(+), 42 deletions(-) rename App/StackExchange.DataExplorer/Models/{UserOpenId.cs => UserAuthClaim.cs} (54%) create mode 100644 Migrations/055 - Make UserOpenIds generic.sql diff --git a/App/StackExchange.DataExplorer.Tests/Models/TestUser.cs b/App/StackExchange.DataExplorer.Tests/Models/TestUser.cs index 3561e35f..56a90a80 100644 --- a/App/StackExchange.DataExplorer.Tests/Models/TestUser.cs +++ b/App/StackExchange.DataExplorer.Tests/Models/TestUser.cs @@ -27,8 +27,8 @@ public void TestBasicUserCreation() { var u2 = Current.DB.Query("select * from Users where Login = @Login", new {Login = "Fred"}).First(); Assert.AreEqual("Fred", u2.Login); - var o = Current.DB.Query("select * from UserOpenIds where OpenIdClaim = @claim", new {claim = "xyz"}).FirstOrDefault(); - Assert.AreEqual("xyz", o.OpenIdClaim); + var o = Current.DB.Query("select * from UserAuthClaims where ClaimIdentifier = @claim", new {claim = "xyz"}).FirstOrDefault(); + Assert.AreEqual("xyz", o.ClaimIdentifier); } [TestMethod] diff --git a/App/StackExchange.DataExplorer/Controllers/AccountController.cs b/App/StackExchange.DataExplorer/Controllers/AccountController.cs index 87011e2a..ff584c00 100644 --- a/App/StackExchange.DataExplorer/Controllers/AccountController.cs +++ b/App/StackExchange.DataExplorer/Controllers/AccountController.cs @@ -151,7 +151,7 @@ public ActionResult Authenticate(string returnUrl) return whiteListResponse; User user = null; - var openId = Current.DB.Query("SELECT * FROM UserOpenIds WHERE OpenIdClaim = @normalizedClaim", new { normalizedClaim }).FirstOrDefault(); + var openId = Current.DB.Query("SELECT * FROM UserAuthClaims WHERE ClaimIdentifier = @normalizedClaim", new { normalizedClaim }).FirstOrDefault(); if (!CurrentUser.IsAnonymous) { @@ -162,14 +162,14 @@ public ActionResult Authenticate(string returnUrl) return LoginError("Another user with this OpenID already exists, merging is not possible at this time."); } - var currentOpenIds = Current.DB.Query("select * from UserOpenIds where UserId = @Id", new {CurrentUser.Id}); + var currentOpenIds = Current.DB.Query("select * from UserAuthClaims where UserId = @Id", new {CurrentUser.Id}); // If a user is merged and then tries to add one of the OpenIDs used for the two original users, // this update will fail...so don't attempt it if we detect that's the case. Really we should // work on allowing multiple OpenID logins, but for now I'll settle for not throwing an exception... - if (!currentOpenIds.Any(s => s.OpenIdClaim == normalizedClaim)) + if (!currentOpenIds.Any(s => s.ClaimIdentifier == normalizedClaim)) { - Current.DB.UserOpenIds.Update(currentOpenIds.First().Id, new { OpenIdClaim = normalizedClaim }); + Current.DB.UserAuthClaims.Update(currentOpenIds.First().Id, new { ClaimIdentifier = normalizedClaim }); } user = CurrentUser; @@ -186,7 +186,7 @@ public ActionResult Authenticate(string returnUrl) if (user != null) { - Current.DB.UserOpenIds.Insert(new { UserId = user.Id, OpenIdClaim = normalizedClaim, isSecure }); + Current.DB.UserAuthClaims.Insert(new { UserId = user.Id, ClaimIdentifier = normalizedClaim, isSecure }); } } @@ -213,7 +213,7 @@ public ActionResult Authenticate(string returnUrl) } else if (isSecure && !openId.IsSecure) { - Current.DB.UserOpenIds.Update(openId.Id, new { IsSecure = true }); + Current.DB.UserAuthClaims.Update(openId.Id, new { IsSecure = true }); } } diff --git a/App/StackExchange.DataExplorer/Controllers/AdminController.cs b/App/StackExchange.DataExplorer/Controllers/AdminController.cs index cb9f69e3..e1827483 100644 --- a/App/StackExchange.DataExplorer/Controllers/AdminController.cs +++ b/App/StackExchange.DataExplorer/Controllers/AdminController.cs @@ -137,9 +137,9 @@ where grp.Count() > 1 } else { - var openids = Current.DB.Query("select * from UserOpenIds").ToList(); + var openids = Current.DB.UserAuthClaims.All(); dupeUserIds = (from openid in openids - group openid by Models.User.NormalizeOpenId(openid.OpenIdClaim) + group openid by Models.User.NormalizeOpenId(openid.ClaimIdentifier) into grp where grp.Count() > 1 select new Tuple>(grp.Key, grp.Select(id => id.UserId).OrderBy(id => id))).ToList(); @@ -169,12 +169,12 @@ where grp.Count() > 1 [StackRoute("admin/normalize-openids")] public ActionResult NormalizeOpenIds() { - foreach (var openId in Current.DB.UserOpenIds.All()) + foreach (var openId in Current.DB.UserAuthClaims.All()) { - var cleanClaim = Models.User.NormalizeOpenId(openId.OpenIdClaim); - if (cleanClaim != openId.OpenIdClaim) + var cleanClaim = Models.User.NormalizeOpenId(openId.ClaimIdentifier); + if (cleanClaim != openId.ClaimIdentifier) { - Current.DB.UserOpenIds.Update(openId.Id, new { OpenIdClaim = cleanClaim }); + Current.DB.UserAuthClaims.Update(openId.Id, new { ClaimIdentifier = cleanClaim }); } } return TextPlain("Done."); @@ -239,12 +239,12 @@ public ActionResult MergeSubmit(int masterId, int mergeId) public ActionResult FindDuplicateUserOpenIds() { - var sql = "select * from UserOpenIds where UserId in (select UserId from UserOpenId having count(*) > 0)"; + var sql = "select * from UserAuthClaims where UserId in (select UserId from UserAuthClaims having count(*) > 0)"; - var dupes = (from uoi in Current.DB.Query(sql) + var dupes = (from uoi in Current.DB.Query(sql) group uoi by uoi.UserId into grp - select new Tuple>(grp.Key, grp.Select(g=>g))).ToList(); + select new Tuple>(grp.Key, grp.Select(g=>g))).ToList(); SetHeader("Possible Duplicate User OpenId records"); return View(dupes); } @@ -253,7 +253,7 @@ into grp [StackRoute("admin/useropenid/remove/{id:int}", HttpVerbs.Post)] public ActionResult RemoveUserOpenIdEntry(int id) { - Current.DB.UserOpenIds.Delete(id); + Current.DB.UserAuthClaims.Delete(id); return Json("ok"); } diff --git a/App/StackExchange.DataExplorer/Models/User.cs b/App/StackExchange.DataExplorer/Models/User.cs index 317a1082..8f5d224a 100644 --- a/App/StackExchange.DataExplorer/Models/User.cs +++ b/App/StackExchange.DataExplorer/Models/User.cs @@ -25,13 +25,13 @@ public partial class User public string PreferencesRaw { get; set; } public string ADLogin { get; set; } - List _userOpenIds; - public List UserOpenIds + List _userAuthClaims; + public List UserAuthClaims { get { - _userOpenIds = _userOpenIds ?? Current.DB.Query("select * from UserOpenIds where UserId = @Id", new { Id }).ToList(); - return _userOpenIds; + _userAuthClaims = _userAuthClaims ?? Current.DB.Query("select * from UserAuthClaims where UserId = @Id", new { Id }).ToList(); + return _userAuthClaims; } } @@ -156,7 +156,7 @@ public static User CreateUser(string login, string email, string openIdClaim) u.Id = Current.DB.Users.Insert(new { u.Email, u.Login, u.CreationDate }).Value; if (openIdClaim != null) - Current.DB.UserOpenIds.Insert(new {OpenIdClaim = openIdClaim, UserId = u.Id}); + Current.DB.UserAuthClaims.Insert(new { ClaimIdentifier = openIdClaim, UserId = u.Id}); return u; } @@ -242,7 +242,7 @@ from RevisionExecutions r // User Open Ids { - var rempped = db.Execute("update UserOpenIds set UserId = @masterId where UserId = @mergeId", new { mergeId, masterId }); + var rempped = db.Execute("update UserAuthClaims set UserId = @masterId where UserId = @mergeId", new { mergeId, masterId }); log.AppendLine(string.Format("Remapped {0} user open ids", rempped)); } diff --git a/App/StackExchange.DataExplorer/Models/UserOpenId.cs b/App/StackExchange.DataExplorer/Models/UserAuthClaim.cs similarity index 54% rename from App/StackExchange.DataExplorer/Models/UserOpenId.cs rename to App/StackExchange.DataExplorer/Models/UserAuthClaim.cs index 5a711529..c7922fc5 100644 --- a/App/StackExchange.DataExplorer/Models/UserOpenId.cs +++ b/App/StackExchange.DataExplorer/Models/UserAuthClaim.cs @@ -1,15 +1,22 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Web; - -namespace StackExchange.DataExplorer.Models -{ - public class UserOpenId - { - public int Id { get; set; } - public int UserId { get; set; } - public string OpenIdClaim { get; set; } - public bool IsSecure { get; set; } - } +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; + +namespace StackExchange.DataExplorer.Models +{ + public class UserAuthClaim + { + public enum ClaimType + { + OpenID = 1, + Google = 2 + } + + public int Id { get; set; } + public int UserId { get; set; } + public string ClaimIdentifier { get; set; } + public bool IsSecure { get; set; } + public ClaimType Type { get; set; } + } } \ No newline at end of file diff --git a/App/StackExchange.DataExplorer/Models/_Database.Specific.cs b/App/StackExchange.DataExplorer/Models/_Database.Specific.cs index 02516fd2..e1a4e6ee 100644 --- a/App/StackExchange.DataExplorer/Models/_Database.Specific.cs +++ b/App/StackExchange.DataExplorer/Models/_Database.Specific.cs @@ -10,7 +10,7 @@ public class DataExplorerDatabase : Dapper.Database public Table Sites { get; private set; } public Table Users { get; private set; } public Table OpenIdWhiteList { get; private set; } - public Table UserOpenIds { get; private set; } + public Table UserAuthClaims { get; private set; } public Table Votes { get; private set; } public Table BlackList { get; private set; } public Table QuerySets { get; private set; } diff --git a/App/StackExchange.DataExplorer/StackExchange.DataExplorer.csproj b/App/StackExchange.DataExplorer/StackExchange.DataExplorer.csproj index d7747170..5e2d7e30 100644 --- a/App/StackExchange.DataExplorer/StackExchange.DataExplorer.csproj +++ b/App/StackExchange.DataExplorer/StackExchange.DataExplorer.csproj @@ -261,7 +261,7 @@ User.cs - + diff --git a/App/StackExchange.DataExplorer/Views/User/Show.cshtml b/App/StackExchange.DataExplorer/Views/User/Show.cshtml index 31c04677..9d232922 100644 --- a/App/StackExchange.DataExplorer/Views/User/Show.cshtml +++ b/App/StackExchange.DataExplorer/Views/User/Show.cshtml @@ -55,11 +55,11 @@ break; //case AppSettings.AuthenitcationMethod.Default: default: - if (Model.UserOpenIds.Any()) + if (Model.UserAuthClaims.Any()) { openid -
@Model.UserOpenIds[0].OpenIdClaim
+
@Model.UserAuthClaims[0].ClaimIdentifier
} else diff --git a/Migrations/055 - Make UserOpenIds generic.sql b/Migrations/055 - Make UserOpenIds generic.sql new file mode 100644 index 00000000..133191f2 --- /dev/null +++ b/Migrations/055 - Make UserOpenIds generic.sql @@ -0,0 +1,33 @@ +IF OBJECT_ID('UserAuthClaims') IS NULL +BEGIN + EXEC sp_rename 'UserOpenIds', 'UserAuthClaims' +END + +GO + +IF dbo.fnIndexExists('UserAuthClaims', 'OpenIdClaimIdx') = 1 +BEGIN + DROP INDEX OpenIdClaimIdx ON UserAuthClaims +END + +GO + +IF dbo.fnColumnExists('UserAuthClaims', 'OpenIdClaim') = 1 +BEGIN + EXEC sp_rename 'UserAuthClaims.OpenIdClaim', 'ClaimIdentifier', 'COLUMN' +END + +GO + +IF dbo.fnColumnExists('UserAuthClaims', 'IdentifierType') = 0 +BEGIN + ALTER TABLE UserAuthClaims ADD IdentifierType TINYINT NOT NULL DEFAULT 1 +END + +GO + +IF dbo.fnIndexExists('UserAuthClaims', 'ClaimIdentifierIdx') = 0 +BEGIN + ALTER TABLE UserAuthClaims ALTER COLUMN ClaimIdentifier NVARCHAR(449) NOT NULL + CREATE UNIQUE NONCLUSTERED INDEX ClaimIdentifierIdx ON UserAuthClaims(IdentifierType, ClaimIdentifier) +END \ No newline at end of file From 08ebe498857b2be46d46f6e5771de07715607ba3 Mon Sep 17 00:00:00 2001 From: Tim Stone Date: Mon, 24 Aug 2015 00:06:29 -0400 Subject: [PATCH 2/5] Unify login logic so Google OAuth checks agains UserAuthClaims, Users.Email is super unreliable --- .../Models/TestQueryExecutions.cs | 4 +- .../Models/TestUser.cs | 27 +--- .../Controllers/AccountController.cs | 123 ++++++------------ App/StackExchange.DataExplorer/Models/User.cs | 26 +++- 4 files changed, 69 insertions(+), 111 deletions(-) diff --git a/App/StackExchange.DataExplorer.Tests/Models/TestQueryExecutions.cs b/App/StackExchange.DataExplorer.Tests/Models/TestQueryExecutions.cs index 39348394..e607a925 100644 --- a/App/StackExchange.DataExplorer.Tests/Models/TestQueryExecutions.cs +++ b/App/StackExchange.DataExplorer.Tests/Models/TestQueryExecutions.cs @@ -15,7 +15,7 @@ public class TestQueryExecutions : BaseTest { public void TestBatchingBatch() { string sql = "print 1 \nGO\nprint 2"; var site = Current.DB.Sites.First(); - var user = User.CreateUser("Fred", "a@a.com", "xyzdsa"); + var user = User.CreateUser("Fred", "a@a.com"); var results = QueryRunner.ExecuteNonCached(new ParsedQuery(sql, null), site, user, null); Assert.AreEqual(0, results.ResultSets.Count()); @@ -27,7 +27,7 @@ public void TestBatchingBatch() { public void TestMultiResultSetsInStatement() { string sql = "select 1 select 2"; var site = Current.DB.Sites.First(); - var user = User.CreateUser("Fred", "a@a.com", "xyzdsa"); + var user = User.CreateUser("Fred", "a@a.com"); var results = QueryRunner.ExecuteNonCached(new ParsedQuery(sql, null), site, user, null); Assert.AreEqual(2, results.ResultSets.Count()); diff --git a/App/StackExchange.DataExplorer.Tests/Models/TestUser.cs b/App/StackExchange.DataExplorer.Tests/Models/TestUser.cs index 56a90a80..729f6401 100644 --- a/App/StackExchange.DataExplorer.Tests/Models/TestUser.cs +++ b/App/StackExchange.DataExplorer.Tests/Models/TestUser.cs @@ -12,32 +12,13 @@ namespace StackExchange.DataExplorer.Tests.Models { [TestClass] public class TestUser : BaseTest { - - [TestMethod] - public void TestUserCreationSetsCreationDate() { - var u = User.CreateUser("Fred", "a@a.com", "xyz"); - Assert.IsNotNull(u.CreationDate); - } - - [TestMethod] - public void TestBasicUserCreation() { - - User.CreateUser("Fred", "a@a.com", "xyz"); - - var u2 = Current.DB.Query("select * from Users where Login = @Login", new {Login = "Fred"}).First(); - Assert.AreEqual("Fred", u2.Login); - - var o = Current.DB.Query("select * from UserAuthClaims where ClaimIdentifier = @claim", new {claim = "xyz"}).FirstOrDefault(); - Assert.AreEqual("xyz", o.ClaimIdentifier); - } - [TestMethod] public void TestNoName() { Current.DB.Execute("delete from Users where Login like 'jon.doe%'"); - var u1 = User.CreateUser("", null, "xyz"); - var u2 = User.CreateUser(null, "", "xyz1"); + var u1 = User.CreateUser("", null); + var u2 = User.CreateUser(null, ""); Assert.AreEqual("jon.doe", u1.Login); // This behaviour is probably not what we want @@ -49,13 +30,13 @@ public void TestNoSpaces() { Current.DB.Execute("delete from Users where Login like 'jon.doe%'"); - var u1 = User.CreateUser("jon doe", null, "xyz"); + var u1 = User.CreateUser("jon doe", null); Assert.AreEqual("jon.doe", u1.Login); } [TestMethod] public void TestWeirdChars() { - var u1 = User.CreateUser("jon&*doe", null, "xyz"); + var u1 = User.CreateUser("jon&*doe", null); Assert.AreEqual(u1.Login, "jondoe"); } } diff --git a/App/StackExchange.DataExplorer/Controllers/AccountController.cs b/App/StackExchange.DataExplorer/Controllers/AccountController.cs index ff584c00..0cb1aefb 100644 --- a/App/StackExchange.DataExplorer/Controllers/AccountController.cs +++ b/App/StackExchange.DataExplorer/Controllers/AccountController.cs @@ -150,83 +150,8 @@ public ActionResult Authenticate(string returnUrl) if (whiteListResponse != null) return whiteListResponse; - User user = null; - var openId = Current.DB.Query("SELECT * FROM UserAuthClaims WHERE ClaimIdentifier = @normalizedClaim", new { normalizedClaim }).FirstOrDefault(); - - if (!CurrentUser.IsAnonymous) - { - if (openId != null && openId.UserId != CurrentUser.Id) //Does another user have this OpenID - { - //TODO: Need to perform a user merge - SetHeader("Log in below to change your OpenID"); - return LoginError("Another user with this OpenID already exists, merging is not possible at this time."); - } - - var currentOpenIds = Current.DB.Query("select * from UserAuthClaims where UserId = @Id", new {CurrentUser.Id}); - - // If a user is merged and then tries to add one of the OpenIDs used for the two original users, - // this update will fail...so don't attempt it if we detect that's the case. Really we should - // work on allowing multiple OpenID logins, but for now I'll settle for not throwing an exception... - if (!currentOpenIds.Any(s => s.ClaimIdentifier == normalizedClaim)) - { - Current.DB.UserAuthClaims.Update(currentOpenIds.First().Id, new { ClaimIdentifier = normalizedClaim }); - } - - user = CurrentUser; - returnUrl = "/users/" + user.Id; - } - else if (openId == null) - { - if (sreg != null && IsVerifiedEmailProvider(normalizedClaim)) - { - // Eh...We can trust the verified email provider, but we can't really trust Users.Email. - // I can't think of a particularly malicious way this could be exploited, but it's likely - // worth reviewing at some point. - user = Current.DB.Query("select * from Users where Email = @Email", new { sreg.Email }).FirstOrDefault(); - - if (user != null) - { - Current.DB.UserAuthClaims.Insert(new { UserId = user.Id, ClaimIdentifier = normalizedClaim, isSecure }); - } - } - - if (user == null) - { - // create new user - string email = ""; - string login = ""; - if (sreg != null) - { - email = sreg.Email; - login = sreg.Nickname ?? sreg.FullName; - } - user = Models.User.CreateUser(login, email, normalizedClaim); - } - } - else - { - user = Current.DB.Users.Get(openId.UserId); - - if (AppSettings.EnableEnforceSecureOpenId && user.EnforceSecureOpenId && !isSecure && openId.IsSecure) - { - return LoginError("User preferences prohibit insecure (non-https) variants of the provided OpenID identifier"); - } - else if (isSecure && !openId.IsSecure) - { - Current.DB.UserAuthClaims.Update(openId.Id, new { IsSecure = true }); - } - } - - IssueFormsTicket(user); - - if (!string.IsNullOrEmpty(returnUrl)) - { - return Redirect(returnUrl); - } - else - { - return RedirectToAction("Index", "Home"); - } + return LoginUser(whitelistEmail, normalizedClaim, sreg != null ? sreg.Nickname ?? sreg.FullName : null, returnUrl, + UserAuthClaim.ClaimType.OpenID, IsVerifiedEmailProvider(originalClaim), isSecure); case AuthenticationStatus.Canceled: return LoginError("Canceled at provider"); case AuthenticationStatus.Failed: @@ -236,18 +161,49 @@ public ActionResult Authenticate(string returnUrl) return new EmptyResult(); } - private ActionResult LoginViaEmail(string email, string displayName, string returnUrl) + private ActionResult LoginUser(string email, string identifier, string displayName, string returnUrl, UserAuthClaim.ClaimType type, bool trustEmail, bool isSecure = false) { - var whiteListResponse = CheckWhitelist("", email, trustEmail: true); + var whiteListResponse = CheckWhitelist(identifier, email, trustEmail: trustEmail); + if (whiteListResponse != null) return whiteListResponse; - var user = Current.DB.Query("Select * From Users Where Email = @email", new { email }).FirstOrDefault(); + Tuple identity = Models.User.FindUserIdentityByAuthClaim(email, identifier, type, CurrentUser.IsAnonymous && trustEmail); + + var user = identity.Item1; + var claim = identity.Item2; + + if (!CurrentUser.IsAnonymous && user != null && user.Id != CurrentUser.Id) + { + //TODO: Need to perform a user merge + SetHeader("Log in below to change your OpenID"); + + return LoginError("Another user with this login already exists, merging is not possible at this time."); + } - // Create the user if not found if (user == null) { - user = Models.User.CreateUser(displayName, email, null); + user = !CurrentUser.IsAnonymous ? CurrentUser : Models.User.CreateUser(displayName, email); + } + + if (claim == null) + { + Current.DB.UserAuthClaims.Insert(new { UserId = user.Id, ClaimIdentifier = identifier, IdentifierType = type, IsSecure = isSecure }); + } + else if (claim.UserId != user.Id) + { + // This implies there's an orphan claim record somehow, I don't think this should be possible + Current.DB.UserAuthClaims.Update(claim.Id, new { UserId = user.Id }); + } + + // This checking is only relevant to OpenID…which is kind of auth-type specific logic for this method, but meh + if (AppSettings.EnableEnforceSecureOpenId && user.EnforceSecureOpenId && !isSecure && claim.IsSecure) + { + return LoginError("User preferences prohibit insecure (non-https) variants of the provided OpenID identifier"); + } + else if (isSecure && !claim.IsSecure) + { + Current.DB.UserAuthClaims.Update(claim.Id, new { IsSecure = true }); } IssueFormsTicket(user); @@ -256,6 +212,7 @@ private ActionResult LoginViaEmail(string email, string displayName, string retu { return Redirect(returnUrl); } + return RedirectToAction("Index", "Home"); } @@ -479,7 +436,7 @@ private ActionResult FetchFromGoogle(string accessToken) if (person.email == null) return LoginError("Error fetching email from Google"); - return LoginViaEmail(person.email, person.name, "/"); + return LoginUser(person.email, person.email, person.name, "/", UserAuthClaim.ClaimType.Google, true); } catch (Exception e) { diff --git a/App/StackExchange.DataExplorer/Models/User.cs b/App/StackExchange.DataExplorer/Models/User.cs index 8f5d224a..762b9003 100644 --- a/App/StackExchange.DataExplorer/Models/User.cs +++ b/App/StackExchange.DataExplorer/Models/User.cs @@ -105,6 +105,27 @@ public static User CreateUser(string accountLogin) return u; } + public static Tuple FindUserIdentityByAuthClaim(string email, string identifier, UserAuthClaim.ClaimType type, bool useEmailFallback = true) + { + var claim = Current.DB.Query( + "SELECT * FROM UserAuthClaims WHERE ClaimIdentifier = @identifier AND IdentifierType = @type", + new { identifier, type } + ).FirstOrDefault(); + + User user = null; + + if (claim != null) + { + user = Current.DB.Users.Get(claim.UserId); + } + else if (useEmailFallback && email.HasValue()) + { + user = Current.DB.Query("SELECT * FROM Users WHERE Email = @email", new { email }).FirstOrDefault(); + } + + return Tuple.Create(user, claim); + } + public void SetAdmin(bool isAdmin) { Current.DB.Execute("Update Users Set IsAdmin = @isAdmin Where Id = @Id", new {Id, isAdmin}); @@ -115,7 +136,7 @@ public static User GetByADLogin(string accountLogin) return Current.DB.Query("Select * From Users Where ADLogin = @accountLogin", new {accountLogin}).SingleOrDefault(); } - public static User CreateUser(string login, string email, string openIdClaim) + public static User CreateUser(string login, string email) { var u = new User(); u.CreationDate = DateTime.UtcNow; @@ -155,8 +176,7 @@ public static User CreateUser(string login, string email, string openIdClaim) } u.Id = Current.DB.Users.Insert(new { u.Email, u.Login, u.CreationDate }).Value; - if (openIdClaim != null) - Current.DB.UserAuthClaims.Insert(new { ClaimIdentifier = openIdClaim, UserId = u.Id}); + return u; } From 6698bd86b5f9af0d42430bfabb6cbd3ea8c4037a Mon Sep 17 00:00:00 2001 From: Tim Stone Date: Sat, 29 Aug 2015 23:51:20 -0400 Subject: [PATCH 3/5] Allow upgrading from legacy Google OpenID identifiers, add display (email) for claim independent of provider ID --- .../Controllers/AccountController.cs | 76 +- App/StackExchange.DataExplorer/Models/User.cs | 18 +- .../Models/UserAuthClaim.cs | 15 +- .../StackExchange.DataExplorer.csproj | 5 + .../packages.config | 3 +- ...tityModel.Tokens.Jwt.4.0.2.206221351.nupkg | Bin 0 -> 103122 bytes .../net45/System.IdentityModel.Tokens.Jwt.Xml | 2502 +++++++++++++++++ .../net45/System.IdentityModel.Tokens.Jwt.dll | Bin 0 -> 136448 bytes Migrations/055 - Make UserOpenIds generic.sql | 7 + 9 files changed, 2593 insertions(+), 33 deletions(-) create mode 100644 App/packages/System.IdentityModel.Tokens.Jwt.4.0.2.206221351/System.IdentityModel.Tokens.Jwt.4.0.2.206221351.nupkg create mode 100644 App/packages/System.IdentityModel.Tokens.Jwt.4.0.2.206221351/lib/net45/System.IdentityModel.Tokens.Jwt.Xml create mode 100644 App/packages/System.IdentityModel.Tokens.Jwt.4.0.2.206221351/lib/net45/System.IdentityModel.Tokens.Jwt.dll diff --git a/App/StackExchange.DataExplorer/Controllers/AccountController.cs b/App/StackExchange.DataExplorer/Controllers/AccountController.cs index 0cb1aefb..5aa5ade7 100644 --- a/App/StackExchange.DataExplorer/Controllers/AccountController.cs +++ b/App/StackExchange.DataExplorer/Controllers/AccountController.cs @@ -1,4 +1,5 @@ using System; +using System.IdentityModel.Tokens; using System.IO; using System.Linq; using System.Net; @@ -144,14 +145,11 @@ public ActionResult Authenticate(string returnUrl) var normalizedClaim = Models.User.NormalizeOpenId(response.ClaimedIdentifier.ToString()); var sreg = response.GetExtension(); var isSecure = originalClaim.StartsWith("https://"); + var email = sreg != null && sreg.Email != null && sreg.Email.Length > 2 ? sreg.Email : null; + var displayName = sreg != null ? sreg.Nickname ?? sreg.FullName : null; - var whitelistEmail = sreg != null && sreg.Email != null && sreg.Email.Length > 2 ? sreg.Email : null; - var whiteListResponse = CheckWhitelist(normalizedClaim, whitelistEmail); - if (whiteListResponse != null) - return whiteListResponse; - - return LoginUser(whitelistEmail, normalizedClaim, sreg != null ? sreg.Nickname ?? sreg.FullName : null, returnUrl, - UserAuthClaim.ClaimType.OpenID, IsVerifiedEmailProvider(originalClaim), isSecure); + return LoginUser(new UserAuthClaim.Identifier(normalizedClaim, UserAuthClaim.ClaimType.OpenID), email, displayName, + returnUrl, IsVerifiedEmailProvider(originalClaim), isSecure); case AuthenticationStatus.Canceled: return LoginError("Canceled at provider"); case AuthenticationStatus.Failed: @@ -161,14 +159,14 @@ public ActionResult Authenticate(string returnUrl) return new EmptyResult(); } - private ActionResult LoginUser(string email, string identifier, string displayName, string returnUrl, UserAuthClaim.ClaimType type, bool trustEmail, bool isSecure = false) + private ActionResult LoginUser(UserAuthClaim.Identifier identifier, string email, string displayName, string returnUrl, bool trustEmail, bool isSecure = false, UserAuthClaim.Identifier legacyIdentifier = null) { - var whiteListResponse = CheckWhitelist(identifier, email, trustEmail: trustEmail); + var whiteListResponse = CheckWhitelist(identifier.Value, email, trustEmail: trustEmail); if (whiteListResponse != null) return whiteListResponse; - Tuple identity = Models.User.FindUserIdentityByAuthClaim(email, identifier, type, CurrentUser.IsAnonymous && trustEmail); + Tuple identity = Models.User.FindUserIdentityByAuthClaim(email, identifier, CurrentUser.IsAnonymous && trustEmail, legacyIdentifier: legacyIdentifier); var user = identity.Item1; var claim = identity.Item2; @@ -188,22 +186,29 @@ private ActionResult LoginUser(string email, string identifier, string displayNa if (claim == null) { - Current.DB.UserAuthClaims.Insert(new { UserId = user.Id, ClaimIdentifier = identifier, IdentifierType = type, IsSecure = isSecure }); + Current.DB.UserAuthClaims.Insert(new { UserId = user.Id, ClaimIdentifier = identifier.Value, IdentifierType = identifier.Type, IsSecure = isSecure, Display = trustEmail ? email : null }); } else if (claim.UserId != user.Id) { // This implies there's an orphan claim record somehow, I don't think this should be possible Current.DB.UserAuthClaims.Update(claim.Id, new { UserId = user.Id }); } - - // This checking is only relevant to OpenID…which is kind of auth-type specific logic for this method, but meh - if (AppSettings.EnableEnforceSecureOpenId && user.EnforceSecureOpenId && !isSecure && claim.IsSecure) - { - return LoginError("User preferences prohibit insecure (non-https) variants of the provided OpenID identifier"); - } - else if (isSecure && !claim.IsSecure) + else { - Current.DB.UserAuthClaims.Update(claim.Id, new { IsSecure = true }); + // This checking is only relevant to OpenID…which is kind of auth-type specific logic for this method, but meh + if (AppSettings.EnableEnforceSecureOpenId && user.EnforceSecureOpenId && !isSecure && claim.IsSecure) + { + return LoginError("User preferences prohibit insecure (non-https) variants of the provided OpenID identifier"); + } + else if (isSecure && !claim.IsSecure) + { + Current.DB.UserAuthClaims.Update(claim.Id, new { IsSecure = true }); + } + + if (trustEmail && claim.Display != email) + { + Current.DB.UserAuthClaims.Update(claim.Id, new { Display = email }); + } } IssueFormsTicket(user); @@ -297,13 +302,14 @@ private ActionResult OAuthLogin() // return Redirect(redirect); case "https://accounts.google.com/o/oauth2/auth": // Google GetGoogleConfig(out secret, out clientId, out path); + return Redirect(string.Format( - "{0}?client_id={1}&scope=openid+email&redirect_uri={2}&state={3}&response_type=code", - server, - clientId, - (BaseUrl + path).UrlEncode(), - stateJson.UrlEncode() - )); + "{0}?client_id={1}&scope=openid+email&redirect_uri={2}&state={3}&response_type=code&openid.realm={2}", + server, + clientId, + (BaseUrl + path).UrlEncode(), + stateJson.UrlEncode() + )); } return LoginError("Unsupported OAuth version or server"); @@ -352,9 +358,10 @@ public ActionResult GoogleCallback(string code, string state, string error) var responseStr = Encoding.UTF8.GetString(response); authResponse = JsonConvert.DeserializeObject(responseStr); } - if (authResponse != null) + + if (authResponse != null && !authResponse.error.HasValue()) { - var loginResponse = FetchFromGoogle(authResponse.access_token); + var loginResponse = FetchFromGoogle(authResponse.access_token, authResponse.id_token); if (loginResponse != null) return loginResponse; } } @@ -387,8 +394,11 @@ public ActionResult GoogleCallback(string code, string state, string error) return LoginError("Google authentication failed"); } - private ActionResult FetchFromGoogle(string accessToken) + private ActionResult FetchFromGoogle(string accessToken, string idToken) { + // We're not bothering to validate the id token because we just got it back directly from Google over HTTPS + var legacyIdentifier = (string)new JwtSecurityToken(idToken).Payload["openid_id"]; + string result = null; Exception lastException = null; for (var retry = 0; retry < GoogleAuthRetryAttempts; retry++) @@ -436,7 +446,14 @@ private ActionResult FetchFromGoogle(string accessToken) if (person.email == null) return LoginError("Error fetching email from Google"); - return LoginUser(person.email, person.email, person.name, "/", UserAuthClaim.ClaimType.Google, true); + return LoginUser( + new UserAuthClaim.Identifier(person.id, UserAuthClaim.ClaimType.Google), + person.email, + person.name, + "/", + person.verified_email, + legacyIdentifier: legacyIdentifier.HasValue() ? new UserAuthClaim.Identifier(Models.User.NormalizeOpenId(legacyIdentifier), UserAuthClaim.ClaimType.OpenID) : null + ); } catch (Exception e) { @@ -503,6 +520,7 @@ public class OAuthLoginState public class GoogleAuthResponse { public string access_token { get; set; } + public string id_token { get; set; } public string error { get; set; } public string error_description { get; set; } } diff --git a/App/StackExchange.DataExplorer/Models/User.cs b/App/StackExchange.DataExplorer/Models/User.cs index 762b9003..b16a341e 100644 --- a/App/StackExchange.DataExplorer/Models/User.cs +++ b/App/StackExchange.DataExplorer/Models/User.cs @@ -105,13 +105,27 @@ public static User CreateUser(string accountLogin) return u; } - public static Tuple FindUserIdentityByAuthClaim(string email, string identifier, UserAuthClaim.ClaimType type, bool useEmailFallback = true) + public static Tuple FindUserIdentityByAuthClaim(string email, UserAuthClaim.Identifier identifier, bool useEmailFallback = true, UserAuthClaim.Identifier legacyIdentifier = null) { var claim = Current.DB.Query( "SELECT * FROM UserAuthClaims WHERE ClaimIdentifier = @identifier AND IdentifierType = @type", - new { identifier, type } + new { identifier = identifier.Value, type = identifier.Type } ).FirstOrDefault(); + if (claim == null && legacyIdentifier != null) + { + claim = Current.DB.Query( + "SELECT * FROM UserAuthClaims WHERE ClaimIdentifier = @identifier AND IdentifierType = @type", + new { identifier = legacyIdentifier.Value, type = legacyIdentifier.Type } + ).FirstOrDefault(); + + if (claim != null) + { + // Update the legacy auth claim (only Google OpenID -> email right now) + Current.DB.UserAuthClaims.Update(claim.Id, new { ClaimIdentifier = identifier.Value, IdentifierType = identifier.Type, IsSecure = false, Display = email }); + } + } + User user = null; if (claim != null) diff --git a/App/StackExchange.DataExplorer/Models/UserAuthClaim.cs b/App/StackExchange.DataExplorer/Models/UserAuthClaim.cs index c7922fc5..44fa80ae 100644 --- a/App/StackExchange.DataExplorer/Models/UserAuthClaim.cs +++ b/App/StackExchange.DataExplorer/Models/UserAuthClaim.cs @@ -13,10 +13,23 @@ public enum ClaimType Google = 2 } + public class Identifier + { + public readonly ClaimType Type; + public readonly string Value; + + public Identifier(String value, ClaimType type) + { + Value = value; + Type = type; + } + } + public int Id { get; set; } public int UserId { get; set; } public string ClaimIdentifier { get; set; } public bool IsSecure { get; set; } - public ClaimType Type { get; set; } + public ClaimType IdentifierType { get; set; } + public string Display { get; set; } } } \ No newline at end of file diff --git a/App/StackExchange.DataExplorer/StackExchange.DataExplorer.csproj b/App/StackExchange.DataExplorer/StackExchange.DataExplorer.csproj index 5e2d7e30..4f206d21 100644 --- a/App/StackExchange.DataExplorer/StackExchange.DataExplorer.csproj +++ b/App/StackExchange.DataExplorer/StackExchange.DataExplorer.csproj @@ -118,6 +118,11 @@ 3.5 + + + ..\packages\System.IdentityModel.Tokens.Jwt.4.0.2.206221351\lib\net45\System.IdentityModel.Tokens.Jwt.dll + True + False diff --git a/App/StackExchange.DataExplorer/packages.config b/App/StackExchange.DataExplorer/packages.config index 50e6d89e..2eb051a0 100644 --- a/App/StackExchange.DataExplorer/packages.config +++ b/App/StackExchange.DataExplorer/packages.config @@ -17,11 +17,12 @@ - + + \ No newline at end of file diff --git a/App/packages/System.IdentityModel.Tokens.Jwt.4.0.2.206221351/System.IdentityModel.Tokens.Jwt.4.0.2.206221351.nupkg b/App/packages/System.IdentityModel.Tokens.Jwt.4.0.2.206221351/System.IdentityModel.Tokens.Jwt.4.0.2.206221351.nupkg new file mode 100644 index 0000000000000000000000000000000000000000..fdb057f0c10b9e884240842ef91a04b8688fac9a GIT binary patch literal 103122 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

    L(=9g+#*#S68*KHF(3`g^W? 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 literal 0 HcmV?d00001 diff --git a/App/packages/System.IdentityModel.Tokens.Jwt.4.0.2.206221351/lib/net45/System.IdentityModel.Tokens.Jwt.Xml b/App/packages/System.IdentityModel.Tokens.Jwt.4.0.2.206221351/lib/net45/System.IdentityModel.Tokens.Jwt.Xml new file mode 100644 index 00000000..817f5bfe --- /dev/null +++ b/App/packages/System.IdentityModel.Tokens.Jwt.4.0.2.206221351/lib/net45/System.IdentityModel.Tokens.Jwt.Xml @@ -0,0 +1,2502 @@ + + + + System.IdentityModel.Tokens.Jwt + + + + + Helper class for adding DateTimes and Timespans. + + + + + Add a DateTime and a TimeSpan. + The maximum time is DateTime.MaxTime. It is not an error if time + timespan > MaxTime. + Just return MaxTime. + + Initial value. + to add. + as the sum of time and timespan. + + + + Gets the Maximum value for a DateTime specifying kind. + + DateTimeKind to use. + DateTime of specified kind. + + + + Gets the Minimum value for a DateTime specifying kind. + + DateTimeKind to use. + DateTime of specified kind. + + + + Error codes and messages + + + + + Serializes the list of strings into string as follows: + 'str1','str2','str3' ... + + + The strings used to build a comma delimited string. + + + The single . + + + + + Provides signing and verifying operations when working with an + + + + + This class defines the object model for types that provide signature services. + + + + + Produces a signature over the 'input' + + bytes to sign. + signed bytes + + + + Verifies that a signature created over the 'input' matches the signature. + + bytes to verify. + signature to compare against. + true if the computed signature matches the signature parameter, false otherwise. + + + + Calls and + + + + + Can be over written in descendants to dispose of internal components. + + true, if called from Dispose(), false, if invoked inside a finalizer + + + + Gets or sets a user context for a . + + + + + Initializes a new instance of the class used to create and verify signatures. + + + The that will be used for cryptographic operations. + + + The signature algorithm to apply. + + + If this is required to create signatures then set this to true. + + Creating signatures requires that the has access to a private key. + Verifying signatures (the default), does not require access to the private key. + + + + 'key' is null. + + + 'algorithm' is null. + + + 'algorithm' contains only whitespace. + + + willCreateSignatures is true and .KeySize is less than . + + + .KeySize is less than . Note: this is always checked. + + + Is thrown if the throws. + + + Is thrown if the returns null. + + + Is thrown if the throws. + + + Is thrown if the returns null. + + + Is thrown if the throws. + + + Is thrown if the returns null. + + + Is thrown if the throws. + + + Is thrown if the throws. + + + + + Produces a signature over the 'input' using the and algorithm passed to . + + bytes to be signed. + a signature over the input. + 'input' is null. + 'input.Length' == 0. + if has been called. + if the internal is null. This can occur if the constructor parameter 'willBeUsedforSigning' was not 'true'. + if the internal is null. This can occur if a derived type deletes it or does not create it. + + + + Verifies that a signature over the' input' matches the signature. + + the bytes to generate the signature over. + the value to verify against. + true if signature matches, false otherwise. + 'input' is null. + 'signature' is null. + 'input.Length' == 0. + 'signature.Length' == 0. + if has been called. + if the internal is null. This can occur if a derived type does not call the base constructor. + if the internal is null. This can occur if a derived type deletes it or does not create it. + + + + Calls to release this managed resources. + + true, if called from Dispose(), false, if invoked inside a finalizer. + + + + Encodes and Decodes strings as Base64Url encoding. + + + + + The following functions perform base64url encoding which differs from regular base64 encoding as follows + * padding is skipped so the pad character '=' doesn't have to be percent encoded + * the 62nd and 63rd regular base64 encoding characters ('+' and '/') are replace with ('-' and '_') + The changes make the encoding alphabet file and URL safe. + + string to encode. + Base64Url encoding of the UTF8 bytes. + + + + Converts a subset of an array of 8-bit unsigned integers to its equivalent string representation that is encoded with base-64-url digits. Parameters specify + the subset as an offset in the input array, and the number of elements in the array to convert. + + An array of 8-bit unsigned integers. + An offset in inArray. + The number of elements of inArray to convert. + The string representation in base 64 url encodingof length elements of inArray, starting at position offset. + 'inArray' is null. + offset or length is negative OR offset plus length is greater than the length of inArray. + + + + Converts a subset of an array of 8-bit unsigned integers to its equivalent string representation that is encoded with base-64-url digits. Parameters specify + the subset as an offset in the input array, and the number of elements in the array to convert. + + An array of 8-bit unsigned integers. + The string representation in base 64 url encodingof length elements of inArray, starting at position offset. + 'inArray' is null. + offset or length is negative OR offset plus length is greater than the length of inArray. + + + + Converts the specified string, which encodes binary data as base-64-url digits, to an equivalent 8-bit unsigned integer array. + base64Url encoded string. + UTF8 bytes. + + + + Decodes the string from Base64UrlEncoded to UTF8. + + string to decode. + UTF8 string. + + + + Defines the inbound and outbound mapping for claim claim types from jwt to .net claim + + + + + Initializes static members of the class. + + + + + Gets the InboundClaimTypeMap used by JwtSecurityTokenHandler when producing claims from jwt. + + + + + Gets the OutboundClaimTypeMap is used by JwtSecurityTokenHandler to shorten claim types when creating a jwt. + + + + + Provides common code for services to use in generating diagnostics and taking actions. + + + + + Returns true if the provided exception matches any of a list of hard system faults that should be allowed + through to outer exception handlers. + + The exception to check. + + Typically this method is used when there is a need to catch all exceptions, but to ensure that .NET runtime + and execution engine exceptions are not absorbed by the catch block. Use of this method also avoids FxCop + warnings about not using general catch blocks. + Please note that use of this method is expensive because of the amount of reflection it performs. + If you can refactor your code to catch more specific exceptions than Exception to avoid using this method, + you should. + Example of use: + + try + { + // Code needing a full Exception catch block + } + catch (Exception ex) + { + if (DiagnosticUtility.IsFatal(ex)) + { + throw; + } + // Perform any needed logging and handling for absorbed exception. + } + + + true if the exception should NOT be trapped + + + + Returns the absolute DateTime or the Seconds since Unix Epoch, where Epoch is UTC 1970-01-01T0:0:0Z. + + + + + DateTime as UTV for UnixEpoch + + + + + Per JWT spec: + Gets the number of seconds from 1970-01-01T0:0:0Z as measured in UTC until the desired date/time. + + The DateTime to convert to seconds. + if dateTimeUtc less than UnixEpoch, return 0 + the number of seconds since Unix Epoch. + + + + Creates a DateTime from epoch time. + + Number of seconds. + The DateTime in UTC. + + + + ISecurityTokenValidator + + + + + Returns true if the token can be read, false otherwise. + + + + + Validates a token passed as a string using + + + + + Gets and sets the maximum size in bytes, that a will be processed. + + + + + Interface that defines a simple cache for tacking replaying of security tokens. + + + + + Try to add a securityToken. + + the security token to add. + the time when security token expires. + true if the security token was successfully added. + + + + Try to find securityToken + + the security token to find. + true if the security token is found. + + + + Definition for a delegate that can be set on to control serialization of objects into JSON. + + Object to serialize + The serialized object. + + + + Definition for a delegate that can be set on to control deserialization JSON into objects. + + JSON to deserialize. + type expected. + The deserialized object. + + + + Dictionary extensions for serializations + + + + + Serializes an object to JSON. + + The object to serialize + the object as JSON. + + + + Deserialzes JSON into an instance of type T. + + the object type. + the JSON to deserialze. + a new instance of type T. + + + + Deserialzes JSON into an instance of . + + the JSON to deserialze. + a new instance . + + + + Deserialzes JSON into an instance of . + + the JSON to deserialze. + a new instance . + + + + Gets or sets a to use when serializing objects to JSON. + + if 'value' is null. + + + + Gets or sets a to use when deserializing objects from JSON. + + if 'value' is null. + + + + contains the element and attribute names used in config when parsing the JwtSecurityTokenHandler from XML. + + + + + Constants for Json Web tokens. + + + + + Short header type. + + + + + Long header type. + + + + + Short token type. + + + + + Long token type. + + + + + Token format: 'header.payload.signature'. Signature is optional, but '.' is required. + + + + + When mapping json to .Net Claim(s), if the value was not a string (or an enumeration of strings), the ClaimValue will serialized using the current JSON serializer, a property will be added with the .Net type and the ClaimTypeValue will be set to 'JsonClaimValueType'. + + + + + List of algorithms see: http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-26#section-3 + + + + + see: http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-26#section-3 + + + + + see: http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-26#section-3 + + + + + see: http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-26#section-3 + + + + + see: http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-26#section-3 + + + + + see: http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-26#section-3 + + + + + see: http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-26#section-3 + + + + + see: http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-26#section-3 + + + + + see: http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-26#section-3 + + + + + see: http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-26#section-3 + + + + + see: http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-26#section-3 + + + + + List of header parameter names see: http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-20#section-5. + + + + + see: http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-20#section-5 + + + + + see: http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-20#section-5 + + + + + see: http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-20#section-5 + + + + + see: http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-20#section-5 + + + + + see: http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-20#section-5 + + + + + see: http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-20#section-5 + + + + + see: http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-20#section-5 + + + + + see: http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-20#section-5 + + + + + see: http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-20#section-5 + + + + + List of registered claims from different sources + http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-20#section-4 + http://openid.net/specs/openid-connect-core-1_0.html#IDToken + + + + + http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-20#section-4 + + + + + http://openid.net/specs/openid-connect-core-1_0.html#IDToken + + + + + http://openid.net/specs/openid-connect-core-1_0.html#IDToken + + + + + http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-20#section-4 + + + + + http://openid.net/specs/openid-connect-core-1_0.html#IDToken + + + + + http://openid.net/specs/openid-connect-core-1_0.html#IDToken + + + + + http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-20#section-4 + + + + + http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-20#section-4 + + + + + http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-20#section-4 + + + + + http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-20#section-4 + + + + + http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-20#section-4 + + + + + http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-20#section-4 + + + + + http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-20#section-4 + + + + + http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-20#section-4 + + + + + http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-20#section-4 + + + + + http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-20#section-4 + + + + + http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-20#section-4 + + + + + http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-20#section-4 + + + + + http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-20#section-4 + + + + + http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-20#section-4 + + + + + http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-20#section-4 + + + + + http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-20#section-4 + + + + + http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-20#section-4 + + + + + http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-20#section-4 + + + + + Initializes a new instance of which contains JSON objects representing the cryptographic operations applied to the JWT and optionally any additional properties of the JWT. + The member names within the JWT Header are referred to as Header Parameter Names. + These names MUST be unique and the values must be (s). The corresponding values are referred to as Header Parameter Values. + + + + + Initializes a new instance of the class. Default string comparer . + + + + + Initializes a new instance of the class. With the Header Parameters as follows: + { { typ, JWT }, { alg, Mapped( } } + See: Algorithm Mapping below. + + The that will be or were used to sign the . + + For each in signingCredentials.SigningKeyIdentifier + if the clause is a Header Parameter { clause.Name, clause.Id } will be added. + For example, if clause.Name == 'kid' and clause.Id == 'SecretKey99'. The JSON object { kid, SecretKey99 } would be added. + In addition, if the is a the JSON object { x5t, Base64UrlEncoded( } will be added. + This simplifies the common case where a X509Certificate is used. + ================= + Algorithm Mapping + ================= + describes the algorithm that is discoverable by the CLR runtime. + The { alg, 'value' } placed in the header reflects the JWT specification. + contains a signature mapping where the 'value' above will be translated according to this mapping. + Current mapping is: +     'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256' => 'RS256' +     'http://www.w3.org/2001/04/xmldsig-more#hmac-sha256' => 'HS256' + + + + + Serializes this instance to JSON. + + this instance as JSON. + use to customize JSON serialization. + + + + Encodes this instance as Base64UrlEncoded JSON. + + Base64UrlEncoded JSON. + use to customize JSON serialization. + + + + Deserializes Base64UrlEncoded JSON into a instance. + + base64url encoded JSON to deserialize. + an instance of . + use to customize JSON serialization. + + + + Deserialzes JSON into a instance. + + the JSON to deserialize. + an instance of . + use to customize JSON serialization. + + + + Gets the signature algorithm that was used to create the signature. + + If the signature algorithm is not found, null is returned. + + + + Gets the passed in the constructor. + + This value may be null. + + + + Gets the mime type (Typ) of the token. + + If the mime type is not found, null is returned. + + + + Gets a that contains a for each key found. + + + Keys are identified by matching a 'Reserved Header Parameter Name' found in the in JSON Web Signature specification. + Names recognized are: jku, jkw, kid, x5c, x5t, x5u + 'x5t' adds a passing a the Base64UrlDecoded( Value ) to the constructor. + 'jku', 'jkw', 'kid', 'x5u', 'x5c' each add a with the { Name, Value } passed to the . + + If no keys are found, an empty will be returned. + + + + + Initializes a new instance of which contains JSON objects representing the claims contained in the JWT. Each claim is a JSON object of the form { Name, Value }. + + + + + Initializes a new instance of the class with no claims. Default string comparer . + Creates a empty + + + + + Initializes a new instance of the class with . Default string comparer . + the claims to add. + + + + + Initializes a new instance of the class with claims added for each parameter specified. Default string comparer . + + if this value is not null, a { iss, 'issuer' } claim will be added. + if this value is not null, a { aud, 'audience' } claim will be added + if this value is not null then for each a { 'Claim.Type', 'Claim.Value' } is added. If duplicate claims are found then a { 'Claim.Type', List<object> } will be created to contain the duplicate values. + if notbefore.HasValue is 'true' a { nbf, 'value' } claim is added. + if expires.HasValue is 'true' a { exp, 'value' } claim is added. + Comparison is set to + The 4 parameters: 'issuer', 'audience', 'notBefore', 'expires' take precednece over (s) in 'claims'. The values in 'claims' will be overridden. + if 'expires' <= 'notbefore'. + + + + Adds a JSON object representing the to the + + { 'Claim.Type', 'Claim.Value' } is added. If a JSON object is found with the name == then a { 'Claim.Type', List<object> } will be created to contain the duplicate values. + See for details on how is applied. + 'claim' is null. + + + + Adds a number of to the as JSON { name, value } pairs. + + for each a JSON pair { 'Claim.Type', 'Claim.Value' } is added. If duplicate claims are found then a { 'Claim.Type', List<object> } will be created to contain the duplicate values. + Each added will have translated according to the mapping found in . Adding and removing to + will affect the name component of the Json claim + Any in the that is null, will be ignored. + 'claims' is null. + + + + Gets the DateTime using the number of seconds from 1970-01-01T0:0:0Z (UTC) + + Claim in the payload that should map to an integer. + If the claim is not found, the function returns: DateTime.MinValue + + if an overflow exception is thrown by the runtime. + the DateTime representation of a claim. + + + + Serializes this instance to JSON. + + this instance as JSON. + use to customize JSON serialization. + + + + Encodes this instance as Base64UrlEncoded JSON. + + Base64UrlEncoded JSON. + use to customize JSON serialization. + + + + Deserializes Base64UrlEncoded JSON into a instance. + + base64url encoded JSON to deserialize. + an instance of . + use to customize JSON serialization. + + + + Deserialzes JSON into a instance. + + the JSON to deserialize. + an instance of . + use to customize JSON serialization. + + + + Gets the 'value' of the 'actor' claim { actort, 'value' }. + + If the 'actor' claim is not found, null is returned. + + + + Gets the 'value' of the 'acr' claim { acr, 'value' }. + + If the 'acr' claim is not found, null is returned. + + + + Gets the 'value' of the 'amr' claim { amr, 'value' }. + + If the 'amr' claim is not found, null is returned. + + + + Gets the 'value' of the 'auth_time' claim { auth_time, 'value' }. + + If the 'auth_time' claim is not found, null is returned. + + + + Gets the 'value' of the 'audience' claim { aud, 'value' } as a list of strings. + + If the 'audience' claim is not found, an empty enumerable is returned. + + + + Gets the 'value' of the 'azp' claim { azp, 'value' }. + + If the 'azp' claim is not found, null is returned. + + + + Gets 'value' of the 'c_hash' claim { c_hash, 'value' }. + + If the 'c_hash' claim is not found, null is returned. + + + + Gets the 'value' of the 'expiration' claim { exp, 'value' }. + + If the 'expiration' claim is not found OR could not be converted to , null is returned. + + + + Gets the 'value' of the 'JWT ID' claim { jti, 'value' }. + + If the 'JWT ID' claim is not found, null is returned. + + + + Gets the 'value' of the 'Issued At' claim { iat, 'value' }. + + If the 'Issued At' claim is not found OR cannot be converted to null is returned. + + + + Gets 'value' of the 'issuer' claim { iss, 'value' }. + + If the 'issuer' claim is not found, null is returned. + + + + Gets the 'value' of the 'expiration' claim { nbf, 'value' }. + + If the 'notbefore' claim is not found OR could not be converted to , null is returned. + + + + Gets 'value' of the 'nonce' claim { nonce, 'value' }. + + If the 'nonce' claim is not found, null is returned. + + + + Gets "value" of the 'subject' claim { sub, 'value' }. + + If the 'subject' claim is not found, null is returned. + + + + Gets 'value' of the 'notbefore' claim { nbf, 'value' } converted to a assuming 'value' is seconds since UnixEpoch (UTC 1970-01-01T0:0:0Z). + + If the 'notbefore' claim is not found, then is returned. + + + + Gets 'value' of the 'expiration' claim { exp, 'value' } converted to a assuming 'value' is seconds since UnixEpoch (UTC 1970-01-01T0:0:0Z). + + If the 'expiration' claim is not found, then is returned. + + + + Gets a for each JSON { name, value }. + + Each (s) returned will have the translated according to the mapping found in . Adding and removing to will affect the value of the . + and will be set to the value of ( if null). + + + + A designed for representing a JSON Web Token (JWT). + + + + + Initializes a new instance of from a string in JWS Compact serialized format. + + A JSON Web Token that has been serialized in JWS Compact serialized format. + 'jwtEncodedString' is null. + 'jwtEncodedString' contains only whitespace. + 'jwtEncodedString' is not in JWS Compact serialized format. + + The contents of this have not been validated, the JSON Web Token is simply decoded. Validation can be accomplished using + + + + + Initializes a new instance of the class where the contains the crypto algorithms applied to the encoded and . The jwtEncodedString is the result of those operations. + + Contains JSON objects representing the cryptographic operations applied to the JWT and optionally any additional properties of the JWT + Contains JSON objects representing the claims contained in the JWT. Each claim is a JSON object of the form { Name, Value } + base64urlencoded JwtHeader + base64urlencoded JwtPayload + base64urlencoded JwtSignature + 'header' is null. + 'payload' is null. + 'rawSignature' is null. + 'rawHeader' or 'rawPayload' is null or whitespace. + + + + Initializes a new instance of the class where the contains the crypto algorithms applied to the encoded and . The jwtEncodedString is the result of those operations. + + Contains JSON objects representing the cryptographic operations applied to the JWT and optionally any additional properties of the JWT + Contains JSON objects representing the claims contained in the JWT. Each claim is a JSON object of the form { Name, Value } + 'header' is null. + 'payload' is null. + + + + Initializes a new instance of the class specifying optional parameters. + + if this value is not null, a { iss, 'issuer' } claim will be added. + if this value is not null, a { aud, 'audience' } claim will be added + if this value is not null then for each a { 'Claim.Type', 'Claim.Value' } is added. If duplicate claims are found then a { 'Claim.Type', List<object> } will be created to contain the duplicate values. + if expires.HasValue a { exp, 'value' } claim is added. + if notbefore.HasValue a { nbf, 'value' } claim is added. + The that will be used to sign the . See for details pertaining to the Header Parameter(s). + if 'expires' <= 'notbefore'. + + + + Serializes the and + + A string containing the header and payload in JSON format + + + + Decodes the string into the header, payload and signature + + Base64Url encoded string. + + + + Gets the 'value' of the 'actor' claim { actort, 'value' }. + + If the 'actor' claim is not found, null is returned. + + + + Gets the list of 'audience' claim { aud, 'value' }. + + If the 'audience' claim is not found, enumeration will be empty. + + + + Gets the (s) for this token. + + (s) returned will NOT have the translated according to + + + + Gets the Base64UrlEncoded associated with this instance. + + + + + Gets the Base64UrlEncoded associated with this instance. + + + + + Gets the associated with this instance. + + + + + Gets the 'value' of the 'JWT ID' claim { jti, ''value' }. + + If the 'JWT ID' claim is not found, null is returned. + + + + Gets the 'value' of the 'issuer' claim { iss, 'value' }. + + If the 'issuer' claim is not found, null is returned. + + + + Gets the associated with this instance. + + + + + Gets the original raw data of this instance when it was created. + + The original JSON Compact serialized format passed to one of the two constructors + or + + + + Gets the original raw data of this instance when it was created. + + The original JSON Compact serialized format passed to one of the two constructors + or + + + + Gets the original raw data of this instance when it was created. + + The original JSON Compact serialized format passed to one of the two constructors + or + + + + Gets the original raw data of this instance when it was created. + + The original JSON Compact serialized format passed to one of the two constructors + or + + + + Gets the s for this instance. + + By default an empty collection is returned. + + + + Gets the signature algorithm associated with this instance. + + if there is a associated with this instance, a value will be returned. Null otherwise. + + + + Gets the associated with this instance. + + + + + Gets or sets the that signed this instance. + + .ValidateSignature(...) sets this value when a is used to successfully validate a signature. + + + + Gets or sets the that contains a that signed this instance. + + .ValidateSignature(...) sets this value when a is used to successfully validate a signature. + + + + Gets "value" of the 'subject' claim { sub, 'value' }. + + If the 'subject' claim is not found, null is returned. + + + + Gets 'value' of the 'notbefore' claim { nbf, 'value' } converted to a assuming 'value' is seconds since UnixEpoch (UTC 1970-01-01T0:0:0Z). + + If the 'notbefore' claim is not found, then is returned. + + + + Gets 'value' of the 'expiration' claim { exp, 'value' } converted to a assuming 'value' is seconds since UnixEpoch (UTC 1970-01-01T0:0:0Z). + + If the 'expiration' claim is not found, then is returned. + + + + A designed for creating and validating Json Web Tokens. See http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-07. + + + + + Default lifetime of tokens created. When creating tokens, if 'expires' and 'notbefore' are both null, then a default will be set to: expires = DateTime.UtcNow, notbefore = DateTime.UtcNow + TimeSpan.FromMinutes(TokenLifetimeInMinutes). + + + + + Initializes a new instance of the class. + + + + + Obsolete method, use when processing tokens. + + use . when processing tokens. + + + + Determines if the is positioned on a well formed <BinarySecurityToken> element. + + positioned at xml. + + 'true' if the reader is positioned at an element <BinarySecurityToken>. + in the namespace: 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd' + With an attribute of 'valueType' equal to one of: +     "urn:ietf:params:oauth:token-type:jwt", "JWT" + + For example: <wsse:BinarySecurityToken valueType = "JWT"> ... + + 'false' otherwise. + + The 'EncodingType' attribute is optional, if it is set, it must be equal to: "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary". + 'reader' is null. + + + + Determines if the string is a well formed Json Web token (see http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-07) + + string that should represent a valid JSON Web Token. + Uses ( token, @"^[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+\.[A-Za-z0-9-_]*$" ). + + + 'true' if the token is in JSON compact serialization format. + 'false' if token.Length * 2 > . + + 'tokenString' is null. + + + + Creating is not NotSupported. + + to create a . + + + + Creates a based on values found in the . + + Contains the parameters used to create the token. + A . + + If is not null, will be signed. + + 'tokenDescriptor' is null. + + + + Uses the constructor, first creating the and . + If is not null, will be signed. + + the issuer of the token. + the audience for this token. + the source of the (s) for this token. + the notbefore time for this token. + the expiration time for this token. + contains cryptographic material for generating a signature. + optional . + If is not null, then a claim { actort, 'value' } will be added to the payload. for details on how the value is created. + See for details on how the HeaderParameters are added to the header. + See for details on how the values are added to the payload. + If signautureProvider is not null, then it will be used to create the signature and will not be called. + A . + if 'expires' <= 'notBefore'. + + + + Gets the token type identifier(s) supported by this handler. + + A collection of strings that identify the tokens this instance can handle. + When receiving a wrapped inside a <wsse:BinarySecurityToken> element. The <wsse:BinarySecurityToken> element must have the ValueType attribute set to one of these values + in order for this handler to recognize that it can read the token. + + + + Reads a JSON web token wrapped inside a WS-Security BinarySecurityToken xml element. + + The pointing at the jwt. + An instance of + First calls .CanReadToken + The reader must be positioned at an element named: + BinarySecurityToken'. + in the namespace: 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd' + with a 'ValueType' attribute equal to one of: "urn:ietf:params:oauth:token-type:jwt", "JWT". + + For example <wsse:BinarySecurityToken valueType = "JWT"> ... + + + The 'EncodingType' attribute is optional, if it is set, it must be equal to: "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" + + + 'reader' is null. + if returns false. + + + + Reads a token encoded in JSON Compact serialized format. + + A 'JSON Web Token' (JWT) that has been encoded as a JSON object. May be signed + using 'JSON Web Signature' (JWS). + + The JWT must be encoded using Base64Url encoding of the UTF-8 representation of the JWT: Header, Payload and Signature. + The contents of the JWT returned are not validated in any way, the token is simply decoded. Use ValidateToken to validate the JWT. + + A + + + + Obsolete method, use . + + use . + + + + Reads and validates a token encoded in JSON Compact serialized format. + + A 'JSON Web Token' (JWT) that has been encoded as a JSON object. May be signed using 'JSON Web Signature' (JWS). + Contains validation parameters for the . + The that was validated. + 'securityToken' is null or whitespace. + 'validationParameters' is null. + 'securityToken.Length' > . + A from the jwt. Does not include the header claims. + + + + Writes the wrapped in a WS-Security BinarySecurityToken using the . + + used to write token. + The that will be written. + 'writer' is null. + 'token' is null. + 'token' is not a not . + The current contents are encoded. If is not null, the encoding will contain a signature. + + + + Writes the as a JSON Compact serialized format string. + + to serialize. + + If the are not null, the encoding will contain a signature. + + 'token' is null. + 'token' is not a not . + The as a signed (if exist) encoded string. + + + + Produces a signature over the 'input' using the and algorithm specified. + + string to be signed + the to use. + the algorithm to use. + if provided, the will be used to sign the token + The signature over the bytes obtained from UTF8Encoding.GetBytes( 'input' ). + The used to created the signature is obtained by calling . + 'input' is null. + returns null. + + + + Validates that the signature, if found and / or required is valid. + + A 'JSON Web Token' (JWT) that has been encoded as a JSON object. May be signed + using 'JSON Web Signature' (JWS). + that contains signing keys. + thrown if 'token is null or whitespace. + thrown if 'validationParameters is null. + thrown if a signature is not found and is true. + thrown if the 'token' has a key identifier and none of the (s) provided result in a validated signature. + This can indicate that a key refresh is required. + thrown if after trying all the (s), none result in a validated signture AND the 'token' does not have a key identifier. + that has the signature validated if token was signed and is true. + If the 'token' is signed, the signature is validated even if is false. + If the 'token' signature is validated, then the will be set to the key that signed the 'token'. + + + + Produces a readable string for a key, used in error messages. + + + + + + + Creates a from a . + + The to use as a source. + The value to set + contains parameters for validating the token. + A containing the . + + + + Creates the 'value' for the actor claim: { actor, 'value' } + + as actor. + representing the actor. + If is not null: +   if 'type' is 'string', return as string. +   if 'type' is 'BootstrapContext' and 'BootstrapContext.SecurityToken' is 'JwtSecurityToken' +     if 'JwtSecurityToken.RawData' != null, return RawData. +     else return . +   if 'BootstrapContext.Token' != null, return 'Token'. + default: new ( ( actor.Claims ). + + 'actor' is null. + + + + Determines if the audiences found in a are valid. + + The audiences found in the . + The being validated. + required for validation. + see for additional details. + + + + Validates the lifetime of a . + + The value of the 'nbf' claim if it exists in the 'jwt'. + The value of the 'exp' claim if it exists in the 'jwt'. + The being validated. + required for validation. + for additional details. + + + + Determines if an issuer found in a is valid. + + The issuer to validate + The that is being validated. + required for validation. + The issuer to use when creating the (s) in the . + for additional details. + + + + Returns a to use when validating the signature of a token. + + the representation of the token that is being validated. + the that is being validated. + the found in the token. + A required for validation. + Returns a to use for signature validation. + if 'keyIdentifier' is null. + if 'validationParameters' is null. + If key fails to resolve, then null is returned + + + + Validates the is an expected value. + + The that signed the . + The to validate. + the current . + If the is a then the X509Certificate2 will be validated using . + + + Gets or sets the used to map Inbound Cryptographic Algorithms. + Strings that describe Cryptographic Algorithms that are understood by the runtime are not necessarily the same values used in the JsonWebToken specification. + When a signature is validated, the algorithm is obtained from the HeaderParameter { alg, 'value' }. + The 'value' is translated according to this mapping and the translated 'value' is used when performing cryptographic operations. + Default mapping is: +     RS256 => http://www.w3.org/2001/04/xmldsig-more#rsa-sha256 +     HS256 => http://www.w3.org/2001/04/xmldsig-more#hmac-sha256 + + 'value' is null. + + + Gets or sets the used to map Outbound Cryptographic Algorithms. + Strings that describe Cryptographic Algorithms understood by the runtime are not necessarily the same in the JsonWebToken specification. + This property contains mappings the will be used to when creating a and setting the HeaderParameter { alg, 'value' }. + The 'value' set is translated according to this mapping. + + Default mapping is: +     http://www.w3.org/2001/04/xmldsig-more#rsa-sha256 => RS256 +     http://www.w3.org/2001/04/xmldsig-more#hmac-sha256 => HS256 + + 'value' is null. + + + + Gets or sets the that is used when setting the for claims in the extracted when validating a . + The is set to the JSON claim 'name' after translating using this mapping. + + 'value is null. + + + + Gets or sets the that is used when creating a from (s). + The JSON claim 'name' value is set to after translating using this mapping. + + This mapping is applied only when using or . Adding values directly will not result in translation. + 'value is null. + + + Gets or sets the used to filter claims when populating a claims form a . + When a is validated, claims with types found in this will not be added to the . + 'value' is null. + + + + Gets or sets the property name of the will contain the original JSON claim 'name' if a mapping occurred when the (s) were created. + See for more information. + + if .IsIsNullOrWhiteSpace('value') is true. + + + + Gets or sets the property name of the will contain .Net type that was recogninzed when JwtPayload.Claims serialized the value to JSON. + See for more information. + + if .IsIsNullOrWhiteSpace('value') is true. + + + + Returns 'true' which indicates this instance can validate a . + + + + + Returns 'true', which indicates this instance can write . + + + + + Gets and sets the token lifetime in minutes. + + 'value' less than 1. + + + + Gets and sets the maximum size in bytes, that a will be processed. + + 'value' less than 1. + + + + Gets or sets the for creating (s). + + This extensibility point can be used to insert custom (s). + is called to obtain a (s) when needed. + 'value' is null. + + + + Gets the supported by this handler. + + + + + represents a collection of named sets of (s) that can be matched by a + and return a that contains (s). + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class. + Populates this instance with a named collection of (s) and an optional that will be called when a + or cannot be resolved. + + + A named collection of (s). + + + A to call when resolving fails, before calling base. + + + if 'keys' is null an empty collection will be created. A named collection of (s) can be added by accessing the property . + + + + + Populates the from xml. + + xml for processing. + 'nodeList' is null. + Only (s) with == 'securityKey' will be processed. Unprocessed nodes will added to a list and can be accessed using the property. + + + + When processing xml in each that has = "securityKey' is passed here for processing. + + contains xml to map to a named . + + A single is expected with up to three attributes: {'expected values'}. + <securityKey +     symmetricKey {required} +     name {required} +     EncodingType or encodingType {optional} + > + </securityKey> + If "EncodingType' type is specified only: +     'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary' +     'Base64Binary' +     'base64Binary' + are allowed and have the same meaning. + When a symmetricKey is found, Convert.FromBase64String( value ) is applied to create the key. + + 'element' is null. + attribute 'symmetricKey' is not found. + value of 'symmetricKey' is empty or whitespace. + attribute 'name' is not found. + value of 'name' is empty or whitespace. + value of 'encodingType' is not valid. + + + + Finds the first in a named collection that match the . + + + The to resolve to a + + + The resolved . + + + If there is no match, then and 'base' are called in order. + + + true if key resolved, false otherwise. + + + + + Finds a named collection of (s) that match the and returns a that contains the (s). + + The to resolve to a + The resolved . + + + A can contain multiple (s). This method will return the named collection that matches the first + + + If there is no match, then and 'base' are called in order. + + + + true is the keyIdentifier is resolved, false otherwise. + + + + + Finds a named collection of (s) that match the and returns a that contains the (s). + + The to resolve to a + The resolved . + If there is no match, then and 'base' are called in order. + true if token was resolved. + if 'keyIdentifierClause' is null. + + + + Gets the named collection of (s). + + + + + Gets or sets the to call when or fails to resolve, before calling base. + + 'value' is null. + 'object.ReferenceEquals( this, value)' is true. + + + + Gets the unprocessed (s) from . + + processes only (s) that have the == 'securityKey'. Unprocessed (s) are accessible here. + + + + A that can be used to match . + + + + + Initializes a new instance of the class. The 'name' for matching key identifiers found in the securityToken. + + Used to identify a named collection of keys. + Additional information for matching. + if 'name' is null or whitespace. + if 'id' is null or whitespace + + + + Determines if a matches this instance. + + The to match. + true if: +     1. keyIdentifierClause is a . +     2. string.Equals( keyIdentifierClause.Name, this.Name, StringComparison.Ordinal). +     2. string.Equals( keyIdentifierClause.Id, this.Id, StringComparison.Ordinal). + Otherwise calls base.Matches( keyIdentifierClause ). + + 'keyIdentifierClause' is null. + + + + Gets the name of the (s) this represents. + + + + + A that contains multiple that have a name. + + + + + Initializes a new instance of the class that contains a single . + + A name for the . + the identifier for this token. + A + if 'name' is null or whitespace. + if 'id' is null or whitespace. + if 'key' is null. + + + + Initializes a new instance of the class that contains a (System.IdentityModel.Tokens.SecurityKey) that can be matched by name. + + the identifier for this token. + A name for the (System.IdentityModel.Tokens.SecurityKey). + A collection of + if 'name' is null or whitespace. + if 'id' is null or whitespace. + if 'keys' is null. + + + + Gets the first that matches a + + the to match. + The first that matches the . + null if there is no match. + Only are matched. + 'keyIdentifierClause' is null. + + + + Answers if the is a match. + + The + true if matched. + A successful match occurs when == . + Only are matched. + 'keyIdentifierClause' is null. + + + + Gets the id of the security token. + + + + + Gets the Name of the security token. + + + + + Gets the creation time as a . + + The default is: . + + + + Gets the expiration time as a + + The default is: . + + + + Gets the (s). + + + + + This exception is thrown when 'audience' of a token was not valid. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class. + + Addtional information to be included in the exception and displayed to user. + + + + Initializes a new instance of the class. + + Addtional information to be included in the exception and displayed to user. + A that represents the root cause of the exception. + + + + Initializes a new instance of the class. + + the that holds the serialized object data. + The contextual information about the source or destination. + + + + This exception is thrown when 'issuer' of a token was not valid. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class. + + Addtional information to be included in the exception and displayed to user. + + + + Initializes a new instance of the class. + + Addtional information to be included in the exception and displayed to user. + A that represents the root cause of the exception. + + + + Initializes a new instance of the class. + + the that holds the serialized object data. + The contextual information about the source or destination. + + + + This exception is thrown when 'lifetime' of a token was not valid. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class. + + Addtional information to be included in the exception and displayed to user. + + + + Initializes a new instance of the class. + + Addtional information to be included in the exception and displayed to user. + A that represents the root cause of the exception. + + + + Initializes a new instance of the class. + + the that holds the serialized object data. + The contextual information about the source or destination. + + + + This exception is thrown when a security is missing an ExpirationTime. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class. + + Addtional information to be included in the exception and displayed to user. + + + + Initializes a new instance of the class. + + Addtional information to be included in the exception and displayed to user. + A that represents the root cause of the exception. + + + + Initializes a new instance of the class. + + the that holds the serialized object data. + The contextual information about the source or destination. + + + + This exception is thrown when an add to the TokenReplayCache fails. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class. + + Addtional information to be included in the exception and displayed to user. + + + + Initializes a new instance of the class. + + Addtional information to be included in the exception and displayed to user. + A that represents the root cause of the exception. + + + + Initializes a new instance of the class. + + the that holds the serialized object data. + The contextual information about the source or destination. + + + + This exception is thrown when a security token contained a key identifier but the key was not found by the runtime. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class. + + Addtional information to be included in the exception and displayed to user. + + + + Initializes a new instance of the class. + + Addtional information to be included in the exception and displayed to user. + A that represents the root cause of the exception. + + + + Initializes a new instance of the class. + + the that holds the serialized object data. + The contextual information about the source or destination. + + + + Creates s by specifying a and algorithm. + Supports both and . + + + + + This is the minimum .KeySize when creating signatures. + + + + + This is the minimum .KeySize when verifying signatures. + + + + + This is the minimum .KeySize when creating and verifying signatures. + + + + + Creates a that supports the and algorithm. + + + The to use for signing. + + + The algorithm to use for signing. + + + 'key' is null. + + + 'algorithm' is null. + + + 'algorithm' contains only whitespace. + + + '' is smaller than . + + + '' is smaller than . + + + '' is not a or a . + + + AsymmetricSignatureProviders require access to a PrivateKey for Signing. + + + The . + + + + + Returns a instance supports the and algorithm. + + + The to use for signing. + + + The algorithm to use for signing. + + + 'key' is null. + + + 'algorithm' is null. + + + 'algorithm' contains only whitespace. + + + '' is smaller than . + + + '' is smaller than . + + + '' is not a or a . + + + The . + + + + + When finished with a call this method for cleanup. The default behavior is to call + + to be released. + + + + Gets or sets the minimum .KeySize"/>. + + 'value' is smaller than . + + + + Gets or sets the minimum .KeySize for creating signatures. + + 'value' is smaller than . + + + + Gets or sets the minimum .KeySize for verifying signatures. + 'value' is smaller than . + + + + + Provides signing and verifying operations using a and specifying an algorithm. + + + + + Initializes a new instance of the class that uses an to create and / or verify signatures over a array of bytes. + + The used for signing. + The signature algorithm to use. + 'key' is null. + 'algorithm' is null. + 'algorithm' contains only whitespace. + '.KeySize' is smaller than . + throws. + returns null. + throws. + + + + Produces a signature over the 'input' using the and 'algorithm' passed to . + + bytes to sign. + signed bytes + 'input' is null. + 'input.Length' == 0. + has been called. + is null. This can occur if a derived type deletes it or does not create it. + + + + Verifies that a signature created over the 'input' matches the signature. Using and 'algorithm' passed to . + + bytes to verify. + signature to compare against. + true if computed signature matches the signature parameter, false otherwise. + 'input' is null. + 'signature' is null. + 'input.Length' == 0. + 'signature.Length' == 0. + has been called. + if the internal is null. This can occur if a derived type deletes it or does not create it. + + + + Disposes of internal components. + + true, if called from Dispose(), false, if invoked inside a finalizer. + + + + Compares two byte arrays for equality. Hash size is fixed normally it is 32 bytes. + The attempt here is to take the same time if an attacker shortens the signature OR changes some of the signed contents. + + + One set of bytes to compare. + + + The other set of bytes to compare with. + + + true if the bytes are equal, false otherwise. + + + + + Definition for AudienceValidator. + + The audiences found in the . + The being validated. + required for validation. + + + + Definition for IssuerSigningKeyRetriever. When validating signatures, this method will return key to use. + + the representation of the token that is being validated. + the that is being validated. It may be null. + the found in the token. It may be null. + required for validation. + + + + + Definition for IssuerValidator. + + The issuer to validate. + The that is being validated. + required for validation. + The issuer to use when creating the "Claim"(s) in a "ClaimsIdentity". + + + + Definition for LifetimeValidator. + + The 'notBefore' time found in the . + The 'expiration' time found in the . + The being validated. + required for validation. + + + + Contains a set of parameters that are used by a when validating a . + + + + + Default for the maximm token size. + + 2 MB (mega bytes). + + + + This is the fallback authenticationtype that a will use if nothing is set. + + + + + Default for the clock skew. + + 300 seconds (5 minutes). + + + + Copy constructor for . + + + + + Initializes a new instance of the class. + + + + + Returns a new instance of with values copied from this object. + + A new object copied from this object + This is a shallow Clone. + + + + Creates a using: + + 'NameClaimType' is calculated: If NameClaimTypeRetriever call that else use NameClaimType. If the result is a null or empty string, use . + 'RoleClaimType' is calculated: If RoleClaimTypeRetriever call that else use RoleClaimType. If the result is a null or empty string, use . + + A with Authentication, NameClaimType and RoleClaimType set. + + + + Gets or sets a delegate that will be used to validate the audience of the tokens + + + + + Gets or sets the AuthenticationType when creating a during token validation. + + if 'value' is null or whitespace. + + + + Gets or sets the for validating X509Certificate2(s). + + + + + Gets or sets the that is to be used for decrypting inbound tokens. + + if 'value' is null. + + + + Gets or sets the clock skew to apply when validating times + + if 'value' is less than 0. + + + + Gets or sets the that is to be used for validating signed tokens. + + + + + Gets or sets the that is to be used for validating signed tokens. + + + + + Gets or sets a delegate that will be used to retreive (s) used for checking signatures. + + Each will be used to check the signature. Returning multiple key can be helpful when the does not contain a key identifier. + This can occur when the issuer has multiple keys available. This sometimes occurs during key rollover. + + + + Gets or sets the that are to be used for validating signed tokens. + + + + + Gets or sets the that is used for validating signed tokens. + + + + + Gets or sets the that are to be used for validating signed tokens. + + + + + Gets or sets a delegate that will be used to validate the issuer of the token. The delegate returns the issuer to use. + + + + + Gets or sets a delegate that will be used to validate the lifetime of the token + + + + + Gets or sets the passed to . + + + Controls the value returns. It will return the first where the equals . + + + + + Gets or sets the passed to . + + + Controls the (s) returned from . + Each returned will have a equal to . + + + + + Gets or sets a delegate that will be called to obtain the NameClaimType to use when creating a ClaimsIdentity + when validating a token. + + + + + Gets or sets a value indicating whether tokens must have an 'expiration' value. + + + + + Gets or sets a value indicating whether a can be valid if not signed. + + + + + Gets or sets a delegate that will be called to obtain the RoleClaimType to use when creating a ClaimsIdentity + when validating a token. + + + + + Gets or sets a boolean to control if the original token is saved when a session is created. /// + The SecurityTokenValidator will use this value to save the orginal string that was validated. + + + + Gets or set the that will be checked to help in detecting that a token has been 'seen' before. + + + + + Gets or sets a value indicating whether the should be validated. + + + + + Gets or sets a boolean to control if the audience will be validated during token validation. + + + + + Gets or sets a boolean to control if the issuer will be validated during token validation. + + + + + Gets or sets a boolean to control if the lifetime will be validated during token validation. + + + + + Gets or sets a boolean that controls if validation of the that signed the securityToken is called. + + + + + Gets or sets a string that represents a valid audience that will be used during token validation. + + + + + Gets or sets the that contains valid audiences that will be used during token validation. + + + + + Gets or sets a that represents a valid issuer that will be used during token validation. + + + + + Gets or sets the that contains valid issuers that will be used during token validation. + + + + + AudienceValidator + + + + + Determines if the audiences found in a are valid. + + The audiences found in the . + The being validated. + required for validation. + if 'vaidationParameters' is null. + if 'audiences' is null and is true. + if is null or whitespace and is null. + if none of the 'audiences' matched either or one of . + An EXACT match is required. + + + + Determines if an issuer found in a is valid. + + The issuer to validate + The that is being validated. + required for validation. + The issuer to use when creating the "Claim"(s) in a "ClaimsIdentity". + if 'vaidationParameters' is null. + if 'issuer' is null or whitespace and is true. + if is null or whitespace and is null. + if 'issuer' failed to matched either or one of . + An EXACT match is required. + + + + Validates the that signed a . + + The that signed the . + The being validated. + required for validation. + if 'vaidationParameters' is null. + + + + Validates the lifetime of a . + + The 'notBefore' time found in the . + The 'expiration' time found in the . + The being validated. + required for validation. + if 'vaidationParameters' is null. + if 'expires.HasValue' is false and is true. + if 'notBefore' is > 'expires'. + if 'notBefore' is > DateTime.UtcNow. + if 'expires' is < DateTime.UtcNow. + All time comparisons apply . + + + + Validates if a token has been replayed. + + The being validated. + When does the security token expire. + required for validation. + if 'securityToken' is null or whitespace. + if 'validationParameters' is null or whitespace. + if is not null and expirationTime.HasValue is false. When a TokenReplayCache is set, tokens require an expiration time. + if the 'securityToken' is found in the cache. + if the 'securityToken' could not be added to the . + + + + Defines constants needed from WS-Security 1.0. + + + + + Defines constants needed from WS-SecureUtility standard schema. + + + + + This class also resets the chainPolicy.VerificationTime = DateTime.Now each time a certificate is validated otherwise certificates created after the validator is created will not chain. + + + + + Initializes a new instance of the class. + + + The certificate validation mode. + + + The revocation mode. + + + The trusted store location. + + thrown if the certificationValidationMode is custom or unknown. + + + + + Validates a . + + + The to validate. + + + + + Security key that allows access to cert + + + + + Instantiates a using a + + cert to use. + + + + Gets the . + + + + diff --git a/App/packages/System.IdentityModel.Tokens.Jwt.4.0.2.206221351/lib/net45/System.IdentityModel.Tokens.Jwt.dll b/App/packages/System.IdentityModel.Tokens.Jwt.4.0.2.206221351/lib/net45/System.IdentityModel.Tokens.Jwt.dll new file mode 100644 index 0000000000000000000000000000000000000000..384dfaf1beda25b0817f3a853e27bcab44748c25 GIT binary patch literal 136448 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

    ^ksm7blO08 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 GG5`RtmxJX1 literal 0 HcmV?d00001 diff --git a/Migrations/055 - Make UserOpenIds generic.sql b/Migrations/055 - Make UserOpenIds generic.sql index 133191f2..4d867fa1 100644 --- a/Migrations/055 - Make UserOpenIds generic.sql +++ b/Migrations/055 - Make UserOpenIds generic.sql @@ -26,6 +26,13 @@ END GO +IF dbo.fnColumnExists('UserAuthClaims', 'Display') = 0 +BEGIN + ALTER TABLE UserAuthClaims ADD Display NVARCHAR(150) +END + +GO + IF dbo.fnIndexExists('UserAuthClaims', 'ClaimIdentifierIdx') = 0 BEGIN ALTER TABLE UserAuthClaims ALTER COLUMN ClaimIdentifier NVARCHAR(449) NOT NULL From 5160eafd74433996197fab18a9af4c1c375435a9 Mon Sep 17 00:00:00 2001 From: Tim Stone Date: Sun, 30 Aug 2015 21:10:56 -0400 Subject: [PATCH 4/5] Prevent #tabs from being duplicated as an ID --- App/StackExchange.DataExplorer/Content/header.css | 8 ++++---- .../Views/Shared/SubHeader.cshtml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/App/StackExchange.DataExplorer/Content/header.css b/App/StackExchange.DataExplorer/Content/header.css index 537fb559..8047c7db 100644 --- a/App/StackExchange.DataExplorer/Content/header.css +++ b/App/StackExchange.DataExplorer/Content/header.css @@ -130,7 +130,7 @@ nav.primary .site-selector-popup .ac_results li.ac_over { margin-bottom: 0; } -#tabs { +.nav-tabs { float: right; } @@ -138,7 +138,7 @@ nav.primary .site-selector-popup .ac_results li.ac_over { margin-left: 5px; } -#tabs a, .miniTabs a { +.nav-tabs a, .miniTabs a { background:none repeat scroll 0 0 #fff; border: 1px solid #fff; color: #777; @@ -152,7 +152,7 @@ nav.primary .site-selector-popup .ac_results li.ac_over { text-decoration: none; } -#tabs a:hover, .miniTabs a:hover { +.nav-tabs a:hover, .miniTabs a:hover { background: none repeat scroll 0 0 #FFFFFF; border-color: #CCC #CCC #FFFFFF; border-style: solid; @@ -161,7 +161,7 @@ nav.primary .site-selector-popup .ac_results li.ac_over { margin-top: 9px; } -#tabs a.youarehere, .miniTabs a.youarehere { +.nav-tabs a.youarehere, .miniTabs a.youarehere { background: none repeat scroll 0 0 #FFFFFF; border-color: #CCC #CCC #FFFFFF; border-style: solid; diff --git a/App/StackExchange.DataExplorer/Views/Shared/SubHeader.cshtml b/App/StackExchange.DataExplorer/Views/Shared/SubHeader.cshtml index 1ab054dd..fcba7810 100644 --- a/App/StackExchange.DataExplorer/Views/Shared/SubHeader.cshtml +++ b/App/StackExchange.DataExplorer/Views/Shared/SubHeader.cshtml @@ -9,7 +9,7 @@ } @if (Model.Items != null) { -

    +