Skip to main content

保护ASP.net Core应用和API

分类:  IdentityServer4教程 标签:  #Asp.Net core基础 #认证 #授权 #Identity Server #OpenId Connect #OAuth2 发布于: 2023-05-27 22:42:21

我们前面两节讨论和两个应用场景,使用一个客户端通过取得access token访问api, 和一个使用mvc的应用通过交互式登录存取访问Mvc应用,我们本节将使得我们新创建的MvcClient除了交互式认证之外,还要可以在MvcClient中访问API。

IdentityServer4同时支持QAuth2.0和OpenId Connect两种协议,在上一个章节里我们仅仅返回给用户标识资源(CliamPrinpcal, Id Token), 如果我们在配置的时候指定API的Scope, 那么IdentityServer4会同时返回两种token: Id Token 和 Access Token。

修改IdentityServer的Client配置

更改配置非常简单,只需要添加api1这个scope就可以了,为了允许使用refresh token我们还需要启用AllowOffineAccess属性。

{
    ClientId = "mvc",
    ClientSecrets = { new Secret("secret".Sha256()) },

    AllowedGrantTypes = GrantTypes.Code,

    // where to redirect to after login
    RedirectUris = { "https://localhost:5002/signin-oidc" },

    // where to redirect to after logout
    PostLogoutRedirectUris = { "https://localhost:5002/signout-callback-oidc" },

    AllowOfflineAccess = true,

    AllowedScopes = new List<string>
    {
        IdentityServerConstants.StandardScopes.OpenId,
        IdentityServerConstants.StandardScopes.Profile,
        "api1"
    }
}

修改MvcClient应用

除了配置了IdentityServer, 我们还需要在MvcClient的应用启用OIDC特性时添加需要访问的scope, 如下:

services.AddAuthentication(options =>
{
    options.DefaultScheme = "Cookies";
    options.DefaultChallengeScheme = "oidc";
})
    .AddCookie("Cookies")
    .AddOpenIdConnect("oidc", options =>
    {
        options.Authority = "https://localhost:5001";

        options.ClientId = "mvc";
        options.ClientSecret = "secret";
        options.ResponseType = "code";

        options.SaveTokens = true;

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

需要注意的是,因为我们开启了特性SaveTokensASP.net Core应用的会话中存储Refresh token和存取的结果。

使用Access Token

通过名称空间Microsoft.AspNetCore.Authentication中的HttpContext的扩展方法GetTokenAsync来存取Access Token:

var accessToken = await HttpContext.GetTokenAsync("access_token");

为了存取API, 完整的代码如下:

public async Task<IActionResult> CallApi()
{
    var accessToken = await HttpContext.GetTokenAsync("access_token");

    var client = new HttpClient();
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
    var content = await client.GetStringAsync("https://localhost:6001/identity");

    ViewBag.Json = JArray.Parse(content).ToString();
    return View("json");
}

管理Access Token

当前一些复杂的应用都要求对Access Token进行管理,例如:

  • 在登录的时候请求Access Token和Refresh token
  • 缓存返回的Token
  • 使用access token存取API
  • 使用refresh token得到一个新的access token
  • 重复登录,获取token, 应用token整个流程。

ASP.net Core提供了多种内置的工具帮助管理和维护token, 但是还是有很多其他的工作需要好好设计,可以参考IdentityModel