I am trying to get New access token for Oauth 2.0 with client credential. I am always getting Forbidden or unauthorized error. While I can directly login to url https://api.flipkart.net/oauth-service/oauth/token?grant_type=client_credentials&scope=Seller_Api and generate the token but going with below code I am not able to generate token
public static String getAccessToken(OAuth2Details oauthDetails) {
URL url;
HttpURLConnection con;
String accessToken = null;
try {
url = new URL("https://api.flipkart.net/oauth-service/oauth/token\?grant_type\=client_credentials\&scope=Seller_Api");
con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("Accept", "application/json");
con.setDoOutput(true);
con.setDoInput(true);
String clientId = oauthDetails.getClientId();
String clientSecret = oauthDetails.getClientSecret();
String scope = oauthDetails.getScope();
System.out
.println("Authorization server expects Basic authentication");
con.setRequestProperty(
OAuthConstants.AUTHORIZATION,
getBasicAuthorizationHeader(oauthDetails.getClientId(),
oauthDetails.getClientSecret()));
System.out.println("Retry with client credentials");
int code = con.getResponseCode();
System.out.print(con.getResponseMessage());
BufferedReader br = new BufferedReader(new InputStreamReader(
con.getErrorStream()));
if (code == 401 || code == 403) {
String s;
while ((s = br.readLine()) != null) {
System.out.print(br.readLine());
}
con.disconnect();
System.out
.println("Could not authenticate using client credentials.");
throw new RuntimeException(
"Could not retrieve access token for client: "
+ oauthDetails.getClientId());
}
}
Map<String, String> map = handleResponse(con);
accessToken = map.get(OAuthConstants.ACCESS_TOKEN);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return accessToken;
}
public static String getBasicAuthorizationHeader(String username,
String password) {
System.out.println("uu" + OAuthConstants.BASIC + " "
+ encodeCredentials(username, password));
return OAuthConstants.BASIC + " "
+ encodeCredentials(username, password);
}
public static String encodeCredentials(String username, String password) {
String cred = username + ":" + password;
return new String(Base64.encodeBase64(cred.getBytes()));
}
Remove the "\" from your url
url = new URL("https://api.flipkart.net/oauth-service/oauth/token?grant_type=client_credentials&scope=Seller_Api");
Also make the app-id and and secretlike this
<app-id>:<app_secret>
example kdfjkfjdsakfjd93842908039489:kdjsfkajidsjf8939034820
oauthDetails.getClientId()+":"+oauthDetails.getClientSecret()
Related
Here department is PartitionKey and id is RowKey.
Error: Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
Status Code: Forbidden
If someone could help me to resolve this error It would be great.
Thanks in advance :)
public HttpClient getRequestHeaders(string requestType, HttpClient Newrequest, string storageAccount, string accessKey, string resource, int Length = 0)
{
HttpClient Client = Newrequest;
var RequestDateString = DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture);
if (Client.DefaultRequestHeaders.Contains("x-ms-date"))
Client.DefaultRequestHeaders.Remove("x-ms-date");
Client.DefaultRequestHeaders.Add("x-ms-date", RequestDateString);
var requestUri = #"https://" + storageAccount + ".table.core.windows.net/" + resource;
Client.DefaultRequestHeaders.Accept.Clear();
Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
if (Client.DefaultRequestHeaders.Contains("x-ms-version"))
Client.DefaultRequestHeaders.Remove("x-ms-version");
Client.DefaultRequestHeaders.Add("x-ms-version", "2015-12-11");
if (Client.DefaultRequestHeaders.Contains("DataServiceVersion"))
Client.DefaultRequestHeaders.Remove("DataServiceVersion");
Client.DefaultRequestHeaders.Add("DataServiceVersion", "3.0;NetFx");
if (Client.DefaultRequestHeaders.Contains("MaxDataServiceVersion"))
Client.DefaultRequestHeaders.Remove("MaxDataServiceVersion");
Client.DefaultRequestHeaders.Add("MaxDataServiceVersion", "3.0;NetFx");
if (Client.DefaultRequestHeaders.Contains("Authorization"))
Client.DefaultRequestHeaders.Remove("Authorization");
var sas = getAuthToken(Client, storageAccount, accessKey, resource);
Client.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", sas);
return Client;
}
public string getAuthToken(HttpClient request, string storageAccount, string accessKey, string resource)
{
try
{
string sAuthTokn = "";
string stringToSign = DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture) + "\n";
stringToSign += "/" + storageAccount + "/" + resource;
HMACSHA256 hasher = new HMACSHA256(Convert.FromBase64String(accessKey));
sAuthTokn = "SharedKeyLite " + storageAccount + ":" + Convert.ToBase64String(hasher.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)));
return sAuthTokn;
}
catch (Exception ex)
{
throw ex;
}
}
public async Task<string> GetEntityByID(string department, string id)
{
EmployeeDetails emp = new EmployeeDetails();
string storageAccount = "sample";
string resourcePath = "SampleAzureTableStorage";
string accessKey = "<sample>";
string uri = #"https://" + storageAccount + ".table.core.windows.net/" + resourcePath + "/";
var request = _httpClientFactory.CreateClient();
request = getRequestHeaders("GET", request, storageAccount, accessKey, resourcePath);
try
{
var httpResponseMessage = await request.GetAsync(uri + department + "/" + id);
httpResponseMessage.EnsureSuccessStatusCode();
return await httpResponseMessage.Content.ReadAsStringAsync();
}
catch (WebException ex)
{
throw ex;
}
}
I believe the reason you are getting this error is because you are using two different dates in your code.
You are getting the current date in getRequestHeaders method and then a different date in getAuthToken. This would cause the authorization header mismatch.
I would recommend modifying getAuthToken method and pass the date/time value computed in getRequestHeaders method.
Try the following code:
public HttpClient getRequestHeaders(string requestType, HttpClient Newrequest, string storageAccount, string accessKey, string resource, string partitionKey, string rowKey, int Length = 0)
{
HttpClient Client = Newrequest;
var RequestDateString = DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture);
if (Client.DefaultRequestHeaders.Contains("x-ms-date"))
Client.DefaultRequestHeaders.Remove("x-ms-date");
Client.DefaultRequestHeaders.Add("x-ms-date", RequestDateString);
var requestUri = #"https://" + storageAccount + ".table.core.windows.net/" + resource;
Client.DefaultRequestHeaders.Accept.Clear();
Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
if (Client.DefaultRequestHeaders.Contains("x-ms-version"))
Client.DefaultRequestHeaders.Remove("x-ms-version");
Client.DefaultRequestHeaders.Add("x-ms-version", "2015-12-11");
if (Client.DefaultRequestHeaders.Contains("DataServiceVersion"))
Client.DefaultRequestHeaders.Remove("DataServiceVersion");
Client.DefaultRequestHeaders.Add("DataServiceVersion", "3.0;NetFx");
if (Client.DefaultRequestHeaders.Contains("MaxDataServiceVersion"))
Client.DefaultRequestHeaders.Remove("MaxDataServiceVersion");
Client.DefaultRequestHeaders.Add("MaxDataServiceVersion", "3.0;NetFx");
if (Client.DefaultRequestHeaders.Contains("Authorization"))
Client.DefaultRequestHeaders.Remove("Authorization");
var sas = getAuthToken(Client, storageAccount, accessKey, resource, RequestDateString, partitionKey, rowKey);
Client.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", sas);
return Client;
}
public string getAuthToken(HttpClient request, string storageAccount, string accessKey, string resource, string requestDateString, string partitionKey, string rowKey)
{
try
{
string sAuthTokn = "";
string stringToSign = requestDateString + "\n";
stringToSign += "/" + storageAccount + "/" + resource + "(PartitionKey='" + partitionKey + "',RowKey='" + rowKey + "')";
HMACSHA256 hasher = new HMACSHA256(Convert.FromBase64String(accessKey));
sAuthTokn = "SharedKeyLite " + storageAccount + ":" + Convert.ToBase64String(hasher.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)));
return sAuthTokn;
}
catch (Exception ex)
{
throw ex;
}
}
public async Task<string> GetEntityByID(string department, string id)
{
EmployeeDetails emp = new EmployeeDetails();
string storageAccount = "sample";
string resourcePath = "SampleAzureTableStorage";
string accessKey = "<sample>";
string uri = #"https://" + storageAccount + ".table.core.windows.net/" + resourcePath + "/";
var request = _httpClientFactory.CreateClient();
request = getRequestHeaders("GET", request, storageAccount, accessKey, resourcePath, department, id);
try
{
var httpResponseMessage = await request.GetAsync(uri + "(PartitionKey='" + department + "',RowKey='" + id + "')");
httpResponseMessage.EnsureSuccessStatusCode();
return await httpResponseMessage.Content.ReadAsStringAsync();
}
catch (WebException ex)
{
throw ex;
}
}
I think the problem is in your Authorization header.
Here is your code:
Client.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", sas);
I think you should change it to:
Client.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", $"Bearer {sas}");
Otherwise the code looks righteous.
I need to use OAuth 2.0 for accessing user's data.
I have used glassfish security oauth 2 library to implement OAuth 2 client.
I am not sure how can I get code and state values after user granted permission to access the data.
ClientIdentifier clientIdentifier = new ClientIdentifier(clientId, secret);
OAuth2CodeGrantFlow.Builder builder =
OAuth2ClientSupport.authorizationCodeGrantFlowBuilder(clientIdentifier,
HOST_NAME + "/authorize",
HOST_NAME + "/token");
OAuth2CodeGrantFlow flow = builder
.scope("activity")
.redirectUri("http://example.com/#/")
.build();
String authorizationUri = flow.start();
System.out.println(authorizationUri);
String redirectedUrl = getFinalRedirectedUrl(authorizationUri);
System.out.print("Enter the authorization code: ");
String code = "";
String state = "";
try {
code = IN.readLine();
state = IN.readLine();
} catch (final IOException ex) {
throw new RuntimeException(ex);
}
final TokenResult result = flow.finish(code, state);
System.out.println("Access Token: " + result.getAllProperties());
}
For Now, I am taking code and status manually from the redirected url. How Can I automate it.
I tried
public static String getFinalRedirectedUrl(String url) {
String finalRedirectedUrl = url;
try {
HttpURLConnection connection;
do {
connection = (HttpURLConnection) new URL(finalRedirectedUrl).openConnection();
connection.setInstanceFollowRedirects(false);
connection.setUseCaches(false);
connection.setRequestMethod("GET");
connection.connect();
int responseCode = connection.getResponseCode();
if (responseCode >= 300 && responseCode < 400) {
String redirectedUrl = connection.getHeaderField("Location");
if (null == redirectedUrl) {
break;
}
finalRedirectedUrl = redirectedUrl;
} else
break;
} while (connection.getResponseCode() != HttpURLConnection.HTTP_OK);
connection.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(finalRedirectedUrl);
return finalRedirectedUrl;
}
but it returns the login page.
I am using OAuth authenication in Jira to test some methods in jira using JIRA Rest Java Client. I have got the access token using OAuth authenication that I need to pass on Jira URL. Here is all what I have got to get access token.
Token is 38ESi9IJW5u3vKDslPFtuV1ZtzDpr6zi
Token secret is cnDSL8oJyuoaQdRcFDwgHzLppSshQn9b
Retrieved request token. go to http://bmh1060149:8080/plugins/servlet/oauth/authorize?oauth_token=38ESi9IJW5u3vKDslPFtuV1ZtzDpr6zi
Access token is : 015CeJiH8cpI5R3OKpNco158kApq8YwV
Now I am passing that access token to Jira URL but I am getting an empty array. Please let me know where I am doing wrong or what changes do I need to incorporate into my code to make this thing work. Here is my code.
public void getAllIssueTypesUsingOAuth(JiraCQCredential jcqcred) {
System.out.println("Inside getAllIssuetypeAssociatedToProject for JiraAdapterImpl");
//String username = jcqcred.getUserName();
//String password = jcqcred.getPassword();
String jiraURL = jcqcred.getJiraUrl();
if (!jiraURL.endsWith("/")) {
jiraURL = jiraURL + "/";
}
try {
String accessToken = JiraAdapterImpl.getAccessToken(); // This method is giving me access token
URL url = new URL(jiraURL + "rest/api/2" + "/" + "issuetype?access_token=" + accessToken);
HttpURLConnection httpConnection = (HttpURLConnection) url.openConnection();
httpConnection.addRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)");
httpConnection.setRequestProperty("Content-Type", "application/json");
httpConnection.setRequestMethod("GET");
BufferedReader reader = new BufferedReader(new InputStreamReader(httpConnection.getInputStream()));
StringBuilder sb = new StringBuilder();
String line = "";
while ((line = reader.readLine()) != null) {
sb.append(line);
}
String issueTypes = sb.toString();
System.out.println("Issuetype associated to project are\n" + issueTypes);
JSONArray jsonArray = new JSONArray(issueTypes);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
String issueNames = (String) jsonObject.get("name");
System.out.println(issueNames);
}
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
}
Its giving me an empty array like []
Hi After searching the little bit I finally managed to a find the solution to the above problem. After getting the access token just pass that access token to the makeAuthenticatedRequest(url, accessToken) method that will give you the resultant data which you want to retrive. Here url is the url which you want to hit to get the resultant data.
private AtlassianOAuthClient getJiraOAuthClient() {
final String baseURI = "http://bmh1060149:8080";
final String consumerKey = "hardcoded-consumer";
final String consumerPrivatekey = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDFkPMZQaTqsSXI+bSI65rSVaDzic6WFA3WCZMVMi7lYXJAUdkXo4DgdfvEBO21Bno3bXIoxqS411G8S53I39yhSp7z2vcB76uQQifi0LEaklZfbTnFUXcKCyfwgKPp0tQVA+JZei6hnscbSw8qEItdc69ReZ6SK+3LHhvFUUP1nLhJDsgdPHRXSllgZzqvWAXQupGYZVANpBJuK+KAfiaVXCgA71N9xx/5XTSFi5K+e1T4HVnKAzDasAUt7Mmad+1PE+56Gpa73FLk1Ww+xaAEvss6LehjyWHM5iNswoNYzrNS2k6ZYkDnZxUlbrPDELETbz/n3YgBHGUlyrXi2PBjAgMBAAECggEAAtMctqq6meRofuQbEa4Uq5cv0uuQeZLV086VPMNX6k2nXYYODYl36T2mmNndMC5khvBYpn6Ykk/5yjBmlB2nQOMZPLFPwMZVdJ2Nhm+naJLZC0o7fje49PrN2mFsdoZeI+LHVLIrgoILpLdBAz/zTiW+RvLvMnXQU4wdp4eO6i8J/Jwh0AY8rWsAGkk1mdZDwklPZZiwR3z+DDsDwPxFs8z6cE5rWJd2c/fhAQrHwOXyrQPsGyLHTOqS3BkjtEZrKRUlfdgV76VlThwrE5pAWuO0GPyfK/XCklwcNS1a5XxCOq3uUogWRhCsqUX6pYfAVS6xzX56MGDndQVlp7U5uQKBgQDyTDwhsNTWlmr++FyYrc6liSF9NEMBNDubrfLJH1kaOp590bE8fu3BG0UlkVcueUr05e33Kx1DMSFW72lR4dht1jruWsbFp6LlT3SUtyW2kcSet3fC8gySs2r6NncsZ2XFPoxTkalKpQ1atGoBe3XIKeT8RDZtgoLztQy7/7yANQKBgQDQvSHEKS5SttoFFf4YkUh2QmNX5m7XaDlTLB/3xjnlz8NWOweK1aVysb4t2Tct/SR4ZZ/qZDBlaaj4X9h9nlxxIMoXEyX6Ilc4tyCWBXxn6HFMSa/Rrq662Vzz228cPvW2XGOQWdj7IqwKO9cXgJkI5W84YtMtYrTPLDSjhfpxNwKBgGVCoPq/iSOpN0wZhbE1KiCaP8mwlrQhHSxBtS6CkF1a1DPm97g9n6VNfUdnB1Vf0YipsxrSBOe416MaaRyUUzwMBRLqExo1pelJnIIuTG+RWeeu6zkoqUKCAxpQuttu1uRo8IJYZLTSZ9NZhNfbveyKPa2D4G9B1PJ+3rSO+ztlAoGAZNRHQEMILkpHLBfAgsuC7iUJacdUmVauAiAZXQ1yoDDo0Xl4HjcvUSTMkccQIXXbLREh2w4EVqhgR4G8yIk7bCYDmHvWZ2o5KZtD8VO7EVI1kD0z4Zx4qKcggGbp2AINnMYqDetopX7NDbB0KNUklyiEvf72tUCtyDk5QBgSrqcCgYEAnlg3ByRd/qTFz/darZi9ehT68Cq0CS7/B9YvfnF7YKTAv6J2Hd/i9jGKcc27x6IMi0vf7zrqCyTMq56omiLdu941oWfsOnwffWRBInvrUWTj6yGHOYUtg2z4xESUoFYDeWwe/vX6TugL3oXSX3Sy3KWGlJhn/OmsN2fgajHRip0=";
AtlassianOAuthClient jiraoAuthClient = new AtlassianOAuthClient(consumerKey, consumerPrivatekey, baseURI, "");
return jiraoAuthClient;
}
Here is the code to get Access Token
private String getAccessToken() {
AtlassianOAuthClient jiraoAuthClient = getJiraOAuthClient();
TokenSecretVerifierHolder requestToken = jiraoAuthClient.getRequestToken();
String authorizeUrl = jiraoAuthClient.getAuthorizeUrlForToken(requestToken.token);
String token = requestToken.token;
String tokenSecret = requestToken.secret;
System.out.println("Token is " + requestToken.token);
System.out.println("Token secret is " + requestToken.secret);
System.out.println("Retrieved request token. go to " + authorizeUrl);
String accessToken = jiraoAuthClient.swapRequestTokenForAccessToken(token, tokenSecret, "");
System.out.println("Access token is : " + accessToken);
return accessToken;
}
This is the method you call to retrieve the data.
public void getAllCommentOfIssueUsingOAuth() {
logger.info("Inside getAllCommentOfIssue for JiraAdapterImpl");
AtlassianOAuthClient jiraoAuthClient = getJiraOAuthClient();
String accessToken = getAccessToken();
String url = "your Jira URL";
String responseAsString = jiraoAuthClient.makeAuthenticatedRequest(url, accessToken);
System.out.println(responseAsString);
}
This will give you the resultant JSON data or XML data in resultantString.
Is there any way to get SAML token for the Application Pool Identity User (configured user)?
when we configure application pool dentity stores config entries (user name & password) in applicationHost.config under %systemroot%\System32\Inetsrv\config path.
When application starts, it picks the user name and encrypted password for authentication. After successful authentication, will it follow token based authentication for subsequent calls or will always follows basic authentication ?
If it token based then how can i get the SAML token for application pool identity user, after the first response?
if any links please let me know.
Thanks in advance.
To Get SAML Assertion for Application pool Identity Or Logged on user :
string rpLoginUrl = string.Format(SapConfiguration.AdfsSignInUrl, SapConfiguration.AdfsInstance, HttpUtility.UrlEncode(GetSapTokenServiceUrl));
string htmlContent;
try
{
do
{
var result = await Client.GetAsync(rpLoginUrl);
htmlContent = await result.Content.ReadAsStringAsync();
IEnumerable<string> values;
if (result.Headers.TryGetValues("location", out values))
{
foreach (string s in values)
{
if (s.StartsWith("/"))
{
rpLoginUrl = rpLoginUrl.Substring(0, rpLoginUrl.IndexOf("/adfs/ls", StringComparison.Ordinal)) + s;
}
else
{
rpLoginUrl = s;
}
}
}
else
{
rpLoginUrl = "";
}
} while (!string.IsNullOrEmpty(rpLoginUrl));
}
catch (Exception exp)
{
var additionalInfo = $" additionalInfo : [rpLoginUrl: {rpLoginUrl}]";
throw new SecurityException($"SapAuthorization.GetSamlResponseForProcessIdentityAsync is failed, {additionalInfo}", exp);
}
var reg = new Regex("SAMLResponse\\W+value\\=\\\"([^\\\"]+)\\\"");
var matches = reg.Matches(htmlContent);
string lastMatch = null;
foreach (Match m in matches)
{
lastMatch = m.Groups[1].Value;
}
return lastMatch;
Ans 1: By Using Adal flow to get Jwt token for Logged on User,
if (!AdfsConfiguration.IsInitialized) throw new SecurityException(Constants.AdfsConfigurationInitilizationExceptionMessage);
if (string.IsNullOrEmpty(AdfsConfiguration.AdfsAuthorityUrl)) throw new SecurityException(Constants.AdfsConfigurationAdfsAuthorityUrlInitilizationExceptionMessage);
try
{
var authenticationContext = new AuthenticationContext(string.Format(AdfsConfiguration.AdfsAuthorityUrl, AdfsConfiguration.AdfsInstance, AdfsConfiguration.Resource), false);
var asyncRequest = authenticationContext.AcquireTokenAsync(AdfsConfiguration.Resource, AdfsConfiguration.ClientId, new Uri(AdfsConfiguration.RedirectUri), new PlatformParameters(PromptBehavior.Auto));
var accessToken = asyncRequest.Result.AccessToken;
return accessToken;
}
catch (Exception exp)
{
var additionalInfo = $" additionalInfo : [authenticationContext : {string.Format(AdfsConfiguration.AdfsAuthorityUrl, AdfsConfiguration.AdfsInstance, AdfsConfiguration.Resource)}]";
throw new SecurityException($"AdfsAuthorization.GetAdfsOAuthJwtAccessTokenForWinAppUserUsingAdal is failed, {additionalInfo}", exp);
}
Ans 2: By Auth code flow to get Jwt token for logged on user or Application pool identity user.
step 1 : Get Auth code from Adfs server
var authUrl = string.Format(AdfsConfiguration.AdfsAuthUrl, AdfsConfiguration.AdfsInstance, AdfsConfiguration.ClientId, AdfsConfiguration.Resource, AdfsConfiguration.UrlEncodedRedirectUri);
var authCode = "";
try
{
do
{
var result = await Client.GetAsync(authUrl);
await result.Content.ReadAsStringAsync();
IEnumerable<string> values;
if (result.Headers.TryGetValues("location", out values))
{
foreach (string s in values)
{
if (s.Contains("code="))
{
authUrl = "";
authCode = s.Substring(s.IndexOf("code=", StringComparison.Ordinal) + 5);
}
else
{
authUrl = s;
}
}
}
else
{
authUrl = "";
}
} while (!string.IsNullOrEmpty(authUrl));
return authCode;
}
catch (Exception exp)
{
var additionalInfo = $"additionalInfo : [authUrl: {authUrl}]";
throw new SecurityException($"AdfsAuthorization.GetAuthCodeForWinAppUserAsync is failed, {additionalInfo}", exp);
}
Step 2 : Pass Auth code to get jwt token from Adfs server
if (!AdfsConfiguration.IsInitialized) throw new SecurityException(Constants.AdfsConfigurationInitilizationExceptionMessage);
var client = new WebClient();
try
{
if (AdfsConfiguration.UseProxy == "Y")
{
var proxyObject = new WebProxy("Proxy", 80) { Credentials = CredentialCache.DefaultNetworkCredentials };
client.Proxy = proxyObject;
}
//Uri address = new Uri(String.Format("https://{0}/adfs/oauth2/token/", AdfsInstance));
Uri address = new Uri(string.Format(AdfsConfiguration.AdfsTokenServiceUrl, AdfsConfiguration.AdfsInstance));
Uri redirectAddress = new Uri(AdfsConfiguration.RedirectUri);
NameValueCollection values = new NameValueCollection
{
{"client_id", AdfsConfiguration.ClientId},
{"grant_type", "authorization_code"},
{"code", code},
{"redirect_uri", redirectAddress.ToString()}
};
byte[] responseBytes = client.UploadValues(address, "POST", values);
string response = System.Text.Encoding.UTF8.GetString(responseBytes);
return response;
}
catch (Exception exp)
{
var additionalInfo = $" additionalInfo : [address: {string.Format(AdfsConfiguration.AdfsTokenServiceUrl, AdfsConfiguration.AdfsInstance) }, redirect Uri :{AdfsConfiguration.RedirectUri}]";
throw new SecurityException($"AdfsAuthorization.GetAdfsOAuthTokenByAuthCode is failed, {additionalInfo}", exp);
}
finally
{
client.Dispose();
}
I wrote a Java based sign-off routine (token revocation) for an Oauth2 authentication flow. See below the code implementation following the cURL protocol instructions in the manual described [ here ]. The program code compiles and works without error message, but after the log-off the user accounts still remains in a connected state under the WSO2 dashboard query.
See below the Servlet class that triggers the log-off function:
class SignoffServlet extends HttpServlet {
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException {
try{
String accessToken = (String) req.getSession().getAttribute("access_token");
System.out.println("Start Logoff processing for revoke of the token: " + accessToken);
URL url = new URL (Oauth2Server + "/oauth2/revoke?token="+accessToken);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// new encode with Apache codec (for Java8 use native lib)
String userCredentials = clientId + ":" + clientSecret;
String basicAuth = "Basic " + new String(new Base64().encode(userCredentials.getBytes()));
connection.setRequestProperty ("Authorization", basicAuth);
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
connection.addRequestProperty("token", accessToken);
connection.addRequestProperty("token_type_hint", "access_token");
//connection.setRequestProperty("token", accessToken);
// connection.setRequestProperty("token_type_hint", "access_token");
connection.setRequestMethod("POST");
connection.setDoOutput(true);
InputStream content = (InputStream)connection.getInputStream();
BufferedReader in =
new BufferedReader (new InputStreamReader (content));
String line;
while ((line = in.readLine()) != null) {
System.out.println(line);
System.out.println("Logoff finished sucessfully");
}
} catch(Exception e) {
System.out.println("Logoff failed, error cause: " + e.toString());
e.printStackTrace();
}
System.out.println("Logoff finished sucessfully");
// return the json of the user's basic info
String html_header = "<html><body>";
String myjson = "<br>Logoff completed sucessfully";
myjson += "<br><br><b><a href='./index.html'>Back to login page</a></b><br>";
String html_footer = "</body></html>";
String mypage = html_header + myjson + html_footer;
resp.setContentType("text/html");
resp.getWriter().println(myjson);
}
}
Advice about what to change in the Java code to activate the sign-off function for Oauth 2.0 is welcome.
Thanks for detailed explanations about the difference between authorization and authentication in Oauth2. See below the code that is able to revoke the valid Oauth2 token:
class SignoffServlet extends HttpServlet {
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException {
String outputl = "";
try{
String accessToken = (String) req.getSession().getAttribute("access_token");
// testing .. inhibu acivate this line: // revoke accessToken = "abc";
System.out.println("Start Logoff processing for revoke of the token: " + accessToken);
// URL url = new URL (Oauth2Server + "/oauth2/revoke?token="+accessToken);
// URL url = new URL (Oauth2Server + "/oauth2endpoints/revoke");
URL url = new URL (Oauth2Server + "/oauth2/revoke");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
// new encode with Apache codec (for Java8 use native lib)
String userCredentials = clientId + ":" + clientSecret;
String basicAuth = "Basic " + new String(new Base64().encode(userCredentials.getBytes()));
basicAuth = basicAuth.replace("\\r", "");
basicAuth = basicAuth.replace("\\n", "");
connection.setRequestProperty ("Authorization", basicAuth);
connection.setUseCaches(false);
connection.setDoInput(true);
connection.setDoOutput(true);
// send data
// String str = "{\"token\": \"" + accessToken + "\",\"token_type_hint\":\"access_token\"}";
// example of JSON string "{\"x\": \"val1\",\"y\":\"val2\"}";
//byte[] outputInBytes = str.getBytes("UTF-8");
//OutputStream os = connection.getOutputStream();
//os.write( outputInBytes );
// os.close();
//send request
DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
wr.writeBytes("token=" + accessToken);
wr.flush();
wr.close();
// end of new method
InputStream content = (InputStream)connection.getInputStream();
BufferedReader in =
new BufferedReader (new InputStreamReader (content));
String line;
while ((line = in.readLine()) != null) {
// System.out.println(line); // for debug only
outputl += line;
}
} catch(Exception e) {
System.out.println("Logoff failed, error cause: " + e.toString());
e.printStackTrace();
}
System.out.println("Logoff finished successfully");
// return the json of the user's basic info
// customized Apache HTTP GET with header - Claude, 27 August 2015 reading user information
// ===============================================================================================
String tokeninfo = "";
String infourl = Oauth2Server + "/oauth2/userinfo?schema=openid";
StringBuilder infobody = new StringBuilder();
DefaultHttpClient infohttpclient = new DefaultHttpClient(); // create new httpClient
HttpGet infohttpGet = new HttpGet(infourl); // create new httpGet object
// get some info about the user with the access token
String currentToken = (String) req.getSession().getAttribute("access_token");
String bearer = "Bearer " + currentToken.toString();
infohttpGet.setHeader("Authorization", bearer);
try {
HttpResponse response = infohttpclient.execute(infohttpGet); // execute httpGet
StatusLine statusLine = response.getStatusLine();
int statusCode = statusLine.getStatusCode();
if (statusCode == HttpStatus.SC_OK) {
System.out.println(statusLine);
infobody.append(statusLine + "\n");
HttpEntity e = response.getEntity();
String entity = EntityUtils.toString(e);
infobody.append(entity);
} else {
infobody.append(statusLine + "\n");
// System.out.println(statusLine);
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
tokeninfo = infobody.toString();
infohttpGet.releaseConnection(); // stop connection
}
// User info lookup is done fetching current log status of the token
if (tokeninfo.startsWith("HTTP/1.1 400 Bad Request")) {
tokeninfo = "Token " + currentToken + " was revoked";
};
String html_header = "<html><body>";
String myjson = "<br>Logoff completed successfully";
myjson += "<br>Current Userinfo and Token Status";
myjson += "<br>" + tokeninfo + "<br>";
myjson += "<br><br><b><a href='./index.html'>Back to login page</a></b><br>";
String html_footer = "</body></html>";
String mypage = html_header + myjson + html_footer;
resp.setContentType("text/html");
resp.getWriter().println(myjson);
// to print signoff screen for debug purpose
// resp.getWriter().println(outputl);
}
}
Above doc has been mentioned the way to revoke the access token.Access token revoking and sign-off from OAuth2 authorization server are two different process. As an example; in Facebook, you can revoke the access token which are given for different applications. But it does not mean that you are sign-off from FB or any other application which you already login.
OAuth2 is not an authentication mechanism. It is authorization framework. It does not contain standard way to sign-off from authorization sever. However, there is some custom way which you can use to sign-off (terminate the SSO session in WSO2IS) from WSO2IS which can be used. But, it must be done using the end user's browser (not using the back channel) by calling following url. Please check last part of this for more details
https://localhost:9443/commonauth?commonAuthLogout=true&type=oidc2&sessionDataKey=7fa50562-2d0f-4234-8e39-8a7271b9b273&commonAuthCallerPath=http://localhost:8080/openidconnect/oauth2client&relyingParty=OpenidConnectWebapp