Introduction
In this blog, I am going to explain how to setup and test OAuth username and password flow also called as Resource Owner Password Credentials Flow.With this type of authorization, the credentials (and thus the password) are sent to the client and then to the authorization server along with the client and client secret. In this flow, the user’s credentials are used by the application to request an access token which you case use to access the data on behalf of the user.
Use Case
- If you would like to access another salesforce instance data by using rest API
- Resource Owner has a trust relationship with the client like if you are making calls from internal or secured on-premise application.
Create a Connected App
- Navigate to App Setup > Create > Apps > Connected Apps > New
- Enter Connected App Name, API Name, Contact Email
- In the API (Enable OAuth Settings) Section click the Enable OAuth Settings checkbox.
- Enter an arbitrary Callback URL, such as https://login.salesforce.com/services/oauth2/callback.
- For Selected OAuth Scopes as full
- Click the Save button.
- Navigate to Administration Setup > Manage Apps > Connected Apps
- Click on the link of the name of the Connected App created above.
- Click on the Edit button
- In the Permitted Users drop-down, select Admin approved users are pre-authorized and click OK on the popup.
- For the IP Restrictions dropdown, choose to Relax IP restrictions, or choose another option based up requirements.
- For the Require Users to Log in radio button, select Refresh Token is valid until revoked.
- Click Save
- On the Connected App page, in the Profiles section click on the Manage Profiles button and Add the profile
Requesting an Access Token
The client token request should be sent in an HTTP POST to the token endpoint with the following parameters.
- grant_type— Value must be the password for this flow
- client_id— Consumer key from the connected app definition
- client_secret— Consumer secret from the connected app definition.
- username—User’s username
- password—User’s password
- format – Optional URLENCODED, JSON ,XML are supported
Here’s an example of the body of the out-of-band POST.
grant_type=password&client_id=3MVG9lKcPoNINVBIPJjdw1J9LLM82Hn FVVX19KY1uA5mu0QqEWhqKpoW3svG3XHrXDiCQjK1mdgAvhCscA9GE&client_secret= 1955279925675241571&username=testuser%40salesforce.com&password=mypassword123456
Handling the Response
{"access_token":"*****", "instance_url":"https://fscttt-dev-ed.my.salesforce.com", "id":"https://login.salesforce.com/id/00D6A000000vnuzUAA/0056A000000IpArQAK", "token_type":"Bearer", "issued_at":"1508299830083", "signature":"btIf29MJg3CuzCG/fLm69Sn6CpL3AGt5ATmI0oJeJRM="}
- access_token—Salesforce session ID that can be used with the web services API.
- token_type—Value is Bearer for all responses that include an access token.
- instance_url—A URL indicating the instance of the user’s Org. For example https://yourInstance.salesforce.com/.
- id—Identity URL that can be used to both identify the user and query for more information about the user.
- signature—Base64-encoded HMAC-SHA256 signature signed with the consumer’s private key containing the concatenated ID and issued_at. Use to verify that the identity URL hasn’t changed since the server sent it.
- issued_at—When the signature was created.
Let’s test it
now the below code is used to send the OAuth details to salesforce endpoint URL which is going to return access token. you can use access token for subsequence calls.
String endpoint='https://login.salesforce.com/services/oauth2/token'; String username = '*****'; String password = '**'; String ClientId= '***'; String ClientSecret = '**'; Httprequest req = new HttpRequest(); req.setMethod('POST'); req.setHeader('Content-Type','application/x-www-form-urlencoded'); req.setBody('grant_type=password' + '&client_id=' + ClientId + '&client_secret=' + ClientSecret + '&username=' + username + '&password=' + password ); req.setEndpoint(endpoint); Http http = new Http(); HttpResponse res= http.send(req); system.debug('body:'+res.getBody()); JSONParser parser = JSON.createParser(res.getBody()); String accessToken ; while (parser.nextToken() != null) { if ((parser.getCurrentToken() == JSONToken.FIELD_NAME)) { String fieldName = parser.getText(); parser.nextToken(); System.debug('fieldName'+fieldName); if (fieldName == 'access_token') { accessToken = parser.getText(); } } }
You can use the access token to authenticate sub sequence calls. you can use access token as similar to session id as shown below.
HttpRequest request=new HttpRequest(); request.setEndPoint('https://fscttt-dev-ed.my.salesforce.com/services/data/v40.0/sobjects/'); request.setHeader('Authorization','Bearer '+accessToken); request.setHeader('Content-Type','application/json'); request.setMethod('GET'); Http hp=new Http(); HttpResponse response=new HttpResponse(); response=hp.send(request); System.debug('response'+response.getBody());