Reputation: 876
I have an authentication service built on IdentityServer3 and a WebAPI Shopper service that is secured with IdentityServer Bearer Token Authentication. I've built a simple MVC client app that can access the Shopper service either as a client app with an access token or on behalf of an authenticated user with an identity token. The Shopper service will return more data to the authenticated user. Now I'm trying to build a JavaScript client that does the same two-tier level of access to the Shopper service. So far, following some IdentityServer3 JavaScript client examples, I've got the JS client successfully calling the Shopper service on behalf of an authenticated user. (I will probably need to reorganize the code a bit to accommodate the non-authenticated scenario, but that shouldn't be too difficult.) What I don't know how to do from the JavaScript code is request the client access token from the Authentication service, i.e. the JavaScript equivalent of the server-side TokenClient.RequestClientCredentialsAsync("shopper-service") in the MVC client. Does anyone know how to request that token from JavaScript or know of a sample that shows how to do it? Here's the JavaScript code that I have so far for the authenticated case and below that is the working MVC client code:
function display(selector, data) {
if (data && typeof data === 'string') {
data = JSON.parse(data);
}
if (data) {
data = JSON.stringify(data, null, 2);
}
$(selector).text(data);
}
var settings = {
authority: 'https://localhost:44332',
client_id: 'js-sample',
popup_redirect_uri: 'http://localhost:15264/popup.html',
response_type: 'id_token token',
scope: 'openid orvis-shopper-service',
filterProtocolClaims: false
};
var manager = new Oidc.UserManager(settings);
var user;
manager.events.addUserLoaded(function (loadedUser) {
user = loadedUser;
display('.js-user', user);
});
$('.js-login').on('click', function () {
manager
.signinPopup()
.catch(function (error) {
console.error('error while logging in through the popup', error);
});
});
$('.js-call-api').on('click', function () {
var headers = {};
if (user && user.access_token) {
headers['Authorization'] = 'Bearer ' + user.access_token;
}
$.ajax({
url: 'https://localhost:44368/api/Shopper/{5FA13934-AD20-4AB2-A386-11653D71AE55}',
method: 'GET',
dataType: 'json',
headers: headers
}).then(function (data) {
display('.js-api-result', data);
}).catch(function (error) {
display('.js-api-result', {
status: error.status,
statusText: error.statusText,
response: error.responseJSON
});
});
});
The client app code works as I intend and looks like this:
public async Task<ActionResult> Index()
{
string tokenValue;
var user = User as ClaimsPrincipal;
if (user.Identity.IsAuthenticated)
{
tokenValue = user.FindFirst("access_token").Value;
}
else
{
var tokenResponse = await GetTokenAsync();
tokenValue = tokenResponse.AccessToken;
}
var result = await CallShopperService(tokenValue);
ViewBag.Json = result;
return View();
}
private async Task<TokenResponse> GetTokenAsync()
{
var client = new TokenClient(
"https://localhost:44332/connect/token",
"mvc-sample-svc",
"mvcsamplesecret");
return await client.RequestClientCredentialsAsync("shopper-service");
}
private async Task<string> CallShopperService(string token)
{
var client = new HttpClient();
client.SetBearerToken(token);
var json = await client.GetStringAsync("https://localhost:44368/api/Shopper/{5FA13934-AD20-4AB2-A386-11653D71AE55}");
return json;
}
Upvotes: 0
Views: 1687
Reputation: 740
JS implicit client is also able to get back you access token, as long as you set token
in response_type
which you did according to your pasted script.
The Oidc-client.js builds up an authorize challenge URL and redirect browser to it, which is where login flow begins. After user signs in, then they get bounced back to your client page following same redirect path. When your client page loaded (depends on which flow your client is configured, it should be hash fragment by default), oidc-client grabs token from URL (everything after #
) and transforms it into JSON object then save in local storage (which means you can check it there too).
I would suggest following method to help you debug:
Turn on traffic monitoring tool (e.g. fiddler) to ensure response that returned back from your identity server after login does contains access token (you can decode token string using https://jwt.io/), if not, check if authorize request url formed correctly
If response returned from identity server does contains access token , then you can debug oidc-client.js javascript by setting a breakpoint at _signinEnd
method
Hope it helps
Updated, from comment section
For "anonymous token" senario? See this example if that is what you are looking for github.com/IdentityServer/IdentityServer3/issues/1953
Upvotes: 0