Adding a Web API

In the previous section, we implemented CAS and added an MVC web application. We used the implicit flow that returns the token to the client through the browser, which can be used by the client for further subsequent requests. However, APIs exposing the tokens over a browser channel is not a recommended approach, and there should be a mechanism that uses the client ID and secret to retrieve the access token and then use it to invoke secure methods.

IdentityServer4 introduces a new flow called Hybrid Flow, which is a combination of both OpenID and OAuth2.0 protocols. In this flow, the Identity token is transmitted via the browser channel on successful user authentication, whereas the access token is retrieved by the client through a backend channel.

In this section, we will modify the authorization server's grant type to HybridAndClientCredentials and add the client secret property. This client secret property will be used by the client, which can be used for subsequent API requests.

Here is the updated GetClients method, in which we have added the grant type to HybridAndClientCredentials for API clients and added two more properties, the client secret that denotes a password user by the client to retrieve the access token and a new scope of vendor API that we will use later in this section:

    public static IEnumerable<Client> GetClients() 
{
return new List<Client>
{
new Client
{
ClientId = "client",
ClientName ="MVC Client",
AllowedGrantTypes= GrantTypes.Implicit,
RedirectUris = { "http://localhost:5002/signin-oidc"
},
PostLogoutRedirectUris= {"http://localhost:5002"},
Enabled=true,
AccessTokenType= AccessTokenType.Jwt,
AllowedScopes =new List<string>
{
StandardScopes.OpenId,
StandardScopes.Profile,
StandardScopes.Email,
StandardScopes.OfflineAccess,
"role"
}
},


new Client
{
ClientId = "clientApi",
ClientName ="MVC Client API",
ClientSecrets= { new Secret("secretkey".Sha256())},
AllowedGrantTypes = GrantTypes.
HybridAndClientCredentials,

RedirectUris = {
"http://localhost:5003/signin-oidc" },
PostLogoutRedirectUris= {"http://localhost:5003"},
Enabled=true,
AccessTokenType= AccessTokenType.Jwt,
AllowedScopes =new List<string>
{
StandardScopes.OpenId,
StandardScopes.Profile,
StandardScopes.Roles,
StandardScopes.OfflineAccess,
"vendorManagementAPI"
}
}
};
}

Once this is set up, add a new Web API project and create the HomeController (MVC controller) and VendorManagementController (API controller). Here is the sample VendorManagementController that contains some methods to get the list of all vendors, get vendor by ID, create vendor, update, and delete vendor:

    [Route("api/[controller]")] 
public class VendorManagementController : Controller
{
[HttpGet]
public IEnumerable<Vendor> GetVendors(){

//Returning static values
return new List<Vendor>
{
new Vendor { VendorID=1, Name="Bentley",
Email="[email protected]", PhoneNo="+12012020030",
Website="www.bentley.com" },
new Vendor { VendorID=2, Name="Mercedez",
Email="[email protected]", PhoneNo="+1201203300",
Website="www.mercedez.com" },
new Vendor { VendorID=3, Name="BMW",
Email="[email protected]", PhoneNo="+12014500030",
Website="www.bmw.com" },
new Vendor { VendorID=4, Name="Lamborghini",
Email="[email protected]",
PhoneNo="+12022220030",
Website="www.lamborghini.com"
},
new Vendor { VendorID=5, Name="Nissan",
Email="[email protected]", PhoneNo="+13312020030",
Website="www.nissan.com" }
};


}

[HttpGet("{id}")]
public Vendor GetVendor(int id){ }

[HttpPost]
public int CreateVendor(Vendor vendor){return -1;}

[HttpPut]
public int UpdateVendor(Vendor vendor){return -1;}

[HttpDelete]
public int DeleteVendor(int vendorID){return -1;}
}

The HomeController is as follows. There are two methods, Index, which will display the page, and the CallAPI method which calls the VendorManagementController GetVendors method:

    public class HomeController : Controller 
{

[Authorize]
// GET: /<controller>/
public async Task<IActionResult> Index()

{
return View();
}


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

var client = new HttpClient();
client.SetBearerToken(accessToken);
var content = await client.GetStringAsync(
"http://localhost:5003/api/vendormanagement");

ViewBag.Json = content;
return View();
}
}

Once we run the application, it will ask for the username and password and show the consent screen on successful authentication, as shown in the following screenshot:

If you notice, on the consent screen, it asks you to allow offline access and Vendor API, which was added as the scope while defining the client on the authorization server. Finally, when we call http://localhost:5003/Home/CallAPI it will get the access token and access the VendorManagementController that returns the vendor list.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.223.171.168