Skip to content
This repository has been archived by the owner on Jul 31, 2024. It is now read-only.

Commit

Permalink
Fix custom redirect after ProcessLogin for custom authorize response …
Browse files Browse the repository at this point in the history
…generators (#4615)

* fix missing check for redirect

* NS cleanup

* fix prompt=none and consent return
  • Loading branch information
brockallen committed Jul 3, 2020
1 parent 0c05323 commit 9e0b0cd
Show file tree
Hide file tree
Showing 5 changed files with 183 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -92,24 +92,24 @@ public virtual async Task<InteractionResponse> ProcessInteractionAsync(Validated
}

var result = await ProcessLoginAsync(request);

if (!result.IsLogin && !result.IsError && !result.IsRedirect)
{
result = await ProcessConsentAsync(request, consent);
}

if (result.IsLogin && request.PromptModes.Contains(OidcConstants.PromptModes.None))
if ((result.IsLogin || result.IsConsent || result.IsRedirect) && request.PromptModes.Contains(OidcConstants.PromptModes.None))
{
// prompt=none means do not show the UI
Logger.LogInformation("Changing response to LoginRequired: prompt=none was requested");
result = new InteractionResponse
{
Error = OidcConstants.AuthorizeErrors.LoginRequired
Error = result.IsLogin ? OidcConstants.AuthorizeErrors.LoginRequired :
result.IsConsent ? OidcConstants.AuthorizeErrors.ConsentRequired :
OidcConstants.AuthorizeErrors.InteractionRequired
};
}

if (result.IsLogin || result.IsError)
{
return result;
}

result = await ProcessConsentAsync(request, consent);

return result;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Threading.Tasks;
using FluentAssertions;
using IdentityModel;
using IdentityServer.UnitTests.Common;
using IdentityServer4;
using IdentityServer4.Configuration;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.


using System.Threading.Tasks;
using FluentAssertions;
using IdentityServer.UnitTests.Common;
using IdentityServer4;
using IdentityServer4.Configuration;
using IdentityServer4.Models;
using IdentityServer4.ResponseHandling;
using IdentityServer4.Services;
using IdentityServer4.Validation;
using Microsoft.AspNetCore.Authentication;
using Microsoft.Extensions.Logging;
using Xunit;
using static IdentityModel.OidcConstants;

namespace IdentityServer.UnitTests.ResponseHandling.AuthorizeInteractionResponseGenerator
{
public class CustomAuthorizeInteractionResponseGenerator : IdentityServer4.ResponseHandling.AuthorizeInteractionResponseGenerator
{
public CustomAuthorizeInteractionResponseGenerator(ISystemClock clock, ILogger<IdentityServer4.ResponseHandling.AuthorizeInteractionResponseGenerator> logger, IConsentService consent, IProfileService profile) : base(clock, logger, consent, profile)
{
}

public InteractionResponse ProcessLoginResponse { get; set; }
protected internal override Task<InteractionResponse> ProcessLoginAsync(ValidatedAuthorizeRequest request)
{
if (ProcessLoginResponse != null)
{
return Task.FromResult(ProcessLoginResponse);
}

return base.ProcessLoginAsync(request);
}

public InteractionResponse ProcessConsentResponse { get; set; }
protected internal override Task<InteractionResponse> ProcessConsentAsync(ValidatedAuthorizeRequest request, ConsentResponse consent = null)
{
if (ProcessConsentResponse != null)
{
return Task.FromResult(ProcessConsentResponse);
}
return base.ProcessConsentAsync(request, consent);
}
}

public class AuthorizeInteractionResponseGeneratorTests_Custom
{
private IdentityServerOptions _options = new IdentityServerOptions();
private CustomAuthorizeInteractionResponseGenerator _subject;
private MockConsentService _mockConsentService = new MockConsentService();
private StubClock _clock = new StubClock();

public AuthorizeInteractionResponseGeneratorTests_Custom()
{
_subject = new CustomAuthorizeInteractionResponseGenerator(
_clock,
TestLogger.Create<IdentityServer4.ResponseHandling.AuthorizeInteractionResponseGenerator>(),
_mockConsentService,
new MockProfileService());
}


[Fact]
public async Task ProcessInteractionAsync_with_overridden_login_returns_redirect_should_return_redirect()
{
var request = new ValidatedAuthorizeRequest
{
ClientId = "foo",
Subject = new IdentityServerUser("123")
{
IdentityProvider = IdentityServerConstants.LocalIdentityProvider
}.CreatePrincipal(),
Client = new Client
{
},
};

_subject.ProcessLoginResponse = new InteractionResponse
{
RedirectUrl = "/custom"
};

var result = await _subject.ProcessInteractionAsync(request);

result.IsRedirect.Should().BeTrue();
result.RedirectUrl.Should().Be("/custom");
}

[Fact]
public async Task ProcessInteractionAsync_with_prompt_none_and_login_returns_login_should_return_error()
{
var request = new ValidatedAuthorizeRequest
{
ClientId = "foo",
Subject = new IdentityServerUser("123")
{
IdentityProvider = IdentityServerConstants.LocalIdentityProvider
}.CreatePrincipal(),
Client = new Client
{
},
PromptModes = new[] { PromptModes.None },
};

_subject.ProcessLoginResponse = new InteractionResponse
{
IsLogin = true
};

var result = await _subject.ProcessInteractionAsync(request);

result.IsError.Should().BeTrue();
result.Error.Should().Be("login_required");
}

[Fact]
public async Task ProcessInteractionAsync_with_prompt_none_and_login_returns_redirect_should_return_error()
{
var request = new ValidatedAuthorizeRequest
{
ClientId = "foo",
Subject = new IdentityServerUser("123")
{
IdentityProvider = IdentityServerConstants.LocalIdentityProvider
}.CreatePrincipal(),
Client = new Client
{
},
PromptModes = new[] { PromptModes.None },
};

_subject.ProcessLoginResponse = new InteractionResponse
{
RedirectUrl = "/custom"
};

var result = await _subject.ProcessInteractionAsync(request);

result.IsError.Should().BeTrue();
result.Error.Should().Be("interaction_required");
result.RedirectUrl.Should().BeNull();
}

[Fact]
public async Task ProcessInteractionAsync_with_prompt_none_and_consent_returns_consent_should_return_error()
{
var request = new ValidatedAuthorizeRequest
{
ClientId = "foo",
Subject = new IdentityServerUser("123")
{
IdentityProvider = IdentityServerConstants.LocalIdentityProvider
}.CreatePrincipal(),
Client = new Client
{
},
PromptModes = new[] { PromptModes.None },
};

_subject.ProcessConsentResponse = new InteractionResponse
{
IsConsent = true
};

var result = await _subject.ProcessInteractionAsync(request);

result.IsError.Should().BeTrue();
result.Error.Should().Be("consent_required");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
using System.Text.Json;
using System.Threading.Tasks;
using FluentAssertions;
using IdentityModel;
using IdentityServer.UnitTests.Common;
using IdentityServer4;
using IdentityServer4.Models;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
using IdentityServer4.Extensions;
using IdentityServer4.Models;
using IdentityServer4.Stores;
using IdentityServer4.Validation;
using Xunit;

namespace IdentityServer.UnitTests.Validation
Expand Down

0 comments on commit 9e0b0cd

Please sign in to comment.