Wednesday, May 20, 2015

[WSO2 AM] Access token related issues

Create an API with following details.

Name      : StockquoteAPI
Context   : stockquote
Version   : 1.0.0
Endpoint : http://www.webservicex.net/stockquote.asmx
Resource : GetQuote
Query      : symbol




1. Invoke with invalid token.

Client side errors:

401 Unauthorized

<ams:fault>
 <ams:code>900901</ams:code>
 <ams:message>Invalid Credentials</ams:message>
 <ams:description>Access failure for API: /stockquote, version: 1.0.0 with key: lI2XVmmRJ9_B_rbh1rwV7Pg3Pp8</ams:description>
</ams:fault>
Backend error :

[2015-05-16 22:22:14,630] ERROR - APIAuthenticationHandler API authentication failure
org.wso2.carbon.apimgt.gateway.handlers.security.APISecurityException: Access failure for API: /stockquote, version: 1.0.0 with key: lI2XVmmRJ9_B_rbh1rwV7Pg3Pp8
    at org.wso2.carbon.apimgt.gateway.handlers.security.oauth.OAuthAuthenticator.authenticate(OAuthAuthenticator.java:212)
    at org.wso2.carbon.apimgt.gateway.handlers.security.APIAuthenticationHandler.handleRequest(APIAuthenticationHandler.java:94)
    at org.apache.synapse.rest.API.process(API.java:284)
    at org.apache.synapse.rest.RESTRequestHandler.dispatchToAPI(RESTRequestHandler.java:83)
    at org.apache.synapse.rest.RESTRequestHandler.process(RESTRequestHandler.java:64)
    at org.apache.synapse.core.axis2.Axis2SynapseEnvironment.injectMessage(Axis2SynapseEnvironment.java:220)
    at org.apache.synapse.core.axis2.SynapseMessageReceiver.receive(SynapseMessageReceiver.java:83)
    at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:180)
    at org.apache.synapse.transport.passthru.ServerWorker.processNonEntityEnclosingRESTHandler(ServerWorker.java:344)
    at org.apache.synapse.transport.passthru.ServerWorker.run(ServerWorker.java:168)
    at org.apache.axis2.transport.base.threads.NativeWorkerPool$1.run(NativeWorkerPool.java:172)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)


Solution: Double check the token.

2. Invoke  API with invalid token type.

Eg: Invoke  API with application token , But resource is allowed only for the application user tokens.

Client Errors:

401 Unauthorized

<ams:fault>
   <ams:code>900905</ams:code>
   <ams:message>Incorrect Access Token Type is provided</ams:message>
   <ams:description>Access failure for API: /stockquote, version: 1.0.0 with key: lI2XVmmRJ9_B_rbh1rwV7Pg3Pp8a</ams:description>
 </ams:fault>
Back end Error:

[2015-05-16 22:29:05,262] ERROR - APIAuthenticationHandler API authentication failure
org.wso2.carbon.apimgt.gateway.handlers.security.APISecurityException: Access failure for API: /stockquote, version: 1.0.0 with key: lI2XVmmRJ9_B_rbh1rwV7Pg3Pp8a
    at org.wso2.carbon.apimgt.gateway.handlers.security.oauth.OAuthAuthenticator.authenticate(OAuthAuthenticator.java:212)
    at org.wso2.carbon.apimgt.gateway.handlers.security.APIAuthenticationHandler.handleRequest(APIAuthenticationHandler.java:94)
    at org.apache.synapse.rest.API.process(API.java:284)
    at org.apache.synapse.rest.RESTRequestHandler.dispatchToAPI(RESTRequestHandler.java:83)
    at org.apache.synapse.rest.RESTRequestHandler.process(RESTRequestHandler.java:64)
    at org.apache.synapse.core.axis2.Axis2SynapseEnvironment.injectMessage(Axis2SynapseEnvironment.java:220)
    at org.apache.synapse.core.axis2.SynapseMessageReceiver.receive(SynapseMessageReceiver.java:83)
    at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:180)
    at org.apache.synapse.transport.passthru.ServerWorker.processNonEntityEnclosingRESTHandler(ServerWorker.java:344)
    at org.apache.synapse.transport.passthru.ServerWorker.run(ServerWorker.java:168)
    at org.apache.axis2.transport.base.threads.NativeWorkerPool$1.run(NativeWorkerPool.java:172)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)

Solution: Edit  API from publisher and go to the manage wizard. Then check for the authentication type.


3. Invoke non-existing API resource.

Client Errors:

403 Forbidden

<ams:fault>
 <ams:code>900906</ams:code>
 <ams:message>No matching resource found in the API for the given request</ams:message>
 <ams:description>Access failure for API: /stockquote, version: 1.0.0 with key: lI2XVmmRJ9_B_rbh1rwV7Pg3Pp8a</ams:description>
