Cannot use refresh token to obtain new access token and refresh token in Identity Server 3 implementation - identityserver3

I've been playing around with Thinktecture's identity server and now I have some problems trying to reach the refresh token endpoint.
What I have is few clients configured like this:
Authorization code flow client:
new Client
{
ClientId = "tripgalleryauthcode",
ClientName = "Trip Gallery (Authorization Code)",
Flow = Flows.AuthorizationCode,
AllowAccessToAllScopes = true,
RequireConsent = false,
RedirectUris = new List<string>
{
"redirecturi"
},
ClientSecrets = new List<Secret>()
{
new Secret("somesecret".Sha256())
}
}
Hybrid flow client:
new Client
{
ClientId = "tripgalleryhybrid",
ClientName = "Tripgalleryhybrid (Hybrid)",
Flow = Flows.Hybrid,
AllowAccessToAllScopes = true,
RequireConsent = false,
IdentityTokenLifetime = 10,
AccessTokenLifetime = 120,
// redirect = URI of the MVC application
RedirectUris = new List<string>
{
"redirecturi"
},
// Needed when requesting refresh tokens
ClientSecrets = new List<Secret>()
{
new Secret("somesecret".Sha256())
},
PostLogoutRedirectUris = new List<string>()
{
"postlogouturi"
}
}
What I do is, I have ASP.NET MVC client which uses the hybrid flow. After the authentication I receive access token, refresh token and some other stuff.
What I am trying to do is to test the refresh token endpoint. The way I prepare my request is as follows:
I make a POST request to: /identity/connect/revocation
In the headers of the request I have:
Content-Type: application/x-www-form-urlencoded
Authorization: Basic dHJpcGdhbGxlcnlhdXRoY29kZTpteXJhbmRvbWNsaWVudHNlY3JldA==(This is base64 encoded clientid:clientsecret that are my Authorization Code ones)
In the request body I have: token=0a24f80dcc97a56ede0e7c04563a3493&token_type_hint=refresh_token
The token is the one that came after my authentication trough the hybrid client.
When I fire the request it returns Http 200. But no content is returned back. When I go the Identity Server logs this is what I see:
SnapshotHelper::TakeSnapshotTimerCallback
SnapshotHelper::TakeSnapshotInternal - no new files in CodeGen
w3wp.exe Warning: 0 : 2016-11-13 13:54:11.557 +00:00 [Warning] AuthorizationCodeStore not configured - falling back to InMemory
w3wp.exe Warning: 0 : 2016-11-13 13:54:11.620 +00:00 [Warning] TokenHandleStore not configured - falling back to InMemory
w3wp.exe Warning: 0 : 2016-11-13 13:54:11.620 +00:00 [Warning] ConsentStore not configured - falling back to InMemory
w3wp.exe Warning: 0 : 2016-11-13 13:54:11.620 +00:00 [Warning] RefreshTokenStore not configured - falling back to InMemory
w3wp.exe Information: 0 : 2016-11-13 13:54:12.356 +00:00 [Information] Start token revocation request
w3wp.exe Information: 0 : 2016-11-13 13:54:12.401 +00:00 [Information] Client secret id found: "tripgalleryauthcode"
w3wp.exe Information: 0 : 2016-11-13 13:54:12.401 +00:00 [Information] Client validation success
w3wp.exe Information: 0 : 2016-11-13 13:54:12.401 +00:00 [Information] End token revocation request
What I really expected to get at least new access and refresh tokens but nothing. I guess I am really missing something in the configuration of my clients so I would be very happy if you could help me.
EDIT:
I changed the endpoint to: /identity/connect/token and also changed the request body to:
grant_type=refresh_token&token=635c7cbcfa1c0417b6d574ade388c0d8&token_type_hint=refresh_token but still no success. Now my Identity server log says:
SnapshotHelper::TakeSnapshotTimerCallback
SnapshotHelper::TakeSnapshotInternal - no new files in CodeGen
SnapshotHelper::TakeSnapshot time since last: 00:19:59.9992231
w3wp.exe Information: 0 : 2016-11-13 20:40:33.406 +00:00 [Information] Start token request
w3wp.exe Information: 0 : 2016-11-13 20:40:33.406 +00:00 [Information] Client secret id found: "tripgalleryauthcode"
w3wp.exe Information: 0 : 2016-11-13 20:40:33.406 +00:00 [Information] Client validation success
w3wp.exe Information: 0 : 2016-11-13 20:40:33.406 +00:00 [Information] Start token request validation
w3wp.exe Information: 0 : 2016-11-13 20:40:33.406 +00:00 [Information] Start validation of refresh token request
w3wp.exe Error: 0 : 2016-11-13 20:40:33.406 +00:00 [Error] "Refresh token is missing"
"{
\"ClientId\": \"tripgalleryauthcode\",
\"ClientName\": \"Trip Gallery (Authorization Code)\",
\"GrantType\": \"refresh_token\",
\"Raw\": {
\"grant_type\": \"refresh_token\",
\"token\": \"635c7cbcfa1c0417b6d574ade388c0d8\",
\"token_type_hint\": \"refresh_token\"
}
}"
w3wp.exe Information: 0 : 2016-11-13 20:40:33.406 +00:00 [Information] End token request
w3wp.exe Information: 0 : 2016-11-13 20:40:33.406 +00:00 [Information] Returning error: invalid_request
SECOND EDIT:
Based on the documentation posted here: Token Endpoint and what's inside of it here: TokenRequest and many more resources related to that I came to this request:
which I believe is the correct one. Unfortunatelly I am still getting HTTP 400 from by identity server with an error that says: error=invalid_grant. This makes me think that most likely I have to make some more configuration on my client. In some of the examples on the internet I can see the usage of: AbsoluteRefreshTokenLifetime, SlidingRefreshTokenLifetime, RefreshTokenUsage, RefreshTokenExpiration when configuring the client. Can you please give me at least a direction to dig into?
SOLUTION:
What worked for me was to add these options to the client:
// refresh token options
AccessTokenType = AccessTokenType.Jwt,
AccessTokenLifetime = 3600,
RefreshTokenUsage = TokenUsage.ReUse,
RefreshTokenExpiration = TokenExpiration.Absolute,
AbsoluteRefreshTokenLifetime = 1296000

