微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

IdentityServer4 授权配置AllowedScopes实例

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,现在就会出现两种情况:

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

  2. 前台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都可以访问。

原文地址:https://www.jb51.cc/csharp/1193775.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