0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2024-12-16 20:26:19 -05:00

chore(console): add asp.net mvc guide (#4490)

* chore(console): add asp.net mvc guide

* chore(console): fix lint errors
This commit is contained in:
Gao Sun 2023-09-14 10:29:14 +08:00 committed by GitHub
parent 1680cf5fa4
commit 17560b1186
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 213 additions and 2 deletions

View file

@ -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<Guide[]> = 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',

View file

@ -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';
<Steps>
<Step title="Get started">
This tutorial will show you how to use Logto ASP.NET Core authentication middleware to protect your web application.
<ul>
<li>It assumes your website is hosted on <code>{props.sampleUrls.origin}</code>.</li>
</ul>
### Installation
```bash
dotnet add package Logto.AspNetCore.Authentication
```
</Step>
<Step title="Add Logto authentication">
Open `Startup.cs` (or `Program.cs`) and add the following code to register Logto authentication middleware:
<pre>
<code className="language-csharp">
{`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();`}
</code>
</pre>
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.
</Step>
<Step title="Sign-in">
<p>
First, let's enter your redirect URI. E.g. <code>{props.sampleUrls.origin + 'Callback'}</code> (replace the endpoint with yours). This is where Logto will redirect users after they sign in.
</p>
<UriInputField name="redirectUris" />
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
<p>Is authenticated: @User.Identity?.IsAuthenticated</p>
<a asp-controller="Home" asp-action="SignIn">Sign in</a>
```
</Step>
<Step title="Sign-out">
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.
<p>
For example, set the URI to <code>{props.sampleUrls.origin + 'SignedOutCallback'}</code> (replace the endpoint with yours):
</p>
<UriInputField name="postLogoutRedirectUris" />
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
<p>Is authenticated: @User.Identity?.IsAuthenticated</p>
@if (User.Identity?.IsAuthenticated == true)
{
<a asp-controller="Home" asp-action="SignOut">Sign out</a>
} else {
<a asp-controller="Home" asp-action="SignIn">Sign in</a>
}
```
It will show the "Sign in" link if the user is not authenticated, and show the "Sign out" link if the user is authenticated.
</Step>
<Step title="Checkpoint: Test your application">
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.
</Step>
<Step title="The user object">
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.
</Step>
</Steps>

View file

@ -0,0 +1,3 @@
{
"order": 5.1
}

View file

@ -0,0 +1,15 @@
import { ApplicationType } from '@logto/schemas';
import { type GuideMetadata } from '../types';
const metadata: Readonly<GuideMetadata> = 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;

View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><style>.cls-1{fill:#5c2d91;}.cls-2,.cls-3{fill:#fff;}.cls-2{opacity:0.1;}.cls-4{fill:#f2f2f2;}</style></defs><title>logo_NETcore</title><circle class="cls-1" cx="32" cy="32" r="32"/><path class="cls-2" d="M9.82,9A32,32,0,1,0,55,54.18Z"/><path class="cls-3" d="M7.4,37.25a1.35,1.35,0,0,1-1-.42,1.38,1.38,0,0,1-.41-1,1.4,1.4,0,0,1,.41-1,1.34,1.34,0,0,1,1-.43,1.37,1.37,0,0,1,1,.43,1.39,1.39,0,0,1,.42,1,1.37,1.37,0,0,1-.42,1A1.38,1.38,0,0,1,7.4,37.25Z"/><path class="cls-3" d="M27.27,37H24.65L15.28,22.46a6,6,0,0,1-.58-1.14h-.08a18.72,18.72,0,0,1,.1,2.5V37H12.59V18.77h2.77l9.12,14.28q.57.89.74,1.22h.05a19.28,19.28,0,0,1-.13-2.68V18.77h2.13Z"/><path class="cls-3" d="M41.69,37H32V18.77h9.24V20.7H34.18v6.06h6.58v1.92H34.18V35h7.52Z"/><path class="cls-3" d="M56,20.7H50.7V37H48.57V20.7H43.33V18.77H56Z"/><path class="cls-4" d="M26.12,49.4a4.93,4.93,0,0,1-2.32.49,3.74,3.74,0,0,1-2.87-1.15,4.26,4.26,0,0,1-1.08-3,4.46,4.46,0,0,1,1.21-3.26,4.12,4.12,0,0,1,3.08-1.24,4.93,4.93,0,0,1,2,.35v1a4,4,0,0,0-2-.5,3.06,3.06,0,0,0-2.35,1,3.64,3.64,0,0,0-.9,2.58,3.47,3.47,0,0,0,.84,2.45,2.86,2.86,0,0,0,2.21.91,4.14,4.14,0,0,0,2.19-.56Z"/><path class="cls-4" d="M30.21,49.89A2.78,2.78,0,0,1,28.08,49a3.11,3.11,0,0,1-.79-2.23,3.24,3.24,0,0,1,.83-2.36,3,3,0,0,1,2.23-.85,2.69,2.69,0,0,1,2.09.83,3.28,3.28,0,0,1,.75,2.29,3.22,3.22,0,0,1-.81,2.3A2.84,2.84,0,0,1,30.21,49.89Zm.07-5.47a1.83,1.83,0,0,0-1.46.63,2.59,2.59,0,0,0-.54,1.74,2.45,2.45,0,0,0,.54,1.68,1.85,1.85,0,0,0,1.46.62,1.76,1.76,0,0,0,1.43-.6,2.62,2.62,0,0,0,.5-1.72,2.66,2.66,0,0,0-.5-1.73A1.75,1.75,0,0,0,30.28,44.42Z"/><path class="cls-4" d="M37.86,44.72a1.18,1.18,0,0,0-.73-.19,1.23,1.23,0,0,0-1,.58,2.68,2.68,0,0,0-.41,1.58v3.06h-1v-6h1V45h0a2.1,2.1,0,0,1,.63-1,1.43,1.43,0,0,1,.94-.35,1.57,1.57,0,0,1,.57.08Z"/><path class="cls-4" d="M43.72,47H39.49A2.24,2.24,0,0,0,40,48.54a1.86,1.86,0,0,0,1.42.54,3,3,0,0,0,1.86-.67v.9a3.48,3.48,0,0,1-2.09.57,2.54,2.54,0,0,1-2-.82,3.35,3.35,0,0,1-.73-2.3,3.28,3.28,0,0,1,.79-2.28,2.55,2.55,0,0,1,2-.88,2.26,2.26,0,0,1,1.82.76,3.18,3.18,0,0,1,.64,2.12Zm-1-.81a2,2,0,0,0-.4-1.29,1.37,1.37,0,0,0-1.1-.46,1.55,1.55,0,0,0-1.15.49,2.21,2.21,0,0,0-.59,1.27Z"/></svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View file

@ -4,8 +4,7 @@ import { type GuideMetadata } from '../types';
const metadata: Readonly<GuideMetadata> = 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',