IdentityServer4 授权配置AllowedScopes实例

来源:这里教程网 时间:2026-02-21 15:01:25 作者:

1. 业务场景

identityserver4 授权配置

client
中的
allowedscopes
,设置的是具体的 api 站点名字,也就是使用方设置的
apiname
,示例代码:

//授权中心配置new Client
{
    ClientId = "client_id_1",
    AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
    AllowOfflineAccess = true,
    AccessTokenLifetime = 3600 * 6, //6小时SlidingRefreshTokenLifetime = 1296000, //15天ClientSecrets =
    {new Secret("secret".Sha256())
    },
    AllowedScopes = 
    {"api_name1"},
}//API 服务配置app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
{
    Authority = $"http://localhost:5000",
    ApiName = "api_name1",
    RequireHttpsMetadata = false});

上面两个

api_name1
配置要一致,问题来了,因为授权中心的
scope
配置是整个 API 服务,如果我们存在多个
Client
配置,比如一个前台和后台,然后都需要访问
api_name1
,就会出现一些问题。

比如,

api_name1
服务中的一个接口服务配置代码:

[Authorize()]
[Route("api/values")]
[HttpGet]public IActionResult Get()
{return Ok();
}

Authorize()
的配置,说明
api/values
接口需要授权后访问,如果授权中心配置了两个
Client
(前台和后台),并且
scope
都包含了
api_name1
,现在就会出现两种情况:

    前台

    Client
    和后台
    Client
    ,都需要授权后访问
    api/values
    接口:没有问题。

    前台

    Client
    不需要授权后访问,后台
    Client
    需要授权后访问:有问题,前台
    Client
    没办法访问了,因为
    api/values
    接口设置了
    Authorize()

其实,说明白些,就是该如何让 API 服务指定

Client
授权访问?比如:
[Authorize(ClientId = 'client_id_1')]

2. 解决方案

没有

[Authorize(ClientId = 'client_id_1')]
这种解决方式,不过可以使用
[Authorize(Roles = 'admin')]

授权中心的

ResourceOwnerPasswordValidator
代码,修改如下:

public class ResourceOwnerPasswordValidator : IResourceOwnerPasswordValidator
{private readonly IUserService _userService;public ResourceOwnerPasswordValidator(IUserService userService)
    {
        _userService = userService;
    }public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context)
    {var user = await _userService.Login(context.UserName, context.Password);if (user != null)
        {var claims = new List<Claim>() { new Claim("role", "admin") }; //根据 user 对象,设置不同的 rolecontext.Result = new GrantValidationResult(user.UserId.ToString(), OidcConstants.AuthenticationMethods.Password, claims);
        }
    }
}

授权中心的

startup
配置,修改如下

var builder = services.AddIdentityServer();
builder.AddTemporarySigningCredential()//.AddInMemoryIdentityResources(Config.GetIdentityResources()).AddInMemoryApiResources(new List<ApiResource>
        {new ApiResource("api_name1", "api1"){ UserClaims = new List<string> {"role"}}, //增加 role claimnew ApiResource("api_name2", "api2"){ UserClaims = new List<string> {"role"}}
        })
        .AddInMemoryClients(Config.GetClients());

API 服务接口,只需要配置如下:

[Authorize()]
[Route("api/values")]
[HttpGet]public IActionResult Get()
{return Ok();
}
[Authorize(Roles = "admin")]
[Route("api/values2")]
[HttpGet]public IActionResult Get2()
{return Ok();
}
[Authorize(Roles = "admin,normal")]
[Route("api/values3")]
[HttpGet]public IActionResult Get3()
{return Ok();
}

需要注意的是,

api/values
接口虽然没有设置具体的
Roles
,但每个
Role
都可以访问。

相关推荐