From b94108b7aad1842c8928df5f82427da86db741c0 Mon Sep 17 00:00:00 2001 From: Szymon Gaertig Date: Wed, 7 Sep 2016 14:54:12 +0200 Subject: [PATCH 1/2] passing claims to the token_revoked_details --- .../Connect/RevocationEndpointController.cs | 12 +++-- .../Authentication/TokenRevokedDetails.cs | 10 ++++ .../Extensions/IEventServiceExtensions.cs | 50 +++++++++++-------- source/Tests/UnitTests/Core.Tests.csproj | 9 ++++ .../Events/TokenRevokedDetailsTests.cs | 45 +++++++++++++++++ 5 files changed, 99 insertions(+), 27 deletions(-) create mode 100644 source/Tests/UnitTests/Events/TokenRevokedDetailsTests.cs diff --git a/source/Core/Endpoints/Connect/RevocationEndpointController.cs b/source/Core/Endpoints/Connect/RevocationEndpointController.cs index d3a7694d5..cb823cf77 100644 --- a/source/Core/Endpoints/Connect/RevocationEndpointController.cs +++ b/source/Core/Endpoints/Connect/RevocationEndpointController.cs @@ -24,7 +24,9 @@ using IdentityServer3.Core.Services; using IdentityServer3.Core.Validation; using System.Collections.Specialized; +using System.Linq; using System.Net.Http; +using System.Security.Claims; using System.Threading.Tasks; using System.Web.Http; @@ -37,7 +39,7 @@ namespace IdentityServer3.Core.Endpoints internal class RevocationEndpointController : ApiController { private static readonly ILog Logger = LogProvider.GetCurrentClassLogger(); - + private readonly IEventService _events; private readonly ClientSecretValidator _clientValidator; private readonly IdentityServerOptions _options; @@ -120,13 +122,13 @@ public async Task ProcessAsync(Client client, NameValueCollec private async Task RevokeAccessTokenAsync(string handle, Client client) { var token = await _tokenHandles.GetAsync(handle); - + if (token != null) { if (token.ClientId == client.ClientId) { await _tokenHandles.RemoveAsync(handle); - await _events.RaiseTokenRevokedEventAsync(token.SubjectId, handle, Constants.TokenTypeHints.AccessToken); + await _events.RaiseTokenRevokedEventAsync(token.Claims, token.SubjectId, handle, Constants.TokenTypeHints.AccessToken); } else { @@ -153,12 +155,12 @@ private async Task RevokeRefreshTokenAsync(string handle, Client client) { await _refreshTokens.RevokeAsync(token.SubjectId, token.ClientId); await _tokenHandles.RevokeAsync(token.SubjectId, token.ClientId); - await _events.RaiseTokenRevokedEventAsync(token.SubjectId, handle, Constants.TokenTypeHints.RefreshToken); + await _events.RaiseTokenRevokedEventAsync(token.Subject.Claims.ToList(), token.SubjectId, handle, Constants.TokenTypeHints.RefreshToken); } else { var message = string.Format("Client {0} tried to revoke a refresh token belonging to a different client: {1}", client.ClientId, token.ClientId); - + Logger.Warn(message); await RaiseFailureEventAsync(message); } diff --git a/source/Core/Events/Authentication/TokenRevokedDetails.cs b/source/Core/Events/Authentication/TokenRevokedDetails.cs index e1e03fa3a..3eac019e5 100644 --- a/source/Core/Events/Authentication/TokenRevokedDetails.cs +++ b/source/Core/Events/Authentication/TokenRevokedDetails.cs @@ -14,6 +14,7 @@ * limitations under the License. */ +using System.Collections.Generic; using IdentityServer3.Core.Models; namespace IdentityServer3.Core.Events @@ -44,5 +45,14 @@ public class TokenRevokedDetails /// /// public string SubjectId { get; set; } + + + /// + /// Gets or sets the claims. + /// + /// + /// The claims. + /// + public Dictionary Claims { get; set; } } } \ No newline at end of file diff --git a/source/Core/Extensions/IEventServiceExtensions.cs b/source/Core/Extensions/IEventServiceExtensions.cs index 88371506e..c0d5124a5 100644 --- a/source/Core/Extensions/IEventServiceExtensions.cs +++ b/source/Core/Extensions/IEventServiceExtensions.cs @@ -18,6 +18,7 @@ using IdentityServer3.Core.Models; using IdentityServer3.Core.Services; using System; +using System.Collections.Generic; using System.Security.Claims; using System.Security.Cryptography.X509Certificates; using System.Threading.Tasks; @@ -26,16 +27,17 @@ namespace IdentityServer3.Core.Extensions { internal static class IEventServiceExtensions { - public static async Task RaisePreLoginSuccessEventAsync(this IEventService events, + public static async Task RaisePreLoginSuccessEventAsync(this IEventService events, string signInMessageId, SignInMessage signInMessage, AuthenticateResult authResult) { var evt = new Event( EventConstants.Categories.Authentication, Resources.Events.PreLoginSuccess, - EventTypes.Success, + EventTypes.Success, EventConstants.Ids.PreLoginSuccess, - new LoginDetails { - SubjectId = authResult.HasSubject ? authResult.User.GetSubjectId() : null, + new LoginDetails + { + SubjectId = authResult.HasSubject ? authResult.User.GetSubjectId() : null, Name = authResult.User.Identity.Name, SignInId = signInMessageId, SignInMessage = signInMessage, @@ -45,7 +47,7 @@ public static async Task RaisePreLoginSuccessEventAsync(this IEventService event await events.RaiseEventAsync(evt); } - public static async Task RaisePreLoginFailureEventAsync(this IEventService events, + public static async Task RaisePreLoginFailureEventAsync(this IEventService events, string signInMessageId, SignInMessage signInMessage, string error) { var evt = new Event( @@ -57,13 +59,13 @@ public static async Task RaisePreLoginFailureEventAsync(this IEventService event { SignInId = signInMessageId, SignInMessage = signInMessage, - }, + }, error); await events.RaiseEventAsync(evt); } - public static async Task RaiseLocalLoginSuccessEventAsync(this IEventService events, + public static async Task RaiseLocalLoginSuccessEventAsync(this IEventService events, string username, string signInMessageId, SignInMessage signInMessage, AuthenticateResult authResult) { var evt = new Event( @@ -84,7 +86,7 @@ public static async Task RaiseLocalLoginSuccessEventAsync(this IEventService eve await events.RaiseEventAsync(evt); } - public static async Task RaiseLocalLoginFailureEventAsync(this IEventService events, + public static async Task RaiseLocalLoginFailureEventAsync(this IEventService events, string username, string signInMessageId, SignInMessage signInMessage, string error) { var evt = new Event( @@ -97,13 +99,13 @@ public static async Task RaiseLocalLoginFailureEventAsync(this IEventService eve SignInId = signInMessageId, SignInMessage = signInMessage, LoginUserName = username - }, + }, error); await events.RaiseEventAsync(evt); } - public static async Task RaiseExternalLoginSuccessEventAsync(this IEventService events, + public static async Task RaiseExternalLoginSuccessEventAsync(this IEventService events, ExternalIdentity externalIdentity, string signInMessageId, SignInMessage signInMessage, AuthenticateResult authResult) { var evt = new Event( @@ -125,7 +127,7 @@ public static async Task RaiseExternalLoginSuccessEventAsync(this IEventService await events.RaiseEventAsync(evt); } - public static async Task RaiseExternalLoginFailureEventAsync(this IEventService events, + public static async Task RaiseExternalLoginFailureEventAsync(this IEventService events, ExternalIdentity externalIdentity, string signInMessageId, SignInMessage signInMessage, string error) { var evt = new Event( @@ -139,7 +141,7 @@ public static async Task RaiseExternalLoginFailureEventAsync(this IEventService SignInMessage = signInMessage, Provider = externalIdentity.Provider, ProviderId = externalIdentity.ProviderId, - }, + }, error); await events.RaiseEventAsync(evt); @@ -157,7 +159,7 @@ public static async Task RaiseExternalLoginErrorEventAsync(this IEventService ev await events.RaiseEventAsync(evt); } - public static async Task RaiseSuccessfulResourceOwnerFlowAuthenticationEventAsync(this IEventService events, + public static async Task RaiseSuccessfulResourceOwnerFlowAuthenticationEventAsync(this IEventService events, string userName, string subjectId, SignInMessage message) { var evt = new Event( @@ -175,7 +177,7 @@ public static async Task RaiseSuccessfulResourceOwnerFlowAuthenticationEventAsyn await events.RaiseEventAsync(evt); } - public static async Task RaiseFailedResourceOwnerFlowAuthenticationEventAsync(this IEventService events, + public static async Task RaiseFailedResourceOwnerFlowAuthenticationEventAsync(this IEventService events, string userName, SignInMessage message, string error) { var evt = new Event( @@ -193,7 +195,7 @@ public static async Task RaiseFailedResourceOwnerFlowAuthenticationEventAsync(th await events.RaiseEventAsync(evt); } - public static async Task RaisePartialLoginCompleteEventAsync(this IEventService events, + public static async Task RaisePartialLoginCompleteEventAsync(this IEventService events, ClaimsIdentity subject, string signInMessageId, SignInMessage signInMessage) { var evt = new Event( @@ -212,7 +214,7 @@ public static async Task RaisePartialLoginCompleteEventAsync(this IEventService await events.RaiseEventAsync(evt); } - public static async Task RaiseLogoutEventAsync(this IEventService events, + public static async Task RaiseLogoutEventAsync(this IEventService events, ClaimsPrincipal subject, string signOutId, SignOutMessage signOutMessage) { var evt = new Event( @@ -239,7 +241,8 @@ public static async Task RaiseCspReportEventAsync(this IEventService events, str EventTypes.Information, EventConstants.Ids.CspReport); - evt.DetailsFunc = () => { + evt.DetailsFunc = () => + { string subject = null; string name = null; if (user != null && user.Identity.IsAuthenticated) @@ -253,7 +256,7 @@ public static async Task RaiseCspReportEventAsync(this IEventService events, str { reportData = Newtonsoft.Json.JsonConvert.DeserializeObject(report); } - catch(Newtonsoft.Json.JsonReaderException) + catch (Newtonsoft.Json.JsonReaderException) { reportData = "Error reading CSP report JSON"; evt.Message = "Raw Report Data: " + report; @@ -406,7 +409,9 @@ public static async Task RaiseSuccessfulRefreshTokenRefreshEventAsync(this IEven await events.RaiseEventAsync(evt); } - public static async Task RaiseTokenRevokedEventAsync(this IEventService events, string subjectId, string token, string tokenType) + public static async Task RaiseTokenRevokedEventAsync(this IEventService events, + List claims, + string subjectId, string handle, string tokenType) { var evt = new Event( EventConstants.Categories.Authentication, @@ -416,8 +421,9 @@ public static async Task RaiseTokenRevokedEventAsync(this IEventService events, new TokenRevokedDetails() { SubjectId = subjectId, - Token = ObfuscateToken(token), - TokenType = tokenType + Token = ObfuscateToken(handle), + TokenType = tokenType, + Claims = claims.ToClaimsDictionary() }); await events.RaiseEventAsync(evt); @@ -429,7 +435,7 @@ public static async Task RaiseUnhandledExceptionEventAsync(this IEventService ev EventConstants.Categories.InternalError, "Unhandled exception", EventTypes.Error, - EventConstants.Ids.UnhandledExceptionError, + EventConstants.Ids.UnhandledExceptionError, exception.ToString()); await events.RaiseEventAsync(evt); diff --git a/source/Tests/UnitTests/Core.Tests.csproj b/source/Tests/UnitTests/Core.Tests.csproj index 2b0d361e5..39b9348c5 100644 --- a/source/Tests/UnitTests/Core.Tests.csproj +++ b/source/Tests/UnitTests/Core.Tests.csproj @@ -195,6 +195,15 @@ +<<<<<<< Updated upstream +======= + + + + + + +>>>>>>> Stashed changes diff --git a/source/Tests/UnitTests/Events/TokenRevokedDetailsTests.cs b/source/Tests/UnitTests/Events/TokenRevokedDetailsTests.cs new file mode 100644 index 000000000..104529b57 --- /dev/null +++ b/source/Tests/UnitTests/Events/TokenRevokedDetailsTests.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Claims; +using System.Text; +using System.Threading.Tasks; +using IdentityServer3.Core.Events; +using IdentityServer3.Core.Extensions; +using IdentityServer3.Core.Models; +using IdentityServer3.Core.Services; +using Moq; +using Xunit; + +namespace IdentityServer3.Tests.Events +{ + public class TokenRevokedDetailsTests + { + [Fact] + public async Task When_claims_are_provided_then_create_event_with_given_claims() + { + // Given + var handle = "handle"; + var subjectId = "subjectId"; + + var claims = new List() + { + new Claim("claim_type_1", "claims_1_value"), + new Claim("claim_type_2", "claims_2_value") + }; + + var eventServiceMock = new Mock(); + + // When + await eventServiceMock.Object.RaiseTokenRevokedEventAsync(claims, subjectId, handle, "access_token"); + + // Then + eventServiceMock.Verify( + x => x.RaiseAsync( + It.Is>(rt + => rt.Details.Claims.ContainsKey("claim_type_1") + && rt.Details.Claims.ContainsKey("claim_type_2") + && rt.Details.Claims.Count == 2))); + } + } +} From 8c1cab41d6579b5c12ac0d6d79490367764394aa Mon Sep 17 00:00:00 2001 From: Szymon Gaertig Date: Wed, 7 Sep 2016 15:05:16 +0200 Subject: [PATCH 2/2] merge fix --- source/Tests/UnitTests/Core.Tests.csproj | 9 --------- 1 file changed, 9 deletions(-) diff --git a/source/Tests/UnitTests/Core.Tests.csproj b/source/Tests/UnitTests/Core.Tests.csproj index 39b9348c5..2b0d361e5 100644 --- a/source/Tests/UnitTests/Core.Tests.csproj +++ b/source/Tests/UnitTests/Core.Tests.csproj @@ -195,15 +195,6 @@ -<<<<<<< Updated upstream -======= - - - - - - ->>>>>>> Stashed changes