Showing posts with label asp.net core. Show all posts
Showing posts with label asp.net core. Show all posts

Single Sign-On Using ASP.NET MVC And ASP.NET Core | RAJESH GAMI

 

What is single sign-on (SSO)?

Users must authenticate themselves to access pages protected by a web application, and if a user accesses multiple web applications, they must be authenticated. You must log in to each application separately.

Single Sign-on using ASP.NET MVC and ASP.NET CORE

Interested in using single sign-on (SSO) for your ASP.NET MVC app? You're in the right place. There are many reasons to use SSO for custom apps owned by the same organization.

  • Improved user experience.
  • Reduce development time.
  • Improved security.

These are all good reasons.

Another thing I like about SSO is that it allows me to update large code bases in small increments instead of all at once.

As? Suppose you want to migrate an app written in ASP.NET MVC 5 to ASP.NET Core MVC. Instead of rewriting everything at once, you can migrate one service at a time. By implementing SSO between two apps, you can effectively connect the two apps as if they were one app.

This tutorial simulates such a scenario by implementing his SSO in an MVC 5 app and a .NET Core app. Along the way, you'll also learn about the differences in how the two platforms implement authentication.

Find the ASP.NET MVC 5 App

Access an existing MVC 5 app from GitHub instead of building a project from scratch. Clone or download this project (https://github.com/oktadev/aspnet-mvc-crud-example) and open the solution in Visual Studio.

Web.config file has some app settings used by programmers to configure authentication with the Open ID Connect server provided by Okta:

<add key="okta:ClientId" value="{yourClientId}" />
<add key="okta:ClientSecret" value="{yourClientSecret}" />
<add key="okta:OktaDomain" value="https://{yourOktaDomain}" />
ASP.NET (C#)

For this tutorial, you'll need to switch these values ​​to your own Okta instance. Sign in to your Okta domain if you already have an account, or sign up for a forever free developer account if you don't already have one.

After signing in to Okta, register your client application.

  • Click Applications on the top menu.
  • Click Add Application.
  • Select Web and click Next.
  • Enter SSO MVC 5 for Name.
  • For the Grant type allowed check the Implicit (Hybrid) checkbox
  • And last click on DONE

The application has been created, but we still need to add something. Select Edit and add http://localhost:8080/Account/PostLogout to the logout redirect URI list and click Save.

On the next screen, you will see a summary of your settings. Under the General Settings section, you will see the Client Credentials section. Update the SSO settings in Web.config with your client ID and client secret. Next, go to the main page of your Okta dashboard, copy the organization URL shown in the top left corner, and paste it into Okta.

OktaDomain app settings in Web.config.

At this point, you should be able to run your app and sign in and out using OpenID Connect. If you're interested, take a look at Startup.cs to see how the authentication middleware is configured.

Find the ASP.NET Core App

Now that you're using Okta to log into your MVC 5 app, adding SSO to your second app is trivial.

First, download or clone this .NET Core app from GitHub.(https://github.com/oktadeveloper/okta-aspnetcore22-crud-example) If opening in Visual Studio, change the debug target from IIS Express to LiveMusicFinder.

This will run your app through the Kestrel web server on port 5001 (for https).

Go back to your Okta admin panel and register this application.

  • click on Applications at top of the menu
  • Then click on Add Application
  • And select Web and click Next
  • Enter SSO Core MVC for the Name
  • Replace Base URIs with https://localhost:5001/
  • Replace Login redirect URIs with https://localhost:5001/authorization-code/callback
  • Click Done

Once complete, you'll be taken to the General Settings tab of the app. In this tab, click the Edit button and add an entry to the Signout Redirect URI as https://localhost:5001/signout/callback.

Then click Save.

Copy the Client ID and Client Secret from the Client Credentials section of the next page and update your application's appsettings.json file.

"Okta": {
  "ClientId": "{yourClientId}",
  "ClientSecret": "{yourClientSecret}",
  "OktaDomain": "https://{yourOktaDomain}",
  "PostLogoutRedirectUri": "https://localhost:5001/"
},
ASP.NET (C#)

While editing the settings, update the OktaDomain settings to match what you entered in your MVC 5 app's Web.config. Also change the PostLogoutRedirectUri to https//local host:5001/.

That's really it. When you sign in to either app, click the Sign In link in the other app to automatically sign you in without prompting for your password.

(If you're inexplicably testing this using Internet Explorer and Visual Studio's auto-launch feature, make sure you're opening her second app in a tab in her window in the first browser. . Each browser window is isolated from the others due to Visual Studio's habit of launching IE.)

How single sign-on works in ASP.NET MVC 5 and ASP.NET Core

We've seen how easy it is to enable SSO in two ASP.NET apps, but what's really going on behind the scenes to make it work?

Suppose you first navigate to App 1 and click Sign In. App 1 redirects to Okta IdP (Identity Provider) where it signs in. When you log in, a cookie from Okta's domain is set in your browser. This cookie keeps you logged into Okta. Okta then returns to App 1 with the token it uses to complete the sign-in process. At this point, her cookie is also set on the App 1 domain. Here's a diagram to explain the states:

Then open app 2 in another tab in the same browser. Click Sign In and you will be redirected back to the Okta IdP. However, this time we still have a valid cookie, so we are already logged into the IdP. So instead of showing a login screen, Okta simply redirects to App 2 with the token needed to complete the local login process. A cookie is set on the domain of app 2 and you can log in from anywhere.

Note that Single sign-out_ is not supported by Okta as of this writing. When you log out of App 1, the cookies in App 1 are deleted and a quick call is made to the Okta IdP, which deletes the cookies. However, the App 2 cookie remains and you remain signed in to App 2 until you click Sign Out or the cookie expires. The default expiration is 30 days.

Explain ASP.NET OpenID Connect Flow

As you may have noticed, when I set up the configuration for my MVC 5 app I had to check the box to enable the implicit (hybrid) grant type, but not for .NET Core apps was.

When the OpenID Connect middleware was written for his MVC 5 years ago (long time ago in the software world), the OpenID Connect hybrid flow was implemented. This flow requires the IdP to pass an authorization code and ID token to the MVC 5 app submission. When redirecting the user to your app.

When the OpenID Connect middleware was written for .NET Core, it implemented a more secure authorization code flow. In this case the IdP should only return an authorization code and the middleware should get the ID token via a backchannel request to his IdP. This means that the ID token is not exposed to browsers. Note that if you pass sensitive information in an ID token, in MVC 5 this token will be returned to your app via the browser. This is not a problem when enabling SSO for him for .NET Core apps.

.Net 7 New Features Update | RAJESH GAMI




 .NET 7 Preview 1 is now available! .. This is the first preview of the next major .NET release and will bring the next wave of innovation to web development with ASP.NET Core. With

.NET 7, we plan to make a significant investment in ASP.NET Core. Below are some of the areas we would like to focus on.


  • Performance: ..NET 6 includes many performance improvements for ASP.NET Core, and we are working to make ASP.NET Core even faster and more efficient with .NET 7.
  • HTTP/3: HTTP / 3 support is provided as a preview feature in .NET 6. For .NET 7, complete it with the support features enabled by default. In future previews, HTTP / 3 support can be expected to enhance TLS capabilities and other performance improvements.
  • Minimal APIs: Adds endpoint filtering and route grouping support as a core element of the minimal API. It also simplifies the configuration of common API authentication and authorization.
  • gRPC:  We are investing in gRPC JSON transcoding. This feature allows you to use JSON requests and responses to call gRPC services such as the RESTful HTTP API.
  • SignalR: Added support for strongly typed clients and returns results from client calls.
  • Razor: Makes various improvements to the Razor compiler to improve performance and restoring force and enable tool improvements.
  • Blazor Once Blazor hybrid support for .NET MAUI, WPF, and Windows Forms is complete, there will be significant Blazor improvements, including:
    • New .NET Web Assembly features: AOT mixed mode, multithreading, web crypto.
    • Improved support for hot reloads.
    • Improved data binding.
    • More flexible pre-rendering.
    • You can have finer control over the life cycle of the Blazor Server circuit.
    • Improved support for the micro front end.
  • MVCImproved endpoint routing, link generation, and parameter binding.
  • Orleans: ASP.NET Core and the Orleans team are looking for ways to further align and integrate Orleans' distributed programming model with ASP.NET Core. Orleans 4 ships with .NET 7 and focuses on simplicity, maintainability, and performance, including a human-readable stream ID and a new optimized version-tolerant serializer.

For more information on specific ASP.NET Core tasks planned for .NET7, see .NET 7's complete ASP.NET Core roadmap on GitHub.

.NET 7 Preview 1 is the first of many .NET 7 preview releases in preparation for the November 2022 .NET 7 release.

Watch the following video on .net to analyze everything contained in .NET 7 and Asp.net in .NET 7.


Here's an overview of what's new in this preview release: 

  • Minimal API improvements:
    • Support for IFormFile and IFormFileCollection
    • Bind the request body as a Stream or PipeReader 
    • JSON option configuration 
  • SignalR client source generator 
  • Support for nullable models in MVC views and Razor pages 
  • Use JSON property name in a validation error
  • Improved console output for dotnet watch 
  • Configure dotnet watch to reboot whenever there is a significant change 
  • Use Dependency Injection with ValidationAttribute
  • Faster header parsing and writing
  • gRPC JSON transcoding


Get started

Starting to use ASP.NET Core with .NET 7 Preview 1, install the .NET 7 SDK.

If you are using Visual Studio on Windows, we recommend that you install the latest Visual Studio 2022 preview. Support for the .NET 7 preview version of Visual Studio for Mac isn't available yet, but it will be available soon.

To install the latest .NET WebAssembly build tools, run the following command from an elevated command prompt:

dotnet workload install wasm-tools

Upgrade an existing project

To upgrade an existing ASP.NET Core app from .NET 6 to .NET 7 Preview 1:

  • Update the target framework for your app to net7.0.
  • Update all Microsoft.AspNetCore.* package references to 7.0.0-preview.1.*.
  • Update all Microsoft.Extensions.* package references to 7.0.0-preview.1.*.

See also the full list of breaking changes in ASP.NET Core for .NET 7.

Minimal API improvements

IFormFile and IFormFileCollection Support

IFormFile and IFormFileCollection can now be used to handle file uploads with a minimal API.

app.MapPost("/upload", async(IFormFile file) =>
{
    using var stream = System.IO.File.OpenWrite("upload.txt");
    await file.CopyToAsync(stream); 
});
app.MapPost("/upload", async (IFormFileCollection myFiles) => { ... });

Anti-counterfeiting support is required to use this feature for authentication, but it has not yet been implemented. Anti-forgery support for minimal APIs is on our roadmap for .NET 7. Binding to an IFormFile or IFormFileCollection if the request contains an Authorization header, Client Certificate, or Cookie header is currently disabled. This limitation will be fixed when the anti-counterfeiting support work is finished.

Bind the request body as a Stream or PipeReader

Scenarios where the request body is bound as a Stream or PipeReader and the user needs to ingest the data and store it in blob storage or queue the data for later processing in a queue provider (such as Azure Queue) or the cloud. We are now able to support you efficiently. function. The following example shows how to use the new binding.

app.MapPost("v1/feeds", async (QueueClient queueClient, Stream body, CancellationToken cancellationToken) =>
{
    await queueClient.CreateIfNotExistsAsync(cancellationToken: cancellationToken);
    await queueClient.SendMessageAsync(await BinaryData.FromStreamAsync(body), cancellationToken: cancellationToken);
});

Keep the following in mind when using  Stream or PipeReader: 

  • When reading data,  Stream is the same object as HttpRequest.Body
  • By default, the request body is not buffered. Once the text has been read, it cannot be rewound (the stream cannot be read multiple times).
  • Stream / PipeReader cannot be used outside the minimal action handler because the underlying buffer is discarded and/or reused.

JSON option configuration

We are introducing a new and cleaner API, ConfigureRouteHandlerJsonOptions, to configure JSON options for minimal API end-point. This new API avoids confusion with Microsoft.AspNetCore.Mvc.JsonOptions.

var builder = WebApplication.CreateBuilder(args);
builder.Services.ConfigureRouteHandlerJsonOptions(options =>
{
    //Ignore Cycles
    options.SerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles; 
});    

SignalR client source generator

SignalR Client Source Generator generates strongly typed transmit and receive codes based on the interface you define. Instead of the loosely typed.On ("methodName", ...) method, you can reuse the same interface from a strongly typed SignalR hub on the client. Similarly, a hub can implement an interface for that method, and clients can call the hub's methods using the same interface.

To use the SignalR client source generator:

[AttributeUsage(AttributeTargets.Method)]
internal class HubServerProxyAttribute : Attribute
{
}

[AttributeUsage(AttributeTargets.Method)]
internal class HubClientProxyAttribute : Attribute
{
}
  • Add a static partial class to your project and write static partial methods with the [HubClientProxy] and [HubServerProxy] attributes
internal static partial class MyCustomExtensions
{
    [HubClientProxy]
    public static partial IDisposable ClientRegistration<T>(this HubConnection connection, T provider);

    [HubServerProxy]
    public static partial T ServerProxy<T>(this HubConnection connection);
}
  • Use the partial methods from your code!
public interface IServerHub
{
    Task SendMessage(string message);
    Task<int> Echo(int i);
}

public interface IClient
{
    Task ReceiveMessage(string message);
}

public class Client : IClient
{
    // Equivalent to HubConnection.On("ReceiveMessage", (message) => {});
    Task ReceiveMessage(string message)
    {
        return Task.CompletedTask;
    }
}

HubConnection connection = new HubConnectionBuilder().WithUrl("...").Build();
var stronglyTypedConnection = connection.ServerProxy<IServerHub>();
var registrations = connection.ClientRegistration<IClient>(new Client());

await stronglyTypedConnection.SendMessage("Hello world");
var echo = await stronglyTypedConnection.Echo(10);

Support for nullable models in MVC views and Razor Pages

 To improve the experience when using null state checking in ASP.NET Core apps, we have enabled the definition of a nullable page or view model.

@model Product?

Use JSON property names in validation errors

By default, when ModelErrorDictionary is generated by model validation, the property name is used as the error key ("MyClass.PropertyName"). Model property names are usually implementation details and can be difficult to handle for single-page apps. You can now configure validation to use the appropriate JSON property name instead of the new SystemTextJsonValidationMetadataProvider (or NewtonsoftJsonValidationMetadataProvider if you are using Json.NET).

services.AddControllers(options =>
{
    options.ModelMetadataDetailsProviders.Add(new SystemTextJsonValidationMetadataProvider())
});

Improved console output for dotnet watch

We cleaned up the console output from dotnet watch to better align with the log out of ASP.NET Core and to stand out with 😮emojis😍.

Here’s an example of what the new output looks like:

C:BlazorApp> dotnet watch
dotnet watch 🔥 Hot reload enabled. For a list of supported edits, see https://aka.ms/dotnet/hot-reload.
  💡 Press "Ctrl + R" to restart.
dotnet watch 🔧 Building...
  Determining projects to restore...
  All projects are up-to-date for restore.
  You are using a preview version of .NET. See: https://aka.ms/dotnet-support-policy
  BlazorApp -> C:UsersdarothDesktopBlazorAppbinDebugnet7.0BlazorApp.dll
dotnet watch 🚀 Started
info: Microsoft.Hosting.Lifetime[14]
      Now listening on: https://localhost:7148
info: Microsoft.Hosting.Lifetime[14]
      Now listening on: http://localhost:5041
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
      Content root path: C:UsersdarothDesktopBlazorApp
dotnet watch ⌚ File changed: .PagesIndex.razor.
dotnet watch 🔥 Hot reload of changes succeeded.
info: Microsoft.Hosting.Lifetime[0]
      Application is shutting down...
dotnet watch 🛑 Shutdown requested. Press Ctrl+C again to force exit.

Configure dotnet watch to always restart for rude edits

Set the DOTNET_WATCH_RESTART_ON_RUDE_EDIT environment variable to true to configure dotnetwatch to always reboot without requesting rude changes (non-reloadable changes).

Inject services into custom validation attributes in Blazor

You can now inject services into custom validation attributes in Blazor. Blazor will be set up  ValidationContext so it can be used as a service provider.

public class SaladChefValidatorAttribute : ValidationAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var saladChef = validationContext.GetRequiredService<SaladChef>();
        if (saladChef.ThingsYouCanPutInASalad.Contains(value.ToString()))
        {
            return ValidationResult.Success;
        }
        return new ValidationResult("You should not put that in a salad!");
    }
}

// Simple class configured as a service for dependency injection
public class SaladChef
{
    public string[] ThingsYouCanPutInASalad = { "Strawberries", "Pineapple", "Honeydew", "Watermelon", "Grapes" };
}

Faster header parsing and writing

We made several improvements to the performance of header parsing and writing for HTTP/2 and HTTP/3. See the following pull requests for details:

gRPC JSON transcoding

gRPC JSON transcoding allows gRPC services to be used like a RESTful HTTP APIs. Once configured, gRPC JSON transcoding allows you to call gRPC methods with familiar HTTP concepts:

  • HTTP verbs
  • URL parameter binding
  • JSON requests/responses

Of course, gRPC can still be used. RESTful API for gRPC services. There is no duplication! 

ASP.NET Core uses a library called gRPC-HTTP-API to provide experimental support for this feature. For .NET 7, we plan to make this feature a supported part of ASP.NET Core. This feature is not yet included in .NET 7, but you can try out existing experimental packages. For more information, see the gRPC HTTP API getting started documentation.


Thanks 

Rajesh Gami

Full-Stack Developer









RAJESH GAMI - Blog

Digital Signature Pad in Angular | RAJESH GAMI

  What is Signature Pad? Signature Pad could be a JavaScript library for drawing fancy signatures. It supports HTML5 canvas and uses variabl...