From 17560b1186283714cd708f4a3c90a5c519a86556 Mon Sep 17 00:00:00 2001 From: Gao Sun Date: Thu, 14 Sep 2023 10:29:14 +0800 Subject: [PATCH] chore(console): add asp.net mvc guide (#4490) * chore(console): add asp.net mvc guide * chore(console): fix lint errors --- .../console/src/assets/docs/guides/index.ts | 8 + .../guides/web-asp-net-core-mvc/README.mdx | 184 ++++++++++++++++++ .../guides/web-asp-net-core-mvc/config.json | 3 + .../docs/guides/web-asp-net-core-mvc/index.ts | 15 ++ .../docs/guides/web-asp-net-core-mvc/logo.svg | 2 + .../docs/guides/web-asp-net-core/index.ts | 3 +- 6 files changed, 213 insertions(+), 2 deletions(-) create mode 100644 packages/console/src/assets/docs/guides/web-asp-net-core-mvc/README.mdx create mode 100644 packages/console/src/assets/docs/guides/web-asp-net-core-mvc/config.json create mode 100644 packages/console/src/assets/docs/guides/web-asp-net-core-mvc/index.ts create mode 100644 packages/console/src/assets/docs/guides/web-asp-net-core-mvc/logo.svg diff --git a/packages/console/src/assets/docs/guides/index.ts b/packages/console/src/assets/docs/guides/index.ts index 15aaa9ec1..e350a4f4c 100644 --- a/packages/console/src/assets/docs/guides/index.ts +++ b/packages/console/src/assets/docs/guides/index.ts @@ -14,6 +14,7 @@ import spaVanilla from './spa-vanilla/index'; import spaVue from './spa-vue/index'; import { type Guide } from './types'; import webAspNetCore from './web-asp-net-core/index'; +import webAspNetCoreMvc from './web-asp-net-core-mvc/index'; import webExpress from './web-express/index'; import webGo from './web-go/index'; import webGptPlugin from './web-gpt-plugin/index'; @@ -151,6 +152,13 @@ const guides: Readonly = Object.freeze([ Component: lazy(async () => import('./web-asp-net-core/README.mdx')), metadata: webAspNetCore, }, + { + order: 5.1, + id: 'web-asp-net-core-mvc', + Logo: lazy(async () => import('./web-asp-net-core-mvc/logo.svg')), + Component: lazy(async () => import('./web-asp-net-core-mvc/README.mdx')), + metadata: webAspNetCoreMvc, + }, { order: 6, id: 'web-outline', diff --git a/packages/console/src/assets/docs/guides/web-asp-net-core-mvc/README.mdx b/packages/console/src/assets/docs/guides/web-asp-net-core-mvc/README.mdx new file mode 100644 index 000000000..093e0ef8f --- /dev/null +++ b/packages/console/src/assets/docs/guides/web-asp-net-core-mvc/README.mdx @@ -0,0 +1,184 @@ +import UriInputField from '@/mdx-components/UriInputField'; +import Tabs from '@mdx/components/Tabs'; +import TabItem from '@mdx/components/TabItem'; +import InlineNotification from '@/ds-components/InlineNotification'; +import { buildIdGenerator } from '@logto/shared/universal'; +import Steps from '@/mdx-components/Steps'; +import Step from '@/mdx-components/Step'; + + + + + +This tutorial will show you how to use Logto ASP.NET Core authentication middleware to protect your web application. + +
    +
  • It assumes your website is hosted on {props.sampleUrls.origin}.
  • +
+ +### Installation + +```bash +dotnet add package Logto.AspNetCore.Authentication +``` + +
+ + + +Open `Startup.cs` (or `Program.cs`) and add the following code to register Logto authentication middleware: + +
+  
+{`using Logto.AspNetCore.Authentication;
+
+var builder = WebApplication.CreateBuilder(args);
+
+builder.Services.AddLogtoAuthentication(options =>
+{
+  options.Endpoint = "${props.endpoint}";${props.alternativeEndpoint ? ' // or "${props.alternativeEndpoint}"' : ''}
+  options.AppId = "${props.app.id}";
+  options.AppSecret = "${props.app.secret}";
+});
+
+app.UseAuthentication();`}
+  
+
+ +The `AddLogtoAuthentication` method will do the following things: + +- Set the default authentication scheme to `LogtoDefaults.CookieScheme`. +- Set the default challenge scheme to `LogtoDefaults.AuthenticationScheme`. +- Set the default sign-out scheme to `LogtoDefaults.AuthenticationScheme`. +- Add cookie and OpenID Connect authentication handlers to the authentication scheme. + +
+ + + +

+First, let's enter your redirect URI. E.g. {props.sampleUrls.origin + 'Callback'} (replace the endpoint with yours). This is where Logto will redirect users after they sign in. +

+ + + +Remember to keep the path `/Callback` in the URI as it's the default value for the Logto authentication middleware. + +To sign-in with Logto, you can use the `Challenge` method of `ControllerBase`: + +```csharp +Challenge(new AuthenticationProperties +{ + // The URI below is different from the redirect URI you entered above. + // It's the URI where users will be redirected after successfully signed in. + // You can change it to any path you want. + RedirectUri = "/" +}); +``` + +For example, you can add the following code to the controller: + +```csharp +public class HomeController : Controller +{ + public IActionResult SignIn() + { + return Challenge(new AuthenticationProperties { RedirectUri = "/" }); + } +} +``` + +And then add the following code to your View: + +```html +

Is authenticated: @User.Identity?.IsAuthenticated

+Sign in +``` + +
+ + + +To clean up both ASP.NET session and Logto session, we can designate a post sign-out redierct URI. This is where Logto will redirect users after they sign out. + +

+For example, set the URI to {props.sampleUrls.origin + 'SignedOutCallback'} (replace the endpoint with yours): +

+ + + +Remember to keep the path `/SignedOutCallback` in the URI as it's the default value for the Logto authentication middleware. + +To sign-out with Logto, you can use the `SignOut` method of `ControllerBase`: + +```csharp +SignOut(new AuthenticationProperties +{ + // The URI below is different from the post sign-out redirect URI you entered above. + // It's the URI where users will be redirected after successfully signed out. + // You can change it to any path you want. + RedirectUri = "/" +}); +``` + +The `SignOut` method will clear the authentication cookie and redirect the user to the Logto sign-out page. + +For example, you can add the following code to your controller: + +```csharp +public class HomeController : Controller +{ + // ... + // Use the `new` keyword to avoid conflict with the `ControllerBase.SignOut` method + new public IActionResult SignOut() + { + return SignOut(new AuthenticationProperties { RedirectUri = "/" }); + } +} +``` + +Then, update the form on your View: + +```html +

Is authenticated: @User.Identity?.IsAuthenticated

+@if (User.Identity?.IsAuthenticated == true) +{ + Sign out +} else { + Sign in +} +``` + +It will show the "Sign in" link if the user is not authenticated, and show the "Sign out" link if the user is authenticated. + +
+ + + +Now you can run the web application and try to sign in and sign out with Logto: + +1. Open the web application in your browser, you should see "Is authenticated: False" and the "Sign in" link. +2. Click the "Sign in" link, and you should be redirected to the Logto sign-in page. +3. After you have signed in, you should be redirected back to the web application, and you should see "Is authenticated: True" and the "Sign out" link. +4. Click the "Sign out" link, and you should be redirected to the Logto sign-out page, and then redirected back to the web application. + + + + + +To know if the user is authenticated, you can check the `User.Identity?.IsAuthenticated` property. + +To get the user profile claims, you can use the `User.Claims` property: + +```csharp +var claims = User.Claims; + +// Get the user ID +var userId = claims.FirstOrDefault(c => c.Type == LogtoParameters.Claims.Subject)?.Value; +``` + +See the [full tutorial](https://github.com/logto-io/csharp/tree/HEAD/src/Logto.AspNetCore.Authentication/docs/tutorial.md) for more details. + + + +
diff --git a/packages/console/src/assets/docs/guides/web-asp-net-core-mvc/config.json b/packages/console/src/assets/docs/guides/web-asp-net-core-mvc/config.json new file mode 100644 index 000000000..e0896d3b5 --- /dev/null +++ b/packages/console/src/assets/docs/guides/web-asp-net-core-mvc/config.json @@ -0,0 +1,3 @@ +{ + "order": 5.1 +} diff --git a/packages/console/src/assets/docs/guides/web-asp-net-core-mvc/index.ts b/packages/console/src/assets/docs/guides/web-asp-net-core-mvc/index.ts new file mode 100644 index 000000000..0bdf883a3 --- /dev/null +++ b/packages/console/src/assets/docs/guides/web-asp-net-core-mvc/index.ts @@ -0,0 +1,15 @@ +import { ApplicationType } from '@logto/schemas'; + +import { type GuideMetadata } from '../types'; + +const metadata: Readonly = Object.freeze({ + name: 'ASP.NET Core (MVC)', + description: 'ASP.NET Core is a cross-platform framework for building modern apps.', + target: ApplicationType.Traditional, + sample: { + repo: 'csharp', + path: 'sample-mvc', + }, +}); + +export default metadata; diff --git a/packages/console/src/assets/docs/guides/web-asp-net-core-mvc/logo.svg b/packages/console/src/assets/docs/guides/web-asp-net-core-mvc/logo.svg new file mode 100644 index 000000000..d04bf0477 --- /dev/null +++ b/packages/console/src/assets/docs/guides/web-asp-net-core-mvc/logo.svg @@ -0,0 +1,2 @@ + +logo_NETcore \ No newline at end of file diff --git a/packages/console/src/assets/docs/guides/web-asp-net-core/index.ts b/packages/console/src/assets/docs/guides/web-asp-net-core/index.ts index c323489f4..35dedf614 100644 --- a/packages/console/src/assets/docs/guides/web-asp-net-core/index.ts +++ b/packages/console/src/assets/docs/guides/web-asp-net-core/index.ts @@ -4,8 +4,7 @@ import { type GuideMetadata } from '../types'; const metadata: Readonly = Object.freeze({ name: 'ASP.NET Core', - description: - 'ASP.NET Core is a cross-platform and open-source framework for building modern applications.', + description: 'ASP.NET Core is a cross-platform framework for building modern apps.', target: ApplicationType.Traditional, sample: { repo: 'csharp',