创建IdentityServer (3)

该项目使用dotnet版本3.1 ,vs code创建

创建Web MVC项目

创建命令

dotnet new mvc --name WebMvc

修改./properties/launchSettings.json

"profiles": {
    "WebApi": {
      "commandName": "Project",
      "launchBrowser": true,
      "launchUrl": "weatherforecast",
      "applicationUrl": "http://localhost:5002",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
  }

添加登录验证

运行下面命令安装

dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer --version 3.1.0
dotnet add package Microsoft.AspNetCore.Authentication.OpenIdConnect --version 3.1.0

在startup.cs中的ConfigureServices类中添加

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();     // 关闭了JWT的Claim 类型映射, 以便允许well-known claims.

services.AddAuthentication(options =>   // 将身份验证服务添加到DI
    {
        options.DefaultScheme = "Cookies";      // 使用cookie来登录用户
        options.DefaultChallengeScheme = "oidc";        // 登录时使用OpenID Connect
    })
    .AddCookie("Cookies")
    .AddOpenIdConnect("oidc", options =>    // 配置执行OpenID Connect
    {
        options.Authority = "http://localhost:5000";    // IdentityServer地址
        options.RequireHttpsMetadata = false;       // 是否需要HTTPS

        options.ClientId = "mvc";
        options.SaveTokens = true;
    });

在startup.cs中的Configure类中添加 认证中间件

app.UseAuthentication();

然后在HomeController中Privacy添加 Authorize属性

然后AuthServer程序中的config.cs文件中将client修改如下

new Client
{
    ClientId = "mvc",
    ClientName = "MVC Client",

    AllowedGrantTypes = GrantTypes.Implicit,
    // AllowedGrantTypes = GrantTypes.CodeAndClientCredentials,
    // RequirePkce = true,
    // ClientSecrets = { new Secret("49C1A7E1-0C79-4A89-A3D6-A37998FB86B0".Sha256()) },

    RedirectUris = { "http://localhost:5002/signin-oidc" },     // login
    // FrontChannelLogoutUri = "http://localhost:5003/signout-oidc",       
    PostLogoutRedirectUris = { "http://localhost:5002/signout-callback-oidc" },     // logout

    AllowOfflineAccess = true,
    AllowedScopes = { "openid", "profile", "api1" }
},

在./view/home/Privacy.cshtml添加如下代码来显示登录成功的用户信息

@using Microsoft.AspNetCore.Authentication
<h2>Claims</h2>
<div>
    <strong>id_token</strong>
    <span>@await ViewContext.HttpContext.GetTokenAsync("id_token")</span>
</div>
<div>
    <strong>access_token</strong>
    <span>@await ViewContext.HttpContext.GetTokenAsync("access_token")</span>
</div>
<dl>
    @foreach (var claim in User.Claims)
    {
        <dt>@claim.Type</dt>
        <dd>@claim.Value</dd>
    }
</dl>

开启AuthServer 和 WebMvc 程序,访问 http://localhost:5002/ ,点击 Privacy 会跳到AuthServer的登录页面

创建IdentityServer (3)

输入账号 bob 密码 bob 后跳到如下页面

创建IdentityServer (3)

点击YES后重定向返回 Privacy 页面,可以看到返回的信息,但access_token没有返回

创建IdentityServer (3)

原因需要在上述修改的AuthServer文件中config的client加上

AllowAccessTokensViaBrowser = true

还要在WebMvc文件中的startup的 ConfigureServices 的 AddOpenIdConnect 加上

options.ResponseType = "id_token token";

重启两个程序,退出登录(登出功能在下文),重新登录即可

创建IdentityServer (3)

登出

在HomeController类中添加

public IActionResult Logout()
{
    return SignOut("Cookies", "oidc");
}

在view/shared/_layout.cshtml添加

<li class="nav-item">
     <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Logout">logout</a>
</li>

重启服务,刷新页面,点击logout,会跳到AuthServer的登出页面

创建IdentityServer (3)

提供access token和refresh tokens来访问api

使用refresh tokens来重新获取新的access token,确保会话不会断

首先,将AuthServer项目的config文件中client修改如下

new Client
{
    ClientId = "mvc",
    ClientName = "MVC Client",

    AllowedGrantTypes = GrantTypes.Hybrid,      // GrantTypes.HybridAndClientCredentials 也可以
    ClientSecrets = { new Secret("secret".Sha256()) },

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

    AllowOfflineAccess = true,
    AllowedScopes = { "openid", "profile", "api1" },
    AllowAccessTokensViaBrowser = true      
},

然后在WebMvc项目的startup文件中的ConfigureServices修改如下

.AddOpenIdConnect("oidc", options =>    // 配置执行OpenID Connect
{
    options.Authority = "http://localhost:5000";    // IdentityServer地址
    options.RequireHttpsMetadata = false;       // 是否需要HTTPS
    options.SignInScheme = "Cookies";

    options.ClientId = "mvc";
    options.SaveTokens = true;
    options.ResponseType = "id_token code";
    options.ClientSecret = "secret";
    options.GetClaimsFromUserInfoEndpoint = true;

    options.Scope.Add("api1");
    options.Scope.Add("offline_access");
});

在WebMvc项目view/home/privacy.cshtml中添加

<div>
    <strong>refresh_token</strong>
    <span>@await ViewContext.HttpContext.GetTokenAsync("refresh_token")</span>
</div>

运行

登录后,显示多出refresh_token

创建IdentityServer (3)

创建IdentityServer (3)

打开postman使用refresh_token(注意:只能使用一次)来重新获取access token

创建IdentityServer (3)

上一篇:ABP框架使用(版本3.3.1) - IdentityServer


下一篇:Ocelot(四)- 认证与授权