You're using the revocation endpoint, which allows you to destroy (aka "revoke") a token. To use the refresh token to get a new access token, you want the token endpoint with the grant_type=refresh_token, as covered in the docs: https://identityserver.github.io/Documentation/docsv2/endpoints/token.html

Related

JWT token exchange via named credentials as per user

I am trying to generate a JSON Web Token(JWT) via named credentials as per user.
I want to use this named creds for authentincation purpose. So that using them after salesforce providing JSON web token, in exchange my local auth server will provide a token.
Below are the settings I have added while creating the named credentials as per user.
Label : TestJWTCredential
Name : TestJWTCredential
URL : -> external-endpoint <-
In Authentication Part
Certificate : MulesoftJWT
Identity Type : Per User
Authentication Protocol : JWT Token Exchange
Token Endpoint Url : http://localhost:8091/api/provider/token
Scope : refresh_token full
Issuer : -> my-username <-
Per User Subject : $userId
Audience : http://localhost:8091/api/provider/token
Token Valid for : 1 Hours
JWT Signing Certificate : MulesoftJWT
Ref :- https://help.salesforce.com/articleView?err=1&id=sf.named_credentials_about.htm&type=5#language-combobox
"http://localhost:8091/api/provider/token" This is the url of my authorization server which is a mule application deployed on my local.
Also while calling this named creds from developer console, it gives this error
System.CalloutException: Unable to complete the JWT token exchange.
Below is the APEX code,
HttpRequest req = new HttpRequest();
req.setEndpoint('callout:TestJWTCredential/services/oauth2/userinfo');
req.setMethod('GET');
req.setHeader('Authorization', 'Bearer'+ UserInfo.getSessionId());
Http http = new Http();
System.debug('REQUEST :::: ' + req);
HTTPResponse resp = http.send(req);
System.debug('RESPONSE :::: ' + resp.getBody());
Can any body help me how to do it.
I was just viewing some Salesforce videos on this topic. In the "Deep Dive into Salesforce Connected App - Part 3" video, at the 23:56 mark, the Salesforce presenter had to delete the "scope" value to get it to work. https://youtu.be/wN8d4vwSA-E?t=1436

WSO2 identity server - SAML2 Response Issuer verification failed

