1. Business Scenarios
IdentityServer4 in the authorization configuration Client
AllowedScopes
, set the specific API site name, which is the user-set ApiName
, sample code:
Authorization Center Configuration new client{ ClientId = "Client_id_1", allowedgranttypes = Granttypes.resourceownerpassword, Allowofflineaccess = True, accesstokenlifetime = 3600 * 6,//6 hours slidingrefreshtokenlifetime = 1296000,// 15 days Clientsecrets = {new Secret ("Secret"). Sha256 ()) }, allowedscopes = {"api_name1"},}//API service configuration app. Useidentityserverauthentication (new identityserverauthenticationoptions{ authority = $ "http://localhost:5000 ", apiname =" Api_name1 ", Requirehttpsmetadata = false});
The above two api_name1
configurations to be consistent, the problem comes, because the authorization center scope
configuration is the entire API service, if we have multiple Client
configurations, such as a foreground and background, and then need access api_name1
, there will be some problems.
For example, api_name1
an interface service configuration code in the service:
[Authorize ()] [Route ("Api/values")] [Httpget]public iactionresult Get () {return Ok ();}
Authorize()
Configuration, which indicates that the api/values
interface requires access after authorization, if the authorization center is configured with two Client
(foreground and background), and scope
both are included, there are api_name1
two scenarios:
Front Client
and back office Client
, both require authorization after Access api/values
interface: no problem.
Front desk Client
does not need authorization after access, background Client
need authorization after access: There is a problem, the front desk has Client
no way to access, because the api/values
interface set up Authorize()
.
In fact, the explanation is white, is how to let the API service specify Client
authorized access? For example: [Authorize(ClientId = 'client_id_1')]
.
2. Solution
There is no [Authorize(ClientId = 'client_id_1')]
such solution, but it can be used [Authorize(Roles = 'admin')]
.
The code for the Authorization center is ResourceOwnerPasswordValidator
modified as follows:
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")};//According to the user object, set different R Olecontext. Result = new Grantvalidationresult (user. Userid.tostring (), OidcConstants.AuthenticationMethods.Password, claims);}}
The configuration of the authorization center is startup
modified as follows
var builder = Services. Addidentityserver (); builder. Addtemporarysigningcredential ()//. Addinmemoryidentityresources (Config.getidentityresources ()). Addinmemoryapiresources (New list<apiresource> {new Apiresource ("Api_name1", "Api1") {userclaims = new List <string> {"Role"}},//Add role claimnew Apiresource ("Api_name2", "Api2") {userclaims = new list<string> {"Role "}} }) . Addinmemoryclients (Config.getclients ());
API Service interface, you only need to configure the following:
[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 ();}
It is important to note that api/values
although the interface is not set up specifically Roles
, it Role
can be accessed by each.