Tip
Looking for a .NET Framework example? Have a look.
Using Cloud Foundry SSO with OpenID Connect provider
This is a guide to integrate a .Net Core API with the Cloud Foundry SSO identity provider service. The sample provides authentication to select entry points of an application. It is meant to provide authentication simiar to how IIS would when Windows authentication is enabled.
Note
For more detailed examples, please refer to the Security section in the Steeltoe Samples Repository.
First, establish an identity provider. Using the Steeltoe dockerfile, start a local instance of SSO.
docker run --rm -ti -p 8080:8080 --name steeltoe-uaa steeltoeoss/workshop-uaa-server
Note
This is a developer image of the Cloud Foundry User Account and Authentication (UAA) OAuth identity provider. It is meant for development purposes only.
Next, create a .NET Core WebAPI that interacts with SSO
Create a new ASP.NET Core WebAPI app with the Steeltoe Initializr
Name the project "OAuthSSOExample"
Add the "OAuth Connector" dependency
Click Generate to download a zip containing the new project
Extract the zipped project and open in your IDE of choice
Open the package manager console
Install NuGet distributed packages
Install-Package -Id Steeltoe.Security.Authentication.CloudFoundryCore -Version 2.4
Set the instance address in appsettings.json
{ "security": { "oauth2": { "client": { "validateCertificates": false, "authDomain": "http://localhost:8080/uaa", "clientId": "fortuneservice", "clientSecret": "fortuneservice_secret" } } } }
Then, add Cloud Foundry OpenID Connect, secure endpoints, and run the app
Set the cloud foundry auth middleware in Startup.cs
using Steeltoe.Security.Authentication.CloudFoundry; public class Startup { public IConfiguration Configuration { get; private set; } public Startup(IConfiguration configuration){ Configuration = configuration; } public void ConfigureServices(IServiceCollection services){ services.AddAuthentication(options => { options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.DefaultChallengeScheme = CloudFoundryDefaults.AuthenticationScheme; }) .AddCookie((options) =>{ // set values like login url, access denied path, etc here options.AccessDeniedPath = new PathString("/Home/AccessDenied"); }) .AddCloudFoundryOpenId(Configuration); // Add Cloud Foundry authentication service } public void Configure(IApplicationBuilder app){ // Use the protocol from the original request when generating redirect uris // (eg: when TLS termination is handled by an appliance in front of the app) app.UseForwardedHeaders(new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.XForwardedProto; }); // Add authentication middleware to pipeline app.UseAuthentication(); } }
Open the Controllers\ValuesControllers.cs file and secure endpoints
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Authorization; [Route("api/[controller]")] [ApiController] public class ValuesController : ControllerBase{ [HttpGet] [AllowAnonymous] public ActionResult<string> Get(){ return "Hi There"; } // GET api/values/5 [HttpGet("{id}")] [Authorize] public ActionResult<string> Get(int id){ return "value: " + id.ToString(); } // POST api/values [HttpPost] [Authorize] public void Post([FromBody] string value){ } // PUT api/values/5 [HttpPut("{id}")] [Authorize] public void Put(int id, [FromBody] string value){ } // DELETE api/values/5 [HttpDelete("{id}")] [Authorize] public void Delete(int id){ } }
Note
Notice the default GET endpoint with no params is open to anonymous connections but the other endpoints all require authorization. With the combination of SSO functions, the user will be prompted for login and returned.
Run the application
dotnet run<PATH_TO>\OAuthSSOExample.csproj
Navigate to the endpoint (you may need to change the port number) http://localhost:5000/api/values
Once the app loads in the browser go to the /api/values
endpoint. It should load with no issue. Then try going to the /api/values/5
endpoint. This will redirect you to the UAA login page. Login with the user fortuneTeller and password password. You will be redirected back to the app's page where the output of "value: 5" is shown.