</ams:fault>

Back end Error:

[2015-05-16 22:40:00,506] ERROR - APIKeyValidator Could not find matching resource for /GetQuote1?symbol=ibm
[2015-05-16 22:40:00,507] ERROR - APIKeyValidator Could not find matching resource for request
[2015-05-16 22:40:00,508] ERROR - APIAuthenticationHandler API authentication failure
org.wso2.carbon.apimgt.gateway.handlers.security.APISecurityException: Access failure for API: /stockquote, version: 1.0.0 with key: lI2XVmmRJ9_B_rbh1rwV7Pg3Pp8a
    at org.wso2.carbon.apimgt.gateway.handlers.security.oauth.OAuthAuthenticator.authenticate(OAuthAuthenticator.java:212)
    at org.wso2.carbon.apimgt.gateway.handlers.security.APIAuthenticationHandler.handleRequest(APIAuthenticationHandler.java:94)
    at org.apache.synapse.rest.API.process(API.java:284)
    at org.apache.synapse.rest.RESTRequestHandler.dispatchToAPI(RESTRequestHandler.java:83)
    at org.apache.synapse.rest.RESTRequestHandler.process(RESTRequestHandler.java:64)
    at org.apache.synapse.core.axis2.Axis2SynapseEnvironment.injectMessage(Axis2SynapseEnvironment.java:220)
    at org.apache.synapse.core.axis2.SynapseMessageReceiver.receive(SynapseMessageReceiver.java:83)
    at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:180)
    at org.apache.synapse.transport.passthru.ServerWorker.processNonEntityEnclosingRESTHandler(ServerWorker.java:344)
    at org.apache.synapse.transport.passthru.ServerWorker.run(ServerWorker.java:168)
    at org.apache.axis2.transport.base.threads.NativeWorkerPool$1.run(NativeWorkerPool.java:172)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745 

Solution: Edit  API from publisher (Design wizard) and double check the availability of the resource names.


4. Token has generated without scope (scope as default), But API resource configured with scope.

Client Errors:

403 Forbidden

<ams:fault>
 <ams:code>900910</ams:code>
 <ams:message>The access token does not allow you to access the requested resource</ams:message>
 <ams:description>Access failure for API: /stockquote, version: 1.0.0 with key: 1e1b6aa805d4bfd89b6e36ac48345a</ams:description>
</ams:fault>
Back end Error:

[2015-05-16 23:08:57,103] ERROR - APIAuthenticationHandler API authentication failure
org.wso2.carbon.apimgt.gateway.handlers.security.APISecurityException: Access failure for API: /stockquote, version: 1.0.0 with key: 1e1b6aa805d4bfd89b6e36ac48345a
    at org.wso2.carbon.apimgt.gateway.handlers.security.oauth.OAuthAuthenticator.authenticate(OAuthAuthenticator.java:212)
    at org.wso2.carbon.apimgt.gateway.handlers.security.APIAuthenticationHandler.handleRequest(APIAuthenticationHandler.java:94)
    at org.apache.synapse.rest.API.process(API.java:284)
    at org.apache.synapse.rest.RESTRequestHandler.dispatchToAPI(RESTRequestHandler.java:83)
    at org.apache.synapse.rest.RESTRequestHandler.process(RESTRequestHandler.java:64)
    at org.apache.synapse.core.axis2.Axis2SynapseEnvironment.injectMessage(Axis2SynapseEnvironment.java:220)
    at org.apache.synapse.core.axis2.SynapseMessageReceiver.receive(SynapseMessageReceiver.java:83)
    at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:180)
    at org.apache.synapse.transport.passthru.ServerWorker.processNonEntityEnclosingRESTHandler(ServerWorker.java:344)
    at org.apache.synapse.transport.passthru.ServerWorker.run(ServerWorker.java:168)
    at org.apache.axis2.transport.base.threads.NativeWorkerPool$1.run(NativeWorkerPool.java:172)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)


Solution: Generate new token with scope(s).
eg:
curl -k -d "grant_type=password&username=admin&password=admin&scope=stock" -H "Authorization: Basic THUwUVlFUUIxYVRKY3B6YTIxQnFxa0ZhU1I0YTo0ZE1FRUs3N1k4emZhSU56aVdGbTB1aFNBdjBh, Content-Type: application/x-www-form-urlencoded" https://localhost:8243/token


5. Invoke with expired token.

Client Errors

401 Unauthorized

<ams:fault>
 <ams:code>900903</ams:code>
 <ams:message>Access Token Expired</ams:message>
 <ams:description>Access failure for API: /stockquote, version: 1.0.0 with key: 8d438b49d9b24c752ce2b89c24bc198</ams:description>
