I have a Webservice class. It has methods like AddStudnet, RemoveStudnet, UpdateStudent etc. These methods take parameters like StudentID, FirstName, LastName etc. All these methods have one common parameter - Api Key. The constructor does not take any parameters. So, in all my methods I'm authenticating the Api Key. If it's not a valid key an error message is returned.
Instead of authenticating in every method, how can I authenticate the api key in the constructor and prevent the object from getting instantiated? When I was researching on preventing the object from getting instantiated I came across throwing exceptions. If I go with throwing exceptions, will the webservice be exposed to any security vulnerabilities? Is there a different approach to prevent the object from getting instantiated if a invalid api key is passed?
Here is two article that will give you a kick start and show you basic implementation of API Key :
First by Ron Jacob :
How to do API key Verification
Second, How to use the API Key with the constructor:
How To Authenticate API Key In The Constructor
Most important thing is to verified the key in each call with this :
InstanceContextMode = InstanceContextMode.PerCall
That line of code is forcing a call to the constructor on every request, so every request the API is verified.
Hope that help you.
Related
I'm performing some logging in our ASP.NET app, using a custom ActionFilterAttribute. I'm adding logging for both the income info (via OnActionExecuting), and outgoing (via OnActionExecuted).
We have a call token (GUID) that I have access to in OnActionExecuting, and is part of the information being logged. I'd like the same token to be used in the logging done in OnActionExecuted.
My questions:
Is one instance of ActionFilterAttribute created for each incoming call?
Is this the same instance used for both OnActionExecuting & OnActionExecuted (allowing me to store the token as a member variable)?
Since no one has replied, and I got an answer through my own testing, I thought I'd post an Answer here.
It turns out that an instance of the action filter is created and shared among various controller action calls. Therefore using a member variable to share common data between a request (setting it in OnActionExecuting) and a response (reading it in OnActionExecuted) is NOT a reliable means on accomplishing what I intended.
just another question about the correct usage of HttpClient, because unless i am missing something, I find contradicting information about HttpClient in Microsoft Docs. These two links are the source of my confusion:
https://learn.microsoft.com/en-us/azure/architecture/antipatterns/improper-instantiation/#how-to-fix-the-problem
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-3.1#typed-clients
First one states that the best approach is a shared singleton HttpClient instance, the second that the AddHttpClient<TypedClient>() registers the service as transient, and more specifically (copied from that URL):
The typed client is registered as transient with DI. In the preceding
code, AddHttpClient registers GitHubService as a transient service.
This registration uses a factory method to:
Create an instance of HttpClient.
Create an instance of GitHubService, passing in the instance of HttpClient to its constructor.
I was always using AddHttpClient<TypedClient>() and feeling safe, but now i am puzzled again... And making things worse, I found this github issue comment by #rynowak which states:
If you are building a library that you plan to distribute, I would
strongly suggest that you don't take a dependency on
IHttpClientFactory at all, and have your consumers pass in an
HttpClient instance.
Why this is important to me? Because, I am in a process of creating a library that mainly does two things:
Retrieve an access token from a token service (IdentityServer4)
Use that token to access a protected resource
And I am following the typed clients approach described in the link 2 above:
//from https://github.com/georgekosmidis/IdentityServer4.Contrib.HttpClientService/blob/master/src/IdentityServer4.Contrib.HttpClientService/Extensions/ServiceCollectionExtensions.cs
services.AddHttpClient<IIdentityServerHttpClient, IdentityServerHttpClient>()
.SetHandlerLifetime(TimeSpan.FromMinutes(5));
Any advises or examples of how a concrete implementation based on HttpClient looks like, will be very welcome.
Thank you!
I am setting up identity server3 with Microsoft identity stored in ef 6
I can "login" at the /token end point but when I try to access the /userinfo I get a scope error.
when I try to add scopes to my /token login they do not work.
tried to edit the client to add the scopes and still stuck.
the client is the resource owner flow.
just need to get userinfo so I can get the name and the roles for the user.
1) what scope do I need to access the user info end point ? I get insufficient scope on all my attempts.
2) I have editied the sql database and the code to allow my client to have more scopes but it does not seem to work. how to debug that ?
also I am using asp.net identity stored in sql and the id server ef to store tokens, clients, scopes and secrets, well I am trying to but I am not sure it's right. the tables were created but I do not see any rows in the tokens table event though I was issued a token. I have two databases right now: one with the token/client/scope stuff and the other with aspnet users and roles.
do I need to make this one database ?
it looks like part of my problem is with the identity server sample for using entity framework to store the clients, scopes and related data.
it looks like some items are missing in the lists of scopes and or scope claims and or clients, so when I try to login with a scope parameter I get rejected when it can not find the row in the scopes table.
working on how to fix this and I hope get it working....
does a scope need scope claims ?? need to see if I can find info on that.
its 'openid' scope as docs say. https://identityserver.github.io/Documentation/docsv2/endpoints/userinfo.html
When in doubt I just download the current source code from Github and apply breakpoints, rather than using the Nuget package.
Just going from memory (So this may not be completely accurate).
I believe the UserInfoEndpoint makes a call to UserService.GetProfileDataAsync. The UserInfoEndpoint is accepting scopes but the GetProfileDataAsync only accepts claims as "RequestedClaimTypes". So somewhere in between it will be taking the scopes sent to endpoint and getting a list of all claim types that fall within the scopes.
The most important thing to keep in mind here is that the scopes you pass into the UserInfoEndpoint must be Identity scopes. The endpoint will not return claims belonging to resource scopes.
So just a quick rundown...
Server receives scopes sent to UserInfoEndpoint
Of the scopes received, it only looks at Identity Scopes
Find claim types that are assigned to the identity scopes
Passes down the list of claim types to GetProfileDataAsync as "context.RequestedClaimTypes".
At this point your custom logic determines how the RequestedClaimTypes translate into IssuedClaims.
My guess is that you are passing in resource scopes to the UserInfoEndpoint.
what finally got my problem fixed:
I needed more scopes in my sql database , the id server sample for v3 using entity framework did not have some of the same scope items that the identity server sample expects , this was making a login token call fail with invalid scope.
I edited the c# code for the scopes and clients to get what I needed and dropped and re-created the sql tables and then it started working.
I also added a new scope and scope claims to add in non standard claims that our app needs.
I did attach the source to let me debug that really helped as I could follow the logic and see where it did not work. that was a huge help.
I will see later if I can post to the source what the sample was missing that was the real problem.
it might also be good if we had some kind of guide on how to get the standard userinfo / profile claims to work. I got it but that also was a bit of source debugging to see how the id server calls to the stores to get the info so that I could understand how to tap in and give it the data to pass back to the caller.
bottom line is that the samples have different sets of scopes and claims in at least one place and that was the key problem.
the rest is learning how to use the scopes and scope claims to add to the user info endpoint for the applications needs.
I'm using signalr and since I wanna use websockets the [Authorize] attribute only authorize the client when the connection opens and then everything is ok. I would like the [Authorize] process to be triggered somehow.
Note: Must works using websockets
For example (I use Owin.Security.Cookies (UseCookieAuthentication)):
I connect to my application with a valid token in my cookie, once I've done this I manually remove the cookie in my browser and everything still works OK until I reload the page. Another example is if the client already has an open and valid connection, but the token limit expires - it's still valid until a reload is done.
Now to my question - Is there anyway I can force signalr to re-authorize the token every x min?
For the rest of this answer, I'm going to assume you're using SignalR hubs instead of PersistentConnections.
When you use SignalR's [Authorize] attribute or your own custom version of it, there are three methods to be aware of.
AuthorizeHubMethodInvocation
This is called, as you might expect, when a method on your hub is called. This could be any method, or only methods you apply an [Authorize] attribute to. You could put your code here.
AuthorizeHubConnection
This is probably what you want. Every time the client connects to the hub- which is a fairly frequent occurrence- this method is called. Do NOT confuse this with SignalR's Hub's idea of a connection. When a client is communicating with a SignalR hub, this method is called frequently- every method call or two on average.
This is where I would put the code you're talking about. You'll want to create a new attribute that inherits from SignalR.AuthorizeAttribute. In there, you'll want to override either AuthorizeHubConnection or AuthorizeHubMethodInvocation. Do note that if you don't override one of these methods, they will call UserAuthorized to make their decision.
In one of those two methods, you want them to return true if their cookie is valid (it exists, has a valid token, and hasn't expired), and false otherwise. This code will be called every time- or just about every time- a call is made to the hub, and deny access to the client if anything's wrong.
Hope this works!
Currently working on an ajax call to an ASP web service (.asmx).
In a situation where I POST to the url/.asmx/WebMethod, am I exposing information of any kind?
In the 'WebMethod' I am running a PostJsonAsync that calls an API and passes along a json string.
As I am still learning, I've been told that calling any public [WebMethod] exposes the code, but I am not sure how that is possible.
Is it possible at all for a user to access the WebMethod server-side code that I have and peek into the API calls that are available?
I've attempted some minor security methods.. We are working with Sitefinity CMS. What I did was call a WebMethod that receives the CurrentUserIdentity and returns a GUID. If the current user is logged in, it returns a valid Guid, if not it returns a Guid full of zeros.
Then, I call the WebMethod containing my API call and post a json object along with the valid or invalid GUID. The server-side WebMethod code will then verify if the GUID is valid and continues based on if a UserProfile can be generated.
To me, this seems to be secure, but I've been told that this still leaves the WebMethod exposed as well as the API. I am however just not understanding what is exposed and what can be used.
If anybody can direct me to any resources that has more information on this, or if anybody can advise me on WebService security, I would appreciate it.
Thanks in advance.
If you're calling the methods via AJAX, then they are exposed to the public...and can be called by anything that can make a call to your server. That being said, there's nothing wrong with it unless you're doing something that's easily abused.
In your particular case, it sounds like the code is accepting a GUID that is assumed to have come from the first API call. If that's really the case, you may want to rethink how the mechanism works. Adding authentication checks for each method that needs to be restricted may be a better solution.