Skip to content

Commit

Permalink
Request RC-4.0.0 merging to the main branch approval (#192)
Browse files Browse the repository at this point in the history
* Expose OIDC and JWT events (#187)
* Expose OIDC events for .NET 4.x and Core MVC projects.
* Expose JWT events for .NET 4.x and Core WebApi projects.
* Expose OIDC events for .NET Core MVC projects.
* Expose JWT events for .NET Core WebApi projects.
* Add tests.
* Update readme.
  • Loading branch information
laura-rodriguez authored Dec 9, 2021
1 parent 77b3847 commit 0435a6d
Show file tree
Hide file tree
Showing 44 changed files with 1,082 additions and 260 deletions.
109 changes: 109 additions & 0 deletions MIGRATING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# Okta.AspNet SDK migration guide

This library uses semantic versioning and follows Okta's [library version policy](https://developer.okta.com/code/library-versions/). In short, we don't make breaking changes unless the major version changes!

## Migrating from Okta.AspNet 1.x to 2.x

In previous versions, the `OktaMvcOptions` exposed the `SecurityTokenValidated` and `AuthenticationFailed` events you could hook into. Starting in 2.x series, the `OktaMvcOptions` exposes the `OpenIdConnectEvents` property which allows you to hook into all the events provided by the uderlying OIDC middleware.

_Before:_

```csharp
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseOktaMvc(new OktaMvcOptions()
{
// ... other configuration options removed for brevity ...
AuthenticationFailed = OnAuthenticationFailed,
});
}

public async Task OnAuthenticationFailed(AuthenticationFailedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> notification)
{
await Task.Run(() =>
{
notification.Response.Redirect("{YOUR-EXCEPTION-HANDLING-ENDPOINT}?message=" + notification.Exception.Message);
notification.HandleResponse();
});
}
}
```

_Now:_

```csharp
app.UseOktaMvc(new OktaMvcOptions()
{
// ... other configuration options removed for brevity ...
OpenIdConnectEvents = new OpenIdConnectAuthenticationNotifications
{
AuthenticationFailed = OnAuthenticationFailed,
},
});
```
## Migrating from Okta.AspNetCore 3.x to 4.x

In previous versions, the `OktaMvcOptions` exposed the `OnTokenValidated`, `OnOktaApiFailure`, `OnUserInformationReceived` and `OnAuthenticationFailed` events you could hook into. Starting in 4.x series, the `OktaMvcOptions` exposes the `OpenIdConnectEvents` property which allows you to hook into all the events provided by the uderlying OIDC middleware.

_Before:_

```csharp
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddOktaMvc(new OktaMvcOptions
{
// ... other configuration options removed for brevity ...
OnOktaApiFailure = OnOktaApiFailure,
OnAuthenticationFailed = OnAuthenticationFailed,
});
}

public async Task OnOktaApiFailure(RemoteFailureContext context)
{
await Task.Run(() =>
{
context.Response.Redirect("{YOUR-EXCEPTION-HANDLING-ENDPOINT}?message=" + context.Failure.Message);
context.HandleResponse();
});
}

public async Task OnAuthenticationFailed(AuthenticationFailedContext context)
{
await Task.Run(() =>
{
context.Response.Redirect("{YOUR-EXCEPTION-HANDLING-ENDPOINT}?message=" + context.Exception.Message);
context.HandleResponse();
});
}
}
```

_Now:_

```csharp
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddOktaMvc(new OktaMvcOptions
{
// ... other configuration options removed for brevity ...
OpenIdConnectEvents = new OpenIdConnectEvents
{
OnAuthenticationFailed = OnAuthenticationFailed,
OnRemoteFailure = OnOktaApiFailure,
},
});
}
}
```

## Getting help

If you have questions about this library or about the Okta APIs, post a question on our [Developer Forum](https://devforum.okta.com).

If you find a bug or have a feature request for this library specifically, [post an issue](https://github.com/okta/okta-aspnet/issues) here on GitHub.
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public async Task BuildUserAgent(string frameworkName)
{
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, "http://foo.com");
var version = typeof(OktaHttpMessageHandlerShould).Assembly.GetName().Version;
var handler = new OktaHttpMessageHandler(frameworkName, version)
var handler = new OktaHttpMessageHandler(frameworkName, version, new OktaWebOptions())
{
InnerHandler = new TestHandler(),
};
Expand Down
18 changes: 18 additions & 0 deletions Okta.AspNet.Abstractions/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,24 @@
# Changelog
Running changelog of releases since `3.0.5`

## v4.0.0

### Features

- Add support for OIDC events configuration in MVC projects.
- Add support for JWT events configuration in Web API projects.
- Add support for BackchannelHttpHandler configuration.
- Add support for BackchannelTimeout configuration.

### Breaking changes

- Remove `ClientId` property from `WebApiOptions`.

### Features

- Add strong name signature.


## v3.2.2

### Bug Fix
Expand Down
2 changes: 1 addition & 1 deletion Okta.AspNet.Abstractions/Okta.AspNet.Abstractions.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<TargetFrameworks>net452;netstandard2.0</TargetFrameworks>
<Version>3.2.2</Version>
<Version>4.0.0</Version>
</PropertyGroup>

<PropertyGroup>
Expand Down
8 changes: 5 additions & 3 deletions Okta.AspNet.Abstractions/OktaHttpMessageHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@ public class OktaHttpMessageHandler : DelegatingHandler
{
private readonly Lazy<string> _userAgent;

public OktaHttpMessageHandler(string frameworkName, Version frameworkVersion, OktaWebOptions oktaWebOptions = null)
public OktaHttpMessageHandler(string frameworkName, Version frameworkVersion, OktaWebOptions oktaWebOptions)
{
_userAgent = new Lazy<string>(() => new UserAgentBuilder(frameworkName, frameworkVersion).GetUserAgent());
InnerHandler = new HttpClientHandler();
if (oktaWebOptions?.Proxy != null)
InnerHandler = oktaWebOptions.BackchannelHttpClientHandler ?? new HttpClientHandler();

// If a backchannel handler is provided, then the proxy config is not overwritten
if (oktaWebOptions.BackchannelHttpClientHandler == null && oktaWebOptions.Proxy != null)
{
((HttpClientHandler)InnerHandler).Proxy = new DefaultProxy(oktaWebOptions.Proxy);
}
Expand Down
4 changes: 1 addition & 3 deletions Okta.AspNet.Abstractions/OktaWebApiOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
// </copyright>

using System;
using System.Net.Http;

namespace Okta.AspNet.Abstractions
{
Expand All @@ -12,8 +13,5 @@ public class OktaWebApiOptions : OktaWebOptions
public static readonly string DefaultAudience = "api://default";

public string Audience { get; set; } = DefaultAudience;

[Obsolete("ClientId is no longer required, and has no effect. This property will be removed in the next major release.")]
public string ClientId { get; set; }
}
}
20 changes: 20 additions & 0 deletions Okta.AspNet.Abstractions/OktaWebOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
// </copyright>

using System;
using System.Net.Http;

namespace Okta.AspNet.Abstractions
{
Expand Down Expand Up @@ -40,6 +41,25 @@ public class OktaWebOptions
/// <summary>
/// Gets or sets the URI of your organization's proxy server. The default is <c>null</c>.
/// </summary>
/// <value>
/// The URI of your organization's proxy server. The default is <c>null</c>.
/// </value>
public ProxyConfiguration Proxy { get; set; }

/// <summary>
/// Gets or sets the HttpMessageHandler used to communicate with Okta.
/// </summary>
/// <value>
/// The HttpMessageHandler used to communicate with Okta.
/// </value>
public HttpMessageHandler BackchannelHttpClientHandler { get; set; }

/// <summary>
/// Gets or sets timeout value in milliseconds for back channel communications with Okta.
/// </summary>
/// <value>
/// Timeout value in milliseconds for back channel communications with Okta.
/// </value>
public TimeSpan BackchannelTimeout { get; set; } = TimeSpan.FromSeconds(60);
}
}
38 changes: 38 additions & 0 deletions Okta.AspNet.Test/HttpClientBuilderShould.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// <copyright file="HttpClientBuilderShould.cs" company="Okta, Inc">
// Copyright (c) 2018-present Okta, Inc. All rights reserved.
// Licensed under the Apache 2.0 license. See the LICENSE file in the project root for full license information.
// </copyright>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FluentAssertions;
using Xunit;

namespace Okta.AspNet.Test
{
public class HttpClientBuilderShould
{
[Fact]
public async Task InvokeCustomHandler()
{
var handler = new MockHttpClientHandler();

var options = new OktaWebApiOptions();
options.OktaDomain = "https://test.okta.com";
options.BackchannelHttpClientHandler = handler;
options.BackchannelTimeout = TimeSpan.FromMinutes(5);

options.BackchannelHttpClientHandler.Should().NotBeNull();

var client = HttpClientBuilder.CreateClient(options);

var response = await client.GetAsync("http://www.okta.com");

handler.NumberOfCalls.Should().BeGreaterThan(0);
client.Timeout.Should().Be(TimeSpan.FromMinutes(5));
}
}
}
34 changes: 34 additions & 0 deletions Okta.AspNet.Test/JwtOptionsBuilderShould.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// <copyright file="JwtOptionsBuilderShould.cs" company="Okta, Inc">
// Copyright (c) 2018-present Okta, Inc. All rights reserved.
// Licensed under the Apache 2.0 license. See the LICENSE file in the project root for full license information.
// </copyright>

using System;
using FluentAssertions;
using Microsoft.Owin.Security.OAuth;
using NSubstitute;
using Xunit;

namespace Okta.AspNet.Test
{
public class JwtOptionsBuilderShould
{
[Fact]
public void BuildJwtBearerOptions()
{
var mockAuthnProvider = Substitute.For<OAuthBearerAuthenticationProvider>();

var oktaWebApiOptions = new OktaWebApiOptions
{
OktaDomain = "http://myoktadomain.com",
BackchannelTimeout = TimeSpan.FromMinutes(5),
BackchannelHttpClientHandler = new MockHttpClientHandler(),
OAuthBearerAuthenticationProvider = mockAuthnProvider,
};

var jwtOptions = JwtOptionsBuilder.BuildJwtBearerAuthenticationOptions(oktaWebApiOptions);
jwtOptions.Should().NotBeNull();
jwtOptions.Provider.Should().Be(mockAuthnProvider);
}
}
}
44 changes: 44 additions & 0 deletions Okta.AspNet.Test/MockHttpClientHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// <copyright file="MockHttpClientHandler.cs" company="Okta, Inc">
// Copyright (c) 2018-present Okta, Inc. All rights reserved.
// Licensed under the Apache 2.0 license. See the LICENSE file in the project root for full license information.
// </copyright>

using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;

namespace Okta.AspNet.Test
{
public class MockHttpClientHandler : DelegatingHandler
{
private readonly string _response;
private readonly HttpStatusCode _statusCode;

public string Body { get; private set; }

public int NumberOfCalls { get; private set; }

public MockHttpClientHandler(string response = "{}", HttpStatusCode statusCode = HttpStatusCode.OK)
{
_response = response;
_statusCode = statusCode;
}

protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken = default)
{
NumberOfCalls++;

if (request.Content != null)
{
Body = await request.Content.ReadAsStringAsync();
}

return new HttpResponseMessage
{
StatusCode = _statusCode,
Content = new StringContent(_response),
};
}
}
}
2 changes: 1 addition & 1 deletion Okta.AspNet.Test/Okta.AspNet.Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<ItemGroup>
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" />
<PackageReference Include="FluentAssertions" Version="5.3.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
<PackageReference Include="NSubstitute" Version="4.2.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">
Expand Down
Loading

0 comments on commit 0435a6d

Please sign in to comment.