I am using the wso2 sample apps (saml2-web-app-pickup-dispatch and saml2-web-app-pickup-manager) to test single sign on through WSO2 identity server version 5.10.0
The deployment is fine and on clicking the application's login, it redirects to the WSO2 login page successfully.
User logs in successfully but receives error below.
HTTP Status 500 – Internal Server Error
Type Exception Report
Message SAML2 Response Issuer verification failed
Description The server encountered an unexpected condition that prevented it from fulfilling the request.
Exception
org.wso2.carbon.identity.sso.agent.exception.SSOAgentException: SAML2 Response Issuer verification failed
org.wso2.carbon.identity.sso.agent.saml.SAML2SSOManager.processSSOResponse(SAML2SSOManager.java:569)
org.wso2.carbon.identity.sso.agent.saml.SAML2SSOManager.processSSOResponse(SAML2SSOManager.java:525)
org.wso2.carbon.identity.sso.agent.saml.SAML2SSOManager.processResponse(SAML2SSOManager.java:358)
org.wso2.carbon.identity.sso.agent.SAML2SSOAgentFilter.doFilter(SAML2SSOAgentFilter.java:98)
Note The full stack trace of the root cause is available in the server logs.
Apache Tomcat/8.5.53
Logs from the server
TID: [-1234] [2020-04-25 19:16:55,881] [7e977cfd-8304-44ba-ab4f-4644baff988e] INFO {AUDIT_LOG} -
Initiator : wickrema | Action : Login | Target : ApplicationAuthenticationFramework |
Data : {
"ContextIdentifier" : "51f93b05-68cf-4bf4-b62b-51e3e2502889",
"AuthenticatedUser" : "wickrema",
"AuthenticatedUserTenantDomain" : "carbon.super",
"ServiceProviderName" : "saml2-web-app-pickup-dispatch",
"RequestType" : "samlsso",
"RelyingParty" : "saml2-web-app-pickup-dispatch.com",
"AuthenticatedIdPs" : "eyJ0eXAiOiJKV1QiLCAiYWxnIjoibm9uZSJ9.eyJpc3MiOiJ3c28yIiwiZXhwIjoxNTg3ODMxNDE1ODA0MzAwMCwiaWF0IjoxNTg3ODMxNDE1ODA0LCJpZHBzIjpbeyJpZHAiOiJMT0NBTCIsImF1dGhlbnRpY2F0b3IiOiJCYXNpY0F1dGhlbnRpY2F0b3IifV19."
} | Result : Success
Your Service Provider application(Pickup-Dispatch) is trying to verify if the received SAML response is issued by the expected SAML Identity Provider. WSO2 includes its ID in the SAML response's <saml:Issuer> tag.
Your application has a pre-configured entity ID for WSO2 in the saml2-web-app-pickup-dispatch.com/WEB-INF/classes/sso.properties file as below.
SAML2.IdPEntityId=localhost
Likewise, WSO2 IS populates its SAML response's issuer with the value you've configured in the Resident Identity Provider's Home Realm Identifier.
But you can override the Home realm identifier with the IdP Entity ID Alias of your Service Provider SAML configurations as below.
Bottom line, the Issuer ID of the SAML response should be the same as what you've configured in the Application as the IdP Entity ID.
Change either value to make them the same.
Code for your reference

Multiple Authorization Server

I have a Zuul Proxy that host behind it all Micro services including UI and Authorization servers .
All are part of spring cloud.
I tried to start a second Authorization Servers but that lead to the below errors
2017-11-17 08:07:47.146 INFO 9652 --- [http-nio-9191-exec-2] o.s.s.o.p.token.store.JdbcTokenStore : Failed to find access token for token 08fa5f86-4bbd-4e5b-818b-a79730232f30
2017-11-17 08:07:47.146 DEBUG 9652 --- [http-nio-9191-exec-2] p.a.OAuth2AuthenticationProcessingFilter : Authentication request failed: error="invalid_token", error_description="Invalid access token: 08fa5f86-4bbd-4e5b-818b-a79730232f30"
2017-11-17 08:07:47.147 DEBUG 9652 --- [http-nio-9191-exec-2] s.s.o.p.e.DefaultOAuth2ExceptionRenderer : Written [error="invalid_token", error_description="Invalid access token: 08fa5f86-4bbd-4e5b-818b-a79730232f30"] as "application/json;charset=UTF-8" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter#3c3df936]
also
2017-11-17 07:39:51.151 DEBUG 9652 --- [http-nio-9191-exec-3] o.s.s.o.provider.endpoint.TokenEndpoint : Clearing scope of incoming token request
2017-11-17 07:39:51.178 DEBUG 9652 --- [http-nio-9191-exec-3] .s.s.o.p.c.AuthorizationCodeTokenGranter : Getting access token for: acme
2017-11-17 07:39:51.204 INFO 9652 --- [http-nio-9191-exec-3] o.s.s.o.provider.endpoint.TokenEndpoint : Handling error: InvalidGrantException, Invalid authorization code: Pb3JKA
2017-11-17 07:40:04.797 DEBUG 9652 --- [http-nio-9191-exec-4] .s.o.p.e.FrameworkEndpointHandlerMapping : Looking up handler method for path /oauth/token
2017-11-17 07:40:04.797 DEBUG 9652 --- [http-nio-9191-exec-4] .s.o.p.e.FrameworkEndpointHandlerMapping : Returning handler method [public org.springframework.http.ResponseEntity<org.springframework.security.oauth2.common.OAuth2AccessToken> org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.postAccessToken(java.security.Principal,java.util.Map<java.lang.String, java.lang.String>) throws org.springframework.web.HttpRequestMethodNotSupportedException]
2017-11-17 07:40:04.850 DEBUG 9652 --- [http-nio-9191-exec-4] o.s.s.o.provider.endpoint.TokenEndpoint : Clearing scope of incoming token request
My conclusion was I need to have a shared session management between both authorization servers like spring session even though I am using the same jdbctoken database back end.
I could not find any sample or any one talking about this so is this correct or it should work without having a shared session.
It turned out that yes , shared session is needed like spring session , my first attempt did not work because I had mixed configuration between both servers.
After that just enabling shared session management, it all worked perfectly

