Unauthorized endpoint calling authorized Microservices - c#

I hope this perhaps isn't too generic of a question. In gatewayAPI based microservices architecture pattern in .net - is it possible for a method dressed with [AllowAnnonymous] to call a method from another microservice that is dressed with [Authorize]?
The challenge that I have is that I have a payment processing method, which posts to another microservice to send an email confirmation, but the email method is marked authorized, and payment one is not.

Yes.
Think of it in terms of who is making the request.
A user makes a request to your endpoint, if there's any authorization, it's processed against the user's session token, form data, other cookies, etc that were included in the request by the user's browser.
If your code spins up an HttpClient and sends a request, the 'user' in this case is your server. If authorization is required, you'll need to include that in the HttpRequestMessage. What that looks like exactly depends on the endpoint you're hitting.

Related

IdentityServer4 custom token validation called only once

I am currently working on the logic of custom token validation. I need to deactivate the token when the user's password is changed (change-password endpoint is public).
I have implemented the ICustomTokenRequestValidator interface and resolved my class via DI
.AddCustomTokenRequestValidator<TokenHashValidatorService>();
However, I can see the following problem, my implementation of ICustomTokenRequestValidator only works when I generate a token and during only the first request to my API.
In logs I see the following information:
JWKS request from log
During first request to API request to /.well-known/openid-configuration and /.well-known/openid-configuration/jwks is sent. But when I send a second, third, etc. requests my breakpoint in TokenHashValidatorService is skipped.
Is there any way I can forcefully initiate second /.well-known/openid-configuration and /.well-known/openid-configuration/jwks requests?
Or maybe I can somehow mark that "token validation needed" during the change-password flow?
I'm really stuck and out of options, I've read all the articles out there, any ideas?

Identity Server 3 - invalid_grant - Refresh token already used

In our application, we periodically encounter a scenario where the user requests a new token at the same time when we're automatically refreshing the token in the background (via JS.)
Both requests are using the refresh token & hitting the token endpoint.
If the automatic request finishes first, the user-initiated request results in an error. This is because both requests are trying to use the same refresh token but since it can only be used once, it's consumed by the first request and the second request gets 400 Bad Request.
My question is: What's the best way to handle the 400 response for the second request? Ideally, I want to silently retry the request and the user should be none-the-wiser.
If this occurs, the ultimate fall-back has to be reauthenticating - IdentityServer is doing nothing wrong, the ball is in your court.
But - you should be able to make this situation impossible by synchronising the automatic token refresh and the user-driven token request. If the refresh token lives in your application in one place, then you can regulate access to it via some kind of lock/release mechanism.
This npm package looks like it'd do it: https://www.npmjs.com/package/lock
Alternatively you could synchronise calls on the server by subclassing the relevant IdentityServer component, and using a per-client lock there - but IdentityServer is already complicated, it would require many locks in one place, and it wouldn't be easily scalable to multiple server instances.

Asp.Net Core 2.2 - Understanding Authentication Middleware and External Logins

I have been trying to wrap my head around this concept but have many questions and unfortunately, all official documents and tutorials are based on Visual Studio templates with individual user accounts.
My goal is pretty straightforward I believe. I have a web application which will only support external provider logins (namely: Facebook, Twitter, and LinkedIn). I do not want to support cookie authentication since there won't be a support for custom username/password.
My first problem is to define a default AuthenticationScheme. Below is my startup.cs:
services.AddAuthentication()
.AddFacebook(/* options */)
.AddTwitter(/* options */)
If I define a controller action with Authorize attribute I get no default authentication scheme defined error when I hit that route. However, I want users to be redirected to my login route if they are unauthorized. If I modify startup.cs like below it all works but then I think I support cookie (old forms authentication?) authentication which I don't want to.
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie()
.AddFacebook(/* options */)
My other issue is that I don't know what happens under the hood of AddFacebook() call. If I set up my middleware this way and log in with Facebook I magically get all the necessary tokens, claims and suddenly I have an application cookie set and my fb_login callback route can access to Facebook's token! When I check the network requests I see there is a hit to the signin-facebook route -which I didn't define- and I guess under the hood it calls HttpContext.SignInAsync() etc... but if I refresh my fb-login callback and check if
HttpContext.AuthenticateAsync(FacebookDefaults.AuthenticationScheme)
returns Success = true no! it returns false! But it was true just one second ago?
Also, when should I be using methods like AuthenticateAsync() and SignInAsync()?
Long story short I need a tutorial or documentation that explains this middleware without asp.net Identity framework, EntityFramework and templates.
I want to understand how a simple AddFacebook() call binds everything, and if I want to manually do that (say with AddOauth) how can I achieve the same functionality?
I'm not a fan of "automagically working" code so if someone can explain what's going on here I'd be very appreciated.
Cookie auth is used to persist the authenticated state between the requests. There is no substitute for this, and no it's not the same as forms auth, though cookies are used in both cases. The reason for that is simply that cookies are what makes state work over the HTTP protocol, which is itself stateless. If exclude the use of cookies, then there is no other mechanism to maintain state.
Using something like the Facebook auth scheme directly authorizes the initial request, but again, because there is no state, the next request is no longer authenticated without going through the Facebook OAuth flow again.
Long and short, the other auth schemes are there for things like APIs, where each request is typically authenticated individually via something like the Authorization header. A web browser doesn't work this way, and instead relies on cookies handle subsequent authorization. No cookies, no auth.

Asp.Net Webhook Subscription outside the webhook project

I have created a webhook custom sender project as described in here. When I try to subscribe to the webhook using postman I get a login error. As per my understanding to subscribe, I must provide a dashboard sort of thing where users come and subscribe to events. I want the user to call the subscription API directly from there own app. how I can do that? I don't see any documentation which tells me about all the parameters in the subscription request. need help.
You get the login error because you probably decorated the controller with Authorize attribute and you need to be logged in in order to access the actions within. You can replace AllowAnonymous attribute if you don't need to be logged in.
If you do, then login normally on the site and grab that cookie(token, etc.) which holds the authentication information and send that along with the Postman request.

Custom httpHeader or soap header into claims-based authorization by endpoint/contract

I have a ServiceHost that implements many Contacts on various endpoints and bindings ((http & https) x (rest & soap) with Anonymous Access, Windows, or Custom authentication, as bound depending on the Contract) & nettcp with Windows authentication. Custom authentication is embedded in the http or soap headers. Each endpoint and contract has its purpose. It should all be manageable on a single ServiceHost - I don't want to split it up.
I've gotten it to the point where all the endpoints work and serve their content correctly, but the authentication/authorization isn't integrated into the WCF stack. I have been using a MessageInspector to handle validation of the authentication header and allowing it if the token was valid.
Now I want to integrate the authentication/authorization into the WCF stack. I want to be able to access the identity and check the claims in each Operation's implementation. And perhaps basic claims can be authorized centrally, like "are these claims authorizing anything at all in this contract?" (by contract type).
In the case of custom authentication, I have a signed/secure token that includes a custom implementation of identity and property claims which I can properly extract and convert into WCF claims upon receipt (even if I don't know exactly where to put them once I've got them). For Windows authentication, I just need access to the default Windows identity stuff.
I can set the ServiceAuthenticationManager and ServiceAuthorizationManager each to custom values, but it's not doing anything I want it to and I'm getting totally lost.
For example, the ReadOnlyCollection<IAuthorizationPolicy> authPolicy coming into Authenticate() seems to be inconsistent - sometimes it's empty, sometimes it has one UnconditionalPolicy and sometimes it has 2 or more (4?) of my custom IAuthorizationPolicy already there. Meanwhile IAuthorizationPolicy.Evaluate() gets executed anywhere from 0 to ~9 times per request. Sometimes, within IAuthorizationPolicy.Evaluate(), OperationContext.Current is null! And sometimes the evaluationContext.ClaimSets already has my claimset. Yet state is always null even when I give it a value in a previous enactment.
Rather than tackling these problems individually, I think it'd be better to step back and ask for some high-level explanation of what I should do/expect to see.
Authentication: When a request comes into the ServiceHost, it needs to get Authenticated. At this point in the pipeline, I don't need to know what they can do, just who they are. If a client submits both Windows credentials and a custom authentication ticket to a Contract/Binding on which I require just a custom authentication ticket, the service shouldn't be tricked into evaluating the wrong one. But perhaps at this stage in the WCF pipeline, the Contract hasn't been resolved so perhaps during this stage, all found identities/claims/tokens should be captured and selected among later. Is this right? How is this done?
Message Inspection: I have a custom MessageInspector which I'll still need for CORS support and OPTIONS request processing on some of the endpoints. I believe this happens after authentication and before authorization. In the case of OPTIONS, I set ref message to null and skip the Operation entirely, jumping straight to the BeforeSendReply. Clients don't send the auth-token on a CORS OPTIONS preflight request and so I allow these requests unconditionally.
Authorization: Depending on the Contract, I want to require certain authentication mechanisms and ignore others. I believe some setup needs to prepare the Thread Principal and Operation Context principal to the correct value. It seems that multiple Authorization policies can be in play at once. How do they interact?
Operation: I want to be able to implement each operation assuming that the identity of the caller is authenticated using a supported authentication (by Contract, which I'm OK maintaining hard-coded somewhere ONCE) and get the validated caller identity and assert simple permissions checks againsts the verified Claims.
How do I achieve this (code preferred over config xml)?
Thanks!

Categories

Resources