</ams:fault>

Back end error:

[2015-05-17 13:30:50,155] ERROR - APIAuthenticationHandler API authentication failure
org.wso2.carbon.apimgt.gateway.handlers.security.APISecurityException: Access failure for API: /stockquote, version: 1.0.0 with key: 8d438b49d9b24c752ce2b89c24bc198
    at org.wso2.carbon.apimgt.gateway.handlers.security.oauth.OAuthAuthenticator.authenticate(OAuthAuthenticator.java:212)
    at org.wso2.carbon.apimgt.gateway.handlers.security.APIAuthenticationHandler.handleRequest(APIAuthenticationHandler.java:94)
    at org.apache.synapse.rest.API.process(API.java:284)
    at org.apache.synapse.rest.RESTRequestHandler.dispatchToAPI(RESTRequestHandler.java:83)
    at org.apache.synapse.rest.RESTRequestHandler.process(RESTRequestHandler.java:64)
    at org.apache.synapse.core.axis2.Axis2SynapseEnvironment.injectMessage(Axis2SynapseEnvironment.java:220)
    at org.apache.synapse.core.axis2.SynapseMessageReceiver.receive(SynapseMessageReceiver.java:83)
    at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:180)
    at org.apache.synapse.transport.passthru.ServerWorker.processNonEntityEnclosingRESTHandler(ServerWorker.java:344)
    at org.apache.synapse.transport.passthru.ServerWorker.run(ServerWorker.java:168)
    at org.apache.axis2.transport.base.threads.NativeWorkerPool$1.run(NativeWorkerPool.java:172)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)

Solution : You need to re-generate a token. If it is user token , you can use the refresh token to generate new token.

curl -k -d "grant_type=refresh_token&refresh_token=<retoken>&scope=PRODUCTION" -H "Authorization: Basic SVpzSWk2SERiQjVlOFZLZFpBblVpX2ZaM2Y4YTpHbTBiSjZvV1Y4ZkM1T1FMTGxDNmpzbEFDVzhh, Content-Type: application/x-www-form-urlencoded" https://localhost:8243/token

6. Token generated with 60 seconds life span , but API can invoke with that token after 60 seconds.


Reason:

The default token validation time is 3600 seconds that is configured in identity.xml file.
<AccessTokenDefaultValidityPeriod>3600</AccessTokenDefaultValidityPeriod>
But there is another configuraion called "TimestampSkew"
<TimestampSkew>300</TimestampSkew>
You can find the usage of that configuration here https://docs.wso2.com/display/AM180/Token+API#TokenAPI-Configuringthetokenexpirationtime

According to that description, token will be valid until the TimestampSkew eventhough the generated time less than the TimestampSkew.

7. User can generate access token, but API is not subscribed to that application.

Client Errors

401 Unauthorized

<ams:fault>
 <ams:code>900901</ams:code>
 <ams:message>Invalid Credentials</ams:message>
 <ams:description>Access failure for API: /stockquote, version: 1.0.0 with key: b31077463e7e7856762234c5d0b599</ams:description>
</ams:fault>
Back end Error

[2015-05-17 22:32:44,609] ERROR - APIAuthenticationHandler API authentication failure
org.wso2.carbon.apimgt.gateway.handlers.security.APISecurityException: Access failure for API: /stockquote, version: 1.0.0 with key: b31077463e7e7856762234c5d0b599
    at org.wso2.carbon.apimgt.gateway.handlers.security.oauth.OAuthAuthenticator.authenticate(OAuthAuthenticator.java:212)
    at org.wso2.carbon.apimgt.gateway.handlers.security.APIAuthenticationHandler.handleRequest(APIAuthenticationHandler.java:94)
    at org.apache.synapse.rest.API.process(API.java:284)
    at org.apache.synapse.rest.RESTRequestHandler.dispatchToAPI(RESTRequestHandler.java:83)
    at org.apache.synapse.rest.RESTRequestHandler.process(RESTRequestHandler.java:64)
    at org.apache.synapse.core.axis2.Axis2SynapseEnvironment.injectMessage(Axis2SynapseEnvironment.java:220)
    at org.apache.synapse.core.axis2.SynapseMessageReceiver.receive(SynapseMessageReceiver.java:83)
    at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:180)
    at org.apache.synapse.transport.passthru.ServerWorker.processNonEntityEnclosingRESTHandler(ServerWorker.java:344)
    at org.apache.synapse.transport.passthru.ServerWorker.run(ServerWorker.java:168)
    at org.apache.axis2.transport.base.threads.NativeWorkerPool$1.run(NativeWorkerPool.java:172)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)  

Solution: Logged in to the store and subscribe API to application.