First of all excuse my bad english.
I'm a newby in oauth2 and I'm trying to setup an authorization server with JWT tokens.
The server is running in a Owin self-hosted environment.
At this moment I've setup the token generation and it seems to work properly, I've also setup the refresh token provider and it seems to work (but it's just a minimal implementation); I didn't change the RefreshTokenFormat in the OAuthAuthorizationServerOptions leaving it to default (I don't know what is the default format), so the access-token is clearly a JWT token and the refresh token is something else.
All of this seems to work correctly, but I will need to run this authorization server in a microservices environment, so the authorization server service might be moved at any moment from one machine to another, so it needs to be stateless or at least to save needed informations on a shared storage (DB) or replicated local storage (I'm on Service Fabric) or some kind of distributed cache.
Testing I noticed that if I generate a refresh-token on a machine and then I try to use this refresh-token on another instance of the authorization server (on another machine) to get a new access-token, it fail with a generic invalid_grant error. My guess is that the auth server just keeps some token-related information in memory but I don't know exactly what and how.
I also would like someone to point me in the right direction to solve this issue.
Thank you very much.
I solved the situation using a JWT token also for the refresh token.
This way the authentication server seems to be completly stateless.
Related
I am writing code to connect to power bi via TOM (Tabular Object Model) as opposed to the Rest API. Apparently the same authentication token can be used for both the REST API as well as TOM connectivity. As per here https://learn.microsoft.com/en-us/analysis-services/tom/introduction-to-the-tabular-object-model-tom-in-analysis-services-amo?view=asallproducts-allversions
In a deployed environment that uses managed identity the token works successfully for both, however in my local dev environment it fails on the Server.Connect to TOM (as per below) with an Unauthorized error.
The TokenService is just using the DefaultAzureCredential which makes use of the Azure CLI credential available once the dev does an "az login". Once again this works seamlessly for the REST API but fails against the XMLA endpoint on Server.Connect.
Wondering if anyone else has managed to get this to work? We do not want to use application based authentication as that significantly complicates things.
Thanks
I've created a new Blazor app using the Visual Studio template adding B2C using the wizard during the project creation.
All works great with authentication. I can sign in using my favorite identity provider and receive the id_token. I don't know where I can get the id_token, but I can see the claims in my user identity.
What I need help with is how do I take the information in the claims to acquire the access token. I need this token to call my endpoints.
This seems like it should be straightforward and a common thing, but I can't seem to find any good examples.
In a normal MVC app, I can get this through the ConfidentialClientApplicationBuilder.AcquireTokenByAuthorizationCode but that doesn't work in Blazor (unless I'm doing something wrong).
I've tried this: https://learn.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-access-tokens
I think it'll work. How do I get "code"(id_token) in my blazor app? It's what is decoded behind the scenes and all I can find are the claims resulting from decoding the "code".
I've used the azure's "Run user flow" to access an example id_token("code") and pasted it into my project and made the call in the link above and it seems to work. I'm running into permission issues, but it's at least a successful call.
Maybe if I can just get access to the id_token I can make it work from there?
This seems like a client side app, similar to a SPA. In which case you must use the implicit flow, where the response type is “id_token token”, and returns an id token and access token to the browser in one call. This isn’t an exact answer, but only our MSAL.js library can make this type of call, but Blazor seems to use C#, and msal .net does not do client side auth calls. acquireTokenByAuthCode() would work client side as long as you register the app as a native app, so a secret is not required.
There are 2 WebApi Projects on different servers. One of these servers (WebApi-A) has OAuth2 authentication workflow setup with Authorization Server and all.
The another WebApi project (WebApi-B) has an end point that I would like to Authenticate through [Authorize] attribute. I don't want have a new authorization server but to utilize (WebApi-A's) authentication process just to validate the token.
From what I understand if the machine-key is same across these server. We can essentially replicate the authentication process from WebApi-A in WebApi-B without having to call WebApi-A at all.
How do I achieve this?
You could, in theory, pass through the JWT token and if your OAuth setup uses the same client secret and data store it should just work. You would have to ensure that you add the JTW token when requesting and to use some distributed cache to verify.
I would rather ask whether or not you should rather create a gateway that can handle and authenticate the requests and delegate them to the separate APIs? This feels like an identity server (http://docs.identityserver.io/en/latest/topics/apis.html) would solve your problem. Anything you do other than moving the authentication from web api A would just be a stopgap.
Duplicating the setup could work but that will mean that you have to now maintain it in two places. So I agree that doing that is less than ideal.
This is a great article that may aid you:
https://www.scottbrady91.com/OAuth/Delegation-Patterns-for-OAuth-20
This will have a lengthy answer so I will just leave you this diagram showing multiple Resource Server, Client, and a separate Authorization Server
Taken from this article Single sign-on across multiple applications (part II) which I hope could get you started.
you can use your token when login in web api and then you add the token to the header "Authorization" with bearer "your token"
I've been working on a multi-app project for a few months now using Azure App Service for my database and ADD B2C for authentication. There are three applications in this project: an admin WPF app, a client web app, and an employee WPF app. All three applications use client managed authentication with my B2C tenant by getting a token from B2C and using that token to login to the App Service database. Everything has been working fine until seemingly overnight I am no longer able to authenticate with the app service. I have no problem displaying the B2C login screen and getting an access token as a result of the authentication, but when I package the token in a JObject and call the 'mobileServiceClient.LoginAsync()' function, all I get back is a 403 "forbidden" error.
First I tried seeing if all three projects were affected, which they are. I then tried rolling back to my last commit. Still the same thing. I then tried re-cloning to see if there was any little quirk with still the same results. Because I know my Azure resources have not hit their limits, I then tried making a completely separate WPF project and I made a table on the app service that allows anonymous access. After setting "Action to take when request is not authenticated" to "Allow anonymous access" on the app service, I was able to read and write to the anonymous table without issue. I then tried to have this new project authenticate the same way the others have been only to get the same 403 error. After checking all of this I can say I'm almost completely sure that there is no issue with the client applications and the issue has to be on the server side.The most confusing part for me is that aside from adding a new table to the database, I haven't changed a single thing server side. I've checked out both the B2C tenant and the authentication settings on the app service but nothing seems to be different than before I was experiencing this problem. Investigating a little bit more in the app service, I tried to find some JS code that handles authentication to see if I could find any useful information using the console output. I did not find any code, but I did find out the console outputs PID[31680] Information Sending response: 403.76 Forbidden whenever a client tries to authenticate.
Additional information that might help is that my request header timestamp is correct. I know from research that Azure only allows a 15 minute variance for incoming requests from its time.
Any help or suggestions for solving this issue would be greatly appreciated! Thanks!
I am building a client program that interacts with a WCF Service via Internet. Everything works as intended but I am wondering how I can protect my services so that only my client program can make use of it?
Right now everyone with the correct URL to my services can use it with WCFTestClient (e.g).
What is the best way to make it private so only my clients can make use of the service? Rotating token strings? Certificate? Password?
I have no idea and haven't found anything useful on the Internet.
Best regards
UPDATE: The client program is intended to be downloaded for the public (everyone). So it is not for internal use, it will be a service we are gonna provide, ones in official production.
My own thinking was like: Bind a certificate in my client programs (if thats possible even?). On the IIS where the WCF service is running, check for valid certificate. Is that possible? Or better solutions out there?
Protect .net Web Service URL
Along with the other answers, that can't be bad too,
and if you want to be super careful you can implement a token system, where the clients get the first token from you, each request returns a new token, and you always check a client vs it's current token (but that's being over careful in my opinion)
Update - because it's for the public, the client can have a way of generating a valid token to check on the server, you can have a token be valid for an interval of seconds, so even if people caught the request and found the token, it will not be valid after ..15 seconds or 30,etc
If you are using Form Authentication then you can leverage the ASP.NET to check for FormAuthentication Cookie by enabling AspNetCompatibilityRequirementsMode to Required
Or if your service is stand alone i.e is consumed by everyone then you can use oauth authentication you can read more about it Oauth Authentication
What you could do is there would be a consumer secret key which would be shared to all authenticated clients. The caller would sign some info using this key and server would also sign it using the same key and then compare it.
Hope it helps