I am using Identity Server4 for a proof of concept project.I have implemented the identity server and I can receive an access token when I authenticate successfully.
For authentication I use, the following endpoint:
http://identity-vm-01/connect/token
and the details I post are:
Now, I would like to check if the token that I receive is valid. For that I am using the following endpoint.
http://identity-vm-01/connect/introspect
with a basic auth header using the client_id and client_secret as shown above, and pass token in the body.
But I receive an Unauthorized error. 401 . It will be great if someone could tell me what is that I am doing wrong.
Thank you
You need to define a scope secret for api1 (on the Scope class) and use the scope name and secret as client_id/secret.
Clients for the introspection endpoint are not really clients in the OAuth 2 sense - they are APIs.
Related
i register on https://bridgedataoutput.com/ for using bridge data api. as per documents
https://bridgedataoutput.com/docs/platform/API/zg-data#Zestimates
require access token. how I get access token ?
after login , I get detail of Client id, Client Secret and Server Token. i try server token but give me authorization error.
I try to do get request on this below API link
https://api.bridgedataoutput.com/api/v2/zestimates_v2/zestimates?access_token=P7cbhWXt2PLOGOHbctzuOJ1qF2mJYSSF7cI1IrUabGdt3u2IGMiFzu5XLCNk&address=%22123%20Main%20Street%22
Response
{"success":false,"status":403,"bundle":{"name":"AuthenticationError","message":"Invalid access_token format"}}
I had the same issue, and Bridge support said to use the Server Token as the access token. It needs to go in the URL, not as a header when I tried it. Here's an example.
https://api.bridgedataoutput.com/api/v2/OData/[DATASET_ID]/[RESOURCE]?access_token=[SERVER_TOKEN]
Zillow Public Records, Zestimates and Econimic Data does need additional approval. Please confirm in https://bridgedataoutput.com/data/feeds.
I have an identity server implementation that works perfectively with jwt tokens and two different clients that access it.
Mr Console authenticates using client_credentials
Ms Website authenticates using pkce
In both cases when using jwt tokens I can get the claims with only one issue. The size of the token is getting out of hand and we'd like to use reference tokens instead.
I changed the token type from Jwt to Reference and can now get the claims for Ms Website by calling the user info endpoint and passing in the reference token. Great!
The problem I have is that I cannot seem to get the claims for Mr Console.
I cannot call the user info endpoint because it expects a user and throws an error "Token contains no sub claim" - which it wouldn't as I'm using client credentials.
I cannot call the introspective endpoint as it appears to only be available to internal apis and fails with the error "API unauthorized to call introspection endpoint".
How can I get the claims from within my client console application when provided with a reference token and not a jwt? Is there a way?
Thanks
Because you are using the client credentials flow you have no user claims available.
However you have Client claims that you can use instead, have you considered to use those instead of userclaims?
I have been securing a webapi using Rob Sander's instructions, found here: Securing a web api with adfs 3.0 and jwt tokens
I have successfully performed a login via ADFS using the usernamemixed end point, and have received the encoded Json Web Token (JWT). That's fine, and I can successfully validate the token with the X509 certificate found in the federation data xml found on the ADFS server.
I have implemented a DelegatingHandler so that any Authorize attributes added to methods will be checked.
The final piece of the puzzle is where I can get the refresh_token from. It would make sense to come from an ADFS endpoint, and I thought it would be in the response from the usernamemixed end point, but it doesn't appear to be there. Also, how do I make a call to request a new access_token if I provide a refresh_token?
Normally, there's another OAuth endpoint. You would have /authorize, /token and /refresh.
Not sure in ADFS 3.0 implements this?
You can get it via:
Set-AdfsRelyingPartyTrust -TargetName "RPT Name" -IssueOAuthRefreshTokensTo AllDevices
More details here.
I have a mobile client (app) letting the user authenticate with google. So, the client receives an access token and some info (name, email etc) from google. Works fine!
I also created an ASP.NET Web API that the mobile app should comunicate with. On the client side I am adding the token to the HttpClient with:
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "pretty_long_access_token_separated_by_two_dots");
Question 1: I'm trying to "decode" the access token on this site (to make sure it's all right): https://jwt.io/
The header and the payload is all right, but it seems like it's an "invalid signature" (says in the bottom). Should I worry about this?
On the server side, I added this to the Configuration method in the Startup class:
app.UseJwtBearerAuthentication( new JwtBearerAuthenticationOptions
{
AuthenticationMode = AuthenticationMode.Active,
AllowedAudiences = new List<string> {"my_client_id"},
IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[]
{
new SymmetricKeyIssuerSecurityTokenProvider(#"https://accounts.google.com/", "my_client_secret")
},
});
The only thing I want to do with the token, on my server side, is making sure that only validated users from my app should be able to access my API-controller.
Question 2: Is UseJwtBearerAuthentication the right thing for me, or am I going in the wrong direction?
My problem is, I constantly get 401, unauthorized, when trying to access my WEB API controller.
If I am on the right track, I can try to explain more about the server side setup...
Any helt would be very appreciated!
If you are using a JWT token then you will need JWT instead of Bearer
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("JWT", "pretty_long_access_token_separated_by_two_dots");
The signature is used to validate the token as authentic and is therefore only required by the authentication server. If Google is your authentication server, then there should be an API endpoint you can call from your server to verify that the token is valid.
If your server is issuing the JWT token, then you will need to check that the token is valid by decoding the signature using the secret that was used to create it in the first place
If Google is issuing the JWT and you want your server to be able to self validate it, then you need to use another encryption type such as RS256 which will allow you to validate the signature using a public key issued by Google (I have no idea if they provide this method or not)
The reason https://jwt.io/ cannot validate your signature is because it was signed using a secret code. If you have this secret code then you are able to paste it into the textbox in the bottom right. If the secret is correct, and the token hasn't expired, it will show as being a valid JWT token.
I'm just finishing authorization and resource server for OAuth2, using DotNetOpenAuth 4.3.4. For testing, I created test client by implementing OAuth2Client.
Because I'm using DNOA for all the communication and request parsing, I'm not sure if I fully understand what is going on under the hood. But this knowledge is very important when I make documentation.
So, could you please explain to me, how client authentification works in DNOA? I use authorization code as grant_type and when I use my test client to exchange code for access_token, the DNOA somehow validate the client_secret and client_id. I downloaded source code for DNOA, but it not helped.
When I set breakpoint to Oauth2 controller(token method) and parse the request as HttpRequestMessage, i see the request contains "grant_type", "code" and "redirect_uri". But where are client_id and client_secret?
Also, can you tell me where I can find any usable documentation for DNOA? I need to create documentation, which will be valid and usable for all platforms, not just C#, which can use DNOA.
Related question:
I somewhere read, that we should not create authorization codes for unauthentificated clients, but this is exactly what DNOA does (since I receive authorization code even if secret is wrong). Is it ok?
Edit:
This is the request I'm trying to read. It is token request made by DNOA client. I can not see the client_id and client_secret under other parameters like "code", "redirect_uri" and "grant_type". I tought they have to be together. Maybe I'm missing something important from http requests and responses.
When I let DNOA to HandleTokenRequest(request) to continue, it is successfully authenticate the client application (fails when bad secret is set in DNOA client app config).
Edit 2
private readonly WebServerClient Client;
protected override string QueryAccessToken(Uri returnUrl, string authorizationCode)
{
var authorization = Client.ProcessUserAuthorization();
if (authorization != null)
return authorization.AccessToken;
else
return null;
}
This is my implementation of QueryAccessToken. It is from some sample. I think I created this at the beginning and did not change it, because it worked.
Going rought DNOA source I found out it is method from OAuth 1. THis can be the problem. But the question is, why it works ok with right client cerdentials and not working with bad ones.
Final edit
Looks like DNOA client uses http Basic authorization (client_id and secret are in header). But I need the DNOA server to be able to grab these parameters from POST.
If anyone know how to set DNOA to support client_id and client_secret in POST parameters, it would be awesome!
Thank you
The authorization code grant requires two steps.
The first step is the browser redirecting to the identity provider and displaying the logon ui. The authorization code is returned to the browser by the identity provider and then, from the browser to the client application. This step doesn't involve client secret! This is because the end user can debug this part of the flow and she should not learn the value of the client secret.
Then, when the client application has the onetime authorization code, it concacts the token endpoint directly (server-to-server) to exchange the authorization code for authorization token. This is where client id and client secret are used to verify that only legitimate client applications exchange codes for tokens.
The idea behind this flow is to protect the end user from exposing her password to the client application and also protect the client application from exposing its client secret to the end user.
Also note that the authorization code grant flow is the most complicated one as it involves both username/password (provided by the end user) and clientid/client secret (provided by the client application). There are other flows which allow to get the authorization token in slightly different way, namely:
resource owner grant which involves sending username/password directly by end user to the token endpoint of the identity provider. This flow is suited for desktop/mobile/native apps where the logon ui can be customized (but it also can raise suspicions and users could proably refuse to use it)
client credentials flow which involves sending clientid/client secret by the client application to the idntity provider. There is no end user but only the client application authenticating in the identity provider.
More on flows here:
http://aaronparecki.com/articles/2012/07/29/1/oauth2-simplified
As for DNOA, I found it clean and understandable but the docs are lacking. Fortunately, examples are great and although barely documented, you can find almost everything there. Nonetheless, I was able to set up oauth2 identity provider and resource server in three days and support all four oauth2 flows. I am not going to dig deeply into details as this is not what your question is about, however, if you have DNOA specific questions, just ask.
Edit:: regarding your QueryAccessToken implementation, it seems that you are using the WebServerClient internally. In my code I just initialize its properties:
WebServerClient client = ...
client.ClientIdentifier = "client_id";
client.ClientCredentialApplicator =
ClientCredentialApplicator.PostParameter( "client_secret" );
With these two configured, both client_id and client_secret are sent to the token service with the client_secret passed in POST params.