Part-1 completely discussed the steps to generate the access token in the GraphQL endpoint. Now in this article, our main goals are to validate the JWT access token and also we try to understand authorization techniques in GraphQL.
Now test again by added the authorization header by providing our access token as its value.
Install JwtBearer Authentication NuGet:
Let's install JwtBearer Authentication NuGet to configure JwtBearer services.
.Net CLI Command: dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
Package Manager Command: Install-Package Microsoft.AspNetCore.Authentication.JwtBearer
Register JWT Validation Service:
Now we need to register the JwtBearer service to validate our access token on the user sending the access token as an authorization header.
Startup.cs:
using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.IdentityModel.Tokens; services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidIssuer = Configuration.GetSection("TokenSettings").GetValue<string>("Issuer"), ValidateIssuer = true, ValidAudience = Configuration.GetSection("TokenSettings").GetValue<string>("Audience"), ValidateAudience = true, IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration.GetSection("TokenSettings").GetValue<string>("Key"))), ValidateIssuerSigningKey = true }; });
- Here in the validation service, we can observe all the configurations that are used to create JWT access tokens are used here as well to validating our access token.
Register Authentication Middleware:
Now we need to configure authentication middleware just about the authorization middleware.
Startup.cs:
app.UseAuthentication(); app.UseAuthorization();
Install GraphQL Authorization Nuget:
Package Manager Command: Install-Package HotChocolate.AspNetCore.Authorization
.Net CLI Command: donet add package HotChocolate.AspNetCore.Authorization
Register GraphQL Authorization Service:
Now let's add an authorization service to the GraphQL service in the startup file.
Startup.cs:
services.AddGraphQLServer() .AddQueryType<QueryObjectType>() .AddMutationType<MutationObjectType>() .AddAuthorization();
Implement Basic Authorization On GraphQL Resolver Method:
In GraphQL authorization need to be added as an extension method on registering each resolver method as a field. If we recall Part-1, we have created 'Welcome' query, so now we are going to implement authorization for that 'Welcome' resolver method.
GraphQLModel/ObjectType/QueryObjectType.cs:
descriptor.Field(_ => _.Welcome()) .Name("Welcome").Type<StringType>() .Authorize();
- Here added 'Authorized' as an extension method.
Now test again by added the authorization header by providing our access token as its value.
Roles Based Authorization:
Role-based authorization is quite a common implementation to restrict the user or allow any particular set of users to consume the server resource. Roles are also claims of the user but its key name will be 'Role'.
First, let's add some roles to access tokens by updating the token generation method.
GraphQLCore/Mutation.cs:(UserLogin Method)
var claims = new Claim[] { new Claim(ClaimTypes.Role, "user") }; var jwtToken = new JwtSecurityToken( issuer: tokenSettings.Value.Issuer, audience: tokenSettings.Value.Audience, expires: DateTime.Now.AddMinutes(20), signingCredentials: credentials, claims: claims );
- Here will generating jwt token I'm updating the code to add a role called "user". Here I added static role value in a real-time application we need to fetch role data from the database.
GraphQLModel/ObjectType/QueryObjectType.cs:
descriptor.Field(_ => _.Welcome()).Name("Welcome") .Type<StringType>() .Authorize(new[]{"user","admin"});
- Here our 'Welcome' method can be consumed by users who had at least one of the roles specified in the 'Authorize' method.
Policy-Based Roles Authorization:
The policy is a set of rules. In the case of roles the policy will group the set of roles, so the user at least one role in the policy group then the user satisfied that policy.
Let's add the roles policy in the startup file.
Startup.cs:
services.AddAuthorization(options => { options.AddPolicy("user-policy", policy => { policy.RequireRole(new[] { "user", "admin" }); }); });Now update our resolver method to use the policy-based authorization.
GraphQLModel/ObjectType/QueryObjectType.cs:
descriptor.Field(_ => _.Welcome()) .Name("Welcome").Type<StringType>() .Authorize("user-policy");
- Here now we are passing the "user-policy" name as the input parameter to the 'Authorize' extension method.
Policy-Based Claims Authorization:
The Claims mean key-value pair of data which something like user information. To use claims-based authorization we need to write the policy for it, which means we can't use claims directly like we do in the case of roles.
Let's update the 'UserLogin' resolver method with the following claims.
GraphQLCore/Mutation.cs:(UserLogin Method)
var claims = new Claim[] { new Claim(ClaimTypes.Role, "user"), new Claim("usercountry","India") }; var jwtToken = new JwtSecurityToken( issuer: tokenSettings.Value.Issuer, audience: tokenSettings.Value.Audience, expires: DateTime.Now.AddMinutes(20), signingCredentials: credentials, claims: claims );
- Here we added claims like "usercountry" and its value as "India".
Startup.cs:
services.AddAuthorization(options => { options.AddPolicy("country-policy", policy => { policy.RequireClaim("usercountry"); }); });
- In this policy we are checking only "usercountry" claim is possessed by the user or not. Here we are not checking the value of the claim.
GraphQLModel/ObjectType/QueryObjectType.cs:
descriptor.Field(_ => _.Welcome()) .Name("Welcome").Type<StringType>() .Authorize("country-policy");Another way of writing a claims policy is by defining the values of the claim and then the user should have at least one claim value registered under the policy.
Startup.cs:
services.AddAuthorization(options => { options.AddPolicy("country-policy", policy => { policy.RequireClaim("usercountry","india","usa","japan"); }); });That's all about different Authorization techniques in GraphQL.
Video Session:
Support Me!
Buy Me A Coffee
PayPal Me
Wrapping Up:
Hopefully, I think this article delivered some useful information on the authorization techniques in the Hot Chocolate GraphQL endpoint. I love to have your feedback, suggestions, and better techniques in the comment section below.
Refer:
Part-1 Hot Chocolate GraphQL JWT(JSON Web Token) Authentication - Generating User Login Access Token
Is the source code available on GitHub
ReplyDelete