Search code examples
javascriptidentityserver4openid-connectusermanager

Add a JavaScript client to IdeniityServer4 & logging using username & password


My Problem statement is: The user will login to IdentityServer, invoke the web API with an access token issued by IdentityServer, and logout of IdentityServer. All of this will be driven from the JavaScript running in the browser.

The closest link I found was https://docs.identityserver.io/en/latest/quickstarts/4_javascript_client.html

I request you to go through the link before answering. Now, I have an API /connect/token which takes username, password, client_id, client_secret, scope & grant_type & returns an access_token & then I use that access token for every other request as Authorisation bearer.

How do I integrate my API with OIDC using UserManager?

The link says that it logs the user in using the below code but I'm not able to comprehend how does it sign in the user without taking its credentials?

var config = {
    authority: "https://localhost:5001",
    client_id: "js",
    redirect_uri: "https://localhost:5003/callback.html",
    response_type: "code",
    scope:"openid profile api1",
    post_logout_redirect_uri : "https://localhost:5003/index.html",
};
var mgr = new Oidc.UserManager(config);

Next, the UserManager provides a getUser API to know if the user is logged into the JavaScript application. It uses a JavaScript Promise to return the results asynchronously. The returned User object has a profile property which contains the claims for the user. Add this code to detect if the user is logged into the JavaScript application:

mgr.getUser().then(function (user) {
    if (user) {
        log("User logged in", user.profile);
    }
    else {
        log("User not logged in");
    }
});

Next, we want to implement the login, api, and logout functions. The UserManager provides a signinRedirect to log the user in, and a signoutRedirect to log the user out. The User object that we obtained in the above code also has an access_token property which can be used to authenticate to a web API. The access_token will be passed to the web API via the Authorization header with the Bearer scheme. Add this code to implement those three functions in our application:

function login() {
    mgr.signinRedirect();
}

function api() {
    mgr.getUser().then(function (user) {
        var url = "https://localhost:6001/identity";

        var xhr = new XMLHttpRequest();
        xhr.open("GET", url);
        xhr.onload = function () {
            log(xhr.status, JSON.parse(xhr.responseText));
        }
        xhr.setRequestHeader("Authorization", "Bearer " + user.access_token);
        xhr.send();
    });
}

function logout() {
    mgr.signoutRedirect();
}

I'm looking for something like this(In response mgr should contain the user & access_token):

var config = {
    authority: "https://localhost:5001/connect/token",
    **username: "Username",
    password: "Password",**
    client_id: "js",
    redirect_uri: "https://localhost:5003/callback.html",
    response_type: "code",
    scope:"openid profile api1",
    post_logout_redirect_uri : "https://localhost:5003/index.html",
};
var mgr = new Oidc.UserManager(config);

Solution

  • What you are trying to achieve will not be possible. IdentityServer4 is based on OAuth2 and the idea is that the user will not have to input his credentials inside your client application but only on the login page of the authorization authority.

    mgr.signinRedirect() redirects the user to the login page of the authority where the user signs in. Throughout the complete login process your application itself does not handle the users credentials but only receives the token as a result. This is a base idea of OAuth2.

    With the token then you will be still able to obtain the exposed user information with the mgr.getUser() function.