How to Secure Your .NET Web API with Token Authentication

leebrandt

I will put this on the list and try to get one out very quickly. I haven’t upgraded my box to 2.2 yet. And 3.0 is almost out! :smiley:

leebrandt

I have fixed the write up to amend the security section to add this. thanks @goobering!

Narayana katooru

What is your suggestion on API client itself generating token and sending as part of GET requests? instead of passing secret id and secret answer over the wire? do you see any disadvantage or security risk with this approach? For me it looks like more hassle for client to generate token on its own unless server provides an console to generate token ( Like how crircleCI does it)

leebrandt

https://developer.okta.com/… This might be what you’re looking for.

leebrandt

I think this depends on how you’re using your API. If you are creating an API for your private consumption (the only client being your client/spa app) then I think just having your API store it’s own client id and secret is fine. You’ll probably only have your client app authenticate users and sending the user’s token and delegating authority to your API.

If you’re creating an API to make it public and be able to control access to everyone’s client apps, then they will likely be sending a client id and secret to get an access token, then just sending the access token with each request.

Hope that helps.

Narayana katooru

Okay. Thank you

lhudson2

Hi Lee, do you have a working sample application and API that demonstrates this in GitHub? Would be helpful if you did.

Vijay Ganapathy

You are awesome! Worked!

Vijay Ganapathy

Hey Lee,

Thanks for the article, helped me very much! I see that the TokenService is configured as singleton and if a valid token exists then the GetToken method returns that instead of creating a new one. If I have two consumers, both servers with different clientid and secret, this setup I believe could return one consumer’s token to another. In such cases, what’s the best way to handle this? Should I change the TokenService to be transient? Any other better ways of handling this?

Vijay Ganapathy

Another question, if I have two consumers and I want to provide one consumer access and deny access to other consumer for a specific endpoint, how do I do that? Since just by decorating with the [Authorization] attribute does it all, how do I restrict access?

Rosario Martone

Hi all, just a quick stupid question. I have implemented the API as for the example and I am getting 401 while launching the API from Visual Studio. My issue is on POSTMAN, I am not able to provide the client id and ClientSecret and always getting 401. Any tip? Please! :slight_smile:

Luke Konecki

I can get a token with Postman no problem but with this code I am getting the error ”An existing connection was forcibly closed by the remote host” right away. Has anyone run into this issue before?

bigjump

This didn’t work for me initially either - I was getting an invalid_scope error.- "The authorization server resource does not have any configured default scopes, ‘scope’ must be provided."

This article helped me figure it out - https://developer.okta.com/…

"The Client Credentials grant type requires us to define a custom scope."

You just need to add a new scope to the Authorization Server and request using that new scope.

Castellionee

After getting the correct Token
/api/UserBasicInfo?access_token={THE TOKEN}

I still receive http error 401.
What Am I missing??
It has been days and I’m running in circles.
Your help is really appreciated.

Patrik Rose

Followed all the steps in this tutorial. One issue though
In GetNewAccessToken() this line:
var json = await response.Content.ReadAsStringAsync();
returns this HTML and not JSON:
<noscript>
<div id=“noscript-msg” class=“noscript-msg”>
<div class=“noscript-content”>
<h2>Javascript is required</h2>
<h1>Javascript is disabled on your browser. Please enable Javascript and refresh this page.</h1>
Refresh
</div>
</div>
</noscript>

This causes an exception to be thrown.

dennis602

Can you show how to call this from Postman? How would you pass in the clientid and secret from postman? Trying to see what is returned using postman.

Tim H

As per the instructions, I have my TokenUrl as “https://dev-xxxxxx.okta.com…”, but I am getting a 400: Bad Request returned when requesting a token. Is this URL correct?

Above, it is mentioned that one can find the URLs in the Admin portal: “…going to the dashboard and hovering over the API menu item in the menu bar, then choosing Authorization Servers from the drop down menu”. This yields the authority URL: https://dev-XXXXXX.okta.com….

Any help would be appreciated.

Vikas Verma

Check token API in Postman to find exact error. If the error is “invalid scope” you need to add access_token as scope in okta application(as mentioned in below comments)
API =>Authorization Servers => default (your app) => Scopes tab. Add access_token.

Vikas Verma

Getting 401, Unauthorized. Even after following the post as is and adding app.UseAuthentication()

{StatusCode: 401, ReasonPhrase: ‘Unauthorized’, Version: 1.1, Content: System.Net.Http.HttpConnectionResponseContent, Headers:
{
Transfer-Encoding: chunked
Server: Microsoft-IIS/10.0
WWW-Authenticate: Bearer
X-Powered-By: ASP.NET
Date: Tue, 07 Jul 2020 16:54:45 GMT
}}

Tommy Wu

1. Create a new request and change the Request Type to POST. (upper left)
2. Select the Authorization tab (below the word POST and to the right of Params)
3. In the dropdown below TYPE, select OAuth 2.0
4. A orange Get New Access Token should show.
5. Click that Get New Access Token button and fill in the info from your okta org into the form you see below.

https://uploads.disquscdn.c…