# oauth2 + oidc 实现 client部分

#### 任务16：oauth2 + oidc 实现 client部分 <a href="#ren-wu-16oauth2oidc-shi-xian-client-bu-fen" id="ren-wu-16oauth2oidc-shi-xian-client-bu-fen"></a>

实现 client 之前启动一下上一节的 server，启动之前需要清除一些代码

**注释 Program 的 MigrateDbContext**

```
public static void Main(string[] args)
{
    BuildWebHost(args)
        //.MigrateDbContext<ApplicationDbContext>((context, services) => {
        //    new ApplicationDbContextSeed().SeedAsync(context, services)
        //    .Wait();
        //})
        .Run();
}
```

**RegisterViewModel**

```
[Required]
//[DataType(DataType.EmailAddress)]
//public string Email{get;set;}
public string UserName { get; set; }
```

启动程序，使用 Config 中的 TestUser 登录

![](/files/IimAht3MOmihTHO37nPY)

登录成功，不过现在是在本地，接下来需要把它放到客户端里面

新建一个 Asp.Net Core MVC 网站 MvcClient

**在 startup 的 ConfigureServices 中添加 Authentication**

```
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
    services.Configure<CookiePolicyOptions>(options =>
    {
        // This lambda determines whether user consent for non-essential cookies is needed for a given request.
        options.CheckConsentNeeded = context => true;
        options.MinimumSameSitePolicy = SameSiteMode.None;
    });


    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

    services.AddAuthentication(options =>
    {
        options.DefaultScheme = "Cookies";
        options.DefaultChallengeScheme = "oidc";
    })
    .AddCookie("Cookies")
    .AddOpenIdConnect("oidc", options =>
    {
        options.SignInScheme = "Cookies";
        options.Authority = "http://localhost:5000";
        options.RequireHttpsMetadata = false;

        options.ClientId = "client";
        options.ClientSecret = "secret";
        options.SaveTokens = true;
    });
}
```

**在 startup 的 Configure 中的 UseMvc 前添加 Authentication**

```
app.UseAuthentication();
```

**在 Program 的 CreateWebHostBuilder 中配置 Urls**

```
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseUrls("http://localhost:5001")
            .UseStartup<Startup>();
```

客户端设置为5001来启动，然后服务端设置为5000

**mvcCookieAuthSample 的 Program**

```
public static IWebHost BuildWebHost(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseEnvironment("Development")
                .UseUrls("http://localhost:5000")
                .UseStartup<Startup>()
                .Build();
```

**修改服务端的 Config 配置跳转地址**

```
public static IEnumerable<Client> GetClients()
{
    return new List<Client>
    {
        new Client()
        {
            ClientId = "client",
            AllowedGrantTypes = GrantTypes.Implicit,// 隐式模式
            ClientSecrets =
            {
                new Secret("secret".Sha256())
            },

            RedirectUris = { "http://localhost:5001/signin-oidc" },
            PostLogoutRedirectUris = { "http://localhost:5001/signout-callback-oidc" },

            //AllowedScopes = {"api"},
            AllowedScopes =
            {
                IdentityServerConstants.StandardScopes.Profile,
                IdentityServerConstants.StandardScopes.OpenId,
            }
        }
    };
}
```

**客户端的 Controller 打上 Authorize 标签**

```
[Authorize]
public class HomeController : Controller
```

**修改客户端 launchSettings.json 中的 applicationUrl**

```
"applicationUrl": "http://localhost:5001",
"sslPort": 0
```

启动服务端，客户端，可以看到跳转到登录界面

![](/files/RBWCu6LEWu3QCM8ol2ib)

登录之后会跳转到 <http://localhost:5001/>

![](/files/shYz3YogZx1PVqyKT5HW)

**在客户端 About.cshtml 页面显示 identity 的 claims**

```
@{
    ViewData["Title"] = "About";
}
<h2>@ViewData["Title"]</h2>
<h3>@ViewData["Message"]</h3>

@*<p>Use this area to provide additional information.</p>*@

<dl>
    @foreach (var claim in User.Claims)
    {
        <dt>@claim.Type</dt>
        <dt>@claim.Value</dt>
    }
</dl>
```

启动程序，跳转之后，点击 About 进入 About 页面

![](/files/IKxpTkpk58tkSsQI4kLR)

主要返回了服务端 Config 中配置的信息

```
public static IEnumerable<IdentityResource> GetIdentityResources()
        {
            return new List<IdentityResource>
            {
                new IdentityResources.OpenId(),
                new IdentityResources.Profile(),
                new IdentityResources.Email(),
            };
        }
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://mingsonzheng.gitbook.io/aspnetcore-distributed-project-combat/oauth2-+-oidc-shi-xian-client-bu-fen.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