IdentityServer3 - ScopeSecretValidator when using reference token

After receiving the access token (reference access token) my api middleware make a call to the instropection end point to get the jwt token. Unfortunate I'm getting a json response with an error message unauthortize.
2016-08-24 13:33:39.505 -04:00 [Debug] Start scope validation
2016-08-24 13:33:39.505 -04:00 [Debug] Start parsing Basic Authentication secret
2016-08-24 13:33:39.505 -04:00 [Debug] Parser found secret: "BasicAuthenticationSecretParser"
2016-08-24 13:33:39.505 -04:00 [Information] Secret id found: "webapp123.hybric.flow"
2016-08-24 13:33:39.507 -04:00 [Information] No scope with that name found. aborting
2016-08-24 13:33:39.507 -04:00 [Warning] Scope unauthorized to call introspection endpoint. aborting.
look like we are searching for the scopes requested by the client application using the client application id passed to the instropection endpoint.
Question:
Is his correct?
Can the Id3 remember the scopes requested by the client?
Can I call the instrospection endpint using the api ClientId? - I don;t want to use the client id of the client application that requested the reference token.
Code bellow:
var scope = (await _scopes.FindScopesAsync(new[] { parsedSecret.Id })).FirstOrDefault();
ntrospection endpoint is for validation of token and not to get Jwt. To call Introspection end point you need to pass "Scope" and "Scope secret" in the request for authentication not client id.
If you send the reference token to instrospection endpoint with valid scope name and secret you will get the claims in the response.
public async Task ValidateValidReferenceTokenUsingIntrospectionEndPoint()
{
var tokenResponse = await GetTokenResponseForClientCredentialsFlow(IdsModel.AccessTokenType.Reference);
var introspectionClient = new IntrospectionClient(
IntrospectionEndpoint,
"Api1", // scope name, scope secret
"Api1Secret");
var response = await introspectionClient.SendAsync(new IntrospectionRequest
{
Token = tokenResponse.AccessToken
});
var jsonResult = JsonConvert.DeserializeObject<Dictionary<string, object>>(response.Raw);
response.IsActive.Should().Be(true);
response.IsError.Should().Be(false);
jsonResult.Should().Contain("iss", ValidIssuer);
jsonResult.Should().Contain("aud", ValidAudience);
jsonResult.Should().Contain("client_id", "referenceTokenClient");
jsonResult.Should().Contain("client_claim1", "claim1value");
jsonResult.Should().Contain("active", true);
}

403 User Rate Limit Exceeded and 401 Invalid Credentials - Google Analytics API v3

We were able get the data from Google Analytics using Oauth2.0, but now suddenly we are getting 403 User Rate Limit Exceeded and 401 Invalid Credentials.
On server start up we are getting,
SEVERE: unable to refresh token
com.google.api.client.auth.oauth2.TokenResponseException: 403 User Rate Limit Exceeded
and for subsequent requests it is giving,
com.google.api.client.googleapis.json.GoogleJsonResponseException: 401 Unauthorized
{
"code" : 401,
"errors" : [ {
"domain" : "global",
"location" : "Authorization",
"locationType" : "header",
"message" : "Invalid Credentials",
"reason" : "authError"
} ],
"message" : "Invalid Credentials"
}
I have tested access token with following url :
https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=xxxxxxxx
I am getting valid access token message, but still i am getting Invalid Credentials. I have also tried with OAuth2 playground, here also i am getting same message.
Any help to resolve this issue.
Make sure you are caching the access tokens and that you are making a reasonable number of refresh requests. Refreshing in a tight loop (or too frequently from multiple threads or servers in a cluster) for the same user will lead to 403.
The 401 error is most likely due to the fact that getting a new access token failed and you are using an expired one.