Tarun Ohri
Tarun Ohri

Reputation: 43

How to secure Asp.Net WebApi built in .Net Framework 4.x using IdentityServer4

I have my authentication server set up using Identity Server 4 but i am not able to consume the token issued by Identity Server 4 in my WebApi built in .Net framework 4.5.2. Although i am able to protect the Web Api built in Core.

Can anyone please guide me how to do that as our .Net Api is a legacy application and it is not possible for us to convert that into Core API.

Thanks in advance.

Best, Tarun Ohri

Upvotes: 2

Views: 2563

Answers (2)

Tarun Ohri
Tarun Ohri

Reputation: 43

@Mahesh More Please have a look at the code below and guide me where i am going wrong :

startup.cs

[assembly: OwinStartup(typeof(AspNet_4_5_2_API.Startup))]
namespace AspNet_4_5_2_API
{
public class Startup
{
    public void Configuration(IAppBuilder app)
    {

        IdentityServerBearerTokenAuthenticationOptions options = new IdentityServerBearerTokenAuthenticationOptions
        {
            Authority = "http://localhost:5000",
            AuthenticationType = "Bearer",
            RequiredScopes = new[] { "api1" }
        };
        app.UseIdentityServerBearerTokenAuthentication(options);
    }
}
}

API Controller Class

namespace AspNet_4_5_2_API.Controllers
{
[Route("identity")]
public class IdentityController : ApiController
{
    [HttpGet]
    public IHttpActionResult Get()
    {
        var identity = (ClaimsIdentity)User.Identity;
        IEnumerable<Claim> claims = identity.Claims;

        return Ok(claims);
    }
}
}

Client configuration in Identity Server Project

public static IEnumerable<ApiResource> GetApis()
    {
        return new List<ApiResource>
        {
            new ApiResource("api1", "My API")
        };
    }

    public static IEnumerable<Client> GetClients()
    {
        return new List<Client>
    {            
        // JavaScript Implicit Client
        new Client
        {
            ClientId = "client_id_js",
            AllowedGrantTypes = GrantTypes.Implicit,

            RedirectUris = { "http://localhost:5004/home/signin" },
            PostLogoutRedirectUris = { "http://localhost:5004/home/index" },
            AllowedCorsOrigins =     { "http://localhost:5004" },

            AllowedScopes =
            {
                IdentityServerConstants.StandardScopes.OpenId,
                IdentityServerConstants.StandardScopes.Profile,
                "api1", "tenant", "dateofbirth"
            },

            //AccessTokenLifetime = 1, //! second for testing
            AlwaysIncludeUserClaimsInIdToken = true,

            AllowAccessTokensViaBrowser = true,
            RequireConsent = false
        }
    };
    }

Javascript Client Code. In this callApi function is calling Web API project.

var config = {
userStore: new Oidc.WebStorageStateStore({ store: window.localStorage }),
authority: "http://localhost:5000",
client_id: "client_id_js",
redirect_uri: "http://localhost:5004/Home/SignIn",
response_type: "id_token token",
scope: "openid api1 dateofbirth tenant",
post_logout_redirect_uri: "http://localhost:5004/Home/Index"
};
var userManager = new Oidc.UserManager(config);

var signIn = function () {
userManager.signinRedirect();
};

var signOut = function () {
userManager.signoutRedirect();
};

userManager.getUser().then(user => {
console.log("user : ", user);
if (user) {
    axios.defaults.headers.common["Authorization"] = "Bearer " + user.access_token;
}
});


var callApi = function () {
axios.get("http://localhost:59502/api/identity").then(result => {
    console.log(result);
});
};

var refreshing = false;

axios.interceptors.response.use(
function (response) { return response; },
function (error) {
    console.log("axios error: ", error.response);

    var axiosConfig = error.response.config;

    // if error response is 401 try to refresh token
    if (error.response.status === 401) {
        console.log("axios error 401");
        // if already refreshing dont make another request
        if (!refreshing) {
            console.log("starting token refresh");
            refreshing = true;

            // do the refresh
            return userManager.signinSilent().then(user => {
                console.log("new user:", user);

                //update the http request and client
                axios.defaults.headers.common["Authorization"] = "Bearer " + user.access_token;
                axiosConfig.headers["Authorization"] = "Bearer " + user.access_token;

                //retry the http request
                return axios(axiosConfig);
            });
        }
    }

    return Promise.reject(error);
}
);

Upvotes: 0

Mahesh More
Mahesh More

Reputation: 855

I believe that you are looking for middleware that will validate your token in WebApi. I was facing this issue a few days ago where I was not able to install IdentityServer4.AccessTokenValidation NuGet package as it's been developed in .NET core.

So I found a workaround for it. You can install IdentityServer3.AccessTokenValidation NuGet package to validate your ID4 token in WebApi. Please see below sample code for more details:

Startup.cs

public void Configuration(IAppBuilder app)
        {

                IdentityServerBearerTokenAuthenticationOptions options = new IdentityServerBearerTokenAuthenticationOptions
                {
                    Authority = "Identity Server 4 base URL",
                    AuthenticationType = "Bearer",
                    RequiredScopes = "Scopes (space separated)"
                };
          app.UseIdentityServerBearerTokenAuthentication(options);
        }

Note: UseIdentityServerBearerTokenAuthentication middleware will validate your request. I hope this will help you to resolve your issue.

Upvotes: 1

Related Questions