I am using SAML2 Bearer assertion profile to obtain OAuth Tokens form WSO2 API Manager. I have two client applications. In the OAuth Token Revoking process I am using following code,
public static boolean revokeToken(Token token) throws IOException {
//Create connection to the Token endpoint of API manger
URL url = new URL(Config.apiMangerOAuthRevokeURL);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
String userCredentials = Config.apiMangerClientID+":"+ Config.apiMangerClientSecret;
String basicAuth = "Basic " + new String(Base64.encodeBytes(userCredentials.getBytes()));
basicAuth = basicAuth.replaceAll("\\r|\\n", "");
// Set the consumer-key and Consumer-secret
connection.setRequestProperty("Authorization", basicAuth);
connection.setUseCaches(false);
connection.setDoInput(true);
connection.setDoOutput(true);
//Send request
DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
wr.writeBytes("token="+token.getAccess_token());
wr.flush();
wr.close();
//Get Response
InputStream iss = connection.getInputStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(iss));
String line;
StringBuffer responseString = new StringBuffer();
while ((line = rd.readLine()) != null) {
responseString.append(line);
responseString.append('\r');
}
rd.close();
System.out.println("Revoking Token Mobile-"+token.getAccess_token());
System.out.println("Revoking Response Mobile -"+responseString.toString());
return true
;
}
One client application do the revoking process OK. I tried to invoke API using CURL after revoking, it fails as expected. But the other client application which use same above logic to revoke tokens return well. But the token is valid after revoking. I can use CURL to query the API. What has gone wrong here?
API Manager has caching enabled by default and is set to 15 min. Try disabling it.
Related
My app first uses the Cognito LOGIN endpoint to obtain an Authorization Code. It then uses the TOKEN endpoint to try and obtain tokens (id_token, access_token, refresh_token) but that fails with unauthorized_client.
I do not understand why, the same client is used to access the LOGIN, and that succeeded in returning an authorization code. I'm following the documentation for the TOKEN endpoint
string clientId = ...
string clientSecret = ...
Uri redirectUri = new Uri("myapp://myhost");
string authorization_code = ... // obtained via HTTP GET on LOGIN endpoint
string accessTokenUrl = "https://<domain>.auth.<region>.amazoncognito.com/oauth2/token";
var queryValues = new Dictionary<string, string>
{
{ "grant_type", "authorization_code" },
{ "code", authorization_code },
{ "redirect_uri", redirectUri.AbsoluteUri },
{ "client_id", clientId},
};
using (HttpClient client = new HttpClient())
{
// Authorization Basic header with Base64Encoded (clientId::clientSecret)
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
"Basic",
Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(
string.Format("{0}:{1}",
clientId,
clientSecret))));
// Url Encoded Content
var content = new FormUrlEncodedContent(queryValues);
// HTTPS POST
HttpResponseMessage response = await client.PostAsync(accessTokenUrl, content).ConfigureAwait(false);
string text = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
// test = {"error" : "unauthorized_client"}
}
The problem is two-fold:
1- System.Uri.AbsoluteUri adds a trailing / in the returned string so that my redirectUri becomes myapp://myhost/ instead of myapp://myhost
2- AWS Cognito TOKEN endpoint does not accept trailing / in a redirectURI.
The solution:
I now call redirectUri.OriginalUri instead of redirectUri.AbsoluteUri where I build the query to preserve the redirectUri as it was when I built it.
(I don't really have control over this since in my case Xamarin.Auth.OAuthAuthenticator2 calls Uri.AbsoluteUri on my behalf and transforms the redirectUri string I gave it, so I'm going to have to fix Xamarin.Auth).
I have a BE Java Service, which is RESTFul, which is ported on WSO2 API Manager. It is published and available in Store. I have registered a new Application (by Name ' Java App ') and upon subscribing to that API, it provided me with Client Key and Client Secret along with Token. Using the Token I am able to successfully access the API (from SOAP UI). My requirement is to access the API from a standalone Java Application. Can someone direct me or provide appropriate code that can access the published API.
Regards, Sreedhar.
You can use Apache HTTP client to invoke the API by sending Authorization as a HTTP Header.
String url = "API_URL";
HttpClient client = HttpClientBuilder.create().build();
HttpGet request = new HttpGet(url);
// add Authorization Header header
request.addHeader("Authorization", "Bearer :" + accessToken);
HttpResponse response = client.execute(request);
System.out.println("Response Code : "
+ response.getStatusLine().getStatusCode());
BufferedReader rd = new BufferedReader(
new InputStreamReader(response.getEntity().getContent()));
StringBuffer result = new StringBuffer();
String line = "";
while ((line = rd.readLine()) != null) {
result.append(line);
}
For Generating Token with username, password and Client Key / Secret, You can use following cURL sample to build the HTTP request. More information can be found in token api
curl -k -d "grant_type=password&username=<username>&password=<password>" -H "Authorization: Basic SVpzSWk2SERiQjVlOFZLZFpBblVpX2ZaM2Y4YTpHbTBiSjZvV1Y4ZkM1T1FMTGxDNmpzbEFDVzhh" -H "Content-Type: application/x-www-form-urlencoded" https://localhost:8243/token
You have to base 64 encode Client Key / Secret and send it with Authorization header as Basic.
I am using WSO2-AM-1.9.0, trying to generate the Access token using Consumer Key and Consumer Secrete.
When making a call using CURL it works fine
curl -k -d "grant_type=password&username=testuser1&password=testUser1&scope=SANDBOX" -H "Content-Type:application/x-www-form-urlencoded" -H "Authorization:Basic ZXNuaHJTZmJmOW9XS28xTVM5UHJSZ1BacUU0YTpld040RGh1ZmsxYTNZbndVNU1uMVlGM3IwanNh" http://10.0.100.108:8280/token
But when trying with Java it returns 403 error code. Code is:
try
{
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet("http://10.0.100.108:8280/token");
HttpParams params=new BasicHttpParams();
get.addHeader("Authorization","Basic ZXNuaHJTZmJmOW9XS28xTVM5UHJSZ1BacUU0YTpld040RGh1ZmsxYTNZbndVNU1uMVlGM3IwanNh");
get.addHeader("content-type", "application/x-www-form-urlencoded");
params.setParameter("grant_type", "password");
params.setParameter("username", "testuser1");
params.setParameter("password", "testUser1");
params.setParameter("scope", "SANDBOX");
get.setParams(params);
HttpResponse response = client.execute(get);
BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
String line = "";
while ((line = rd.readLine()) != null) {
responseBody = responseBody +"\n"+line;
}
}
catch(Exception ex)
{
ex.printStackTrace();
}
Error:
403 Status report
Runtime Error No matching resource found in the API for the given request
Any help and info on this is appreciated.
You have to send a POST request not a GET. Use,
HttpPost httpPost = new HttpPost("http://10.0.100.108:8280/token");
I am new to web based solutions. I am hitting a rest url using RestSharp library.
My code is as follows:
var cleint = new RestClient("http://REST_URL");
cleint.Authenticator = new HttpBasicAuthenticator("username", "password");
var request = new RestRequest();
request.Method = Method.GET;
request.Resource = "0.json";
IRestResponse response = cleint.Execute(request);
if (response != null && ((response.StatusCode == HttpStatusCode.OK) &&
(response.ResponseStatus == ResponseStatus.Completed)))
{
// var arr = JsonConvert.DeserializeObject<JArray> (response.Content);
}
The url returns a json file, when I hit it manually. But I want to use a C# console application to get the json file and save it to the disk. I am getting an unauthorized response when I run the above mentioned code:
response.ResponseStatus= "Unauthorized"
This is all it needed..
client.Authenticator = new NtlmAuthenticator();
So if your IIS settings have Windows Authentication set as enabled, this is what you are going to need, Http Basic authentication is not enough to by pass the server security
I have a Custom SharePoint webservice for performing certain actions. User credentials are passed via Soap Header. The credentials reach the webservice without any problem.
Issue:
The following code returns "Unauthorized Error" if I did not make the webservice call with user credentials.
WebService Method
[WebMethod(Description = "Test Credentials")]
[SoapDocumentMethod(Binding = "SPService")]
[SoapHeader("Authen")]
public string[] TestCredentials(string siteURL)
{
string[] credentials = new string[3];
using (SPSite site = new SPSite(siteURL))
{
using (SPWeb spW = site.OpenWeb())
{
credentials[0] = Authen.CallingUserName;
credentials[1] = Authen.CallingUserPwd;
credentials[2] = siteURL;
}
}
return credentials;
}
Client Code
SPService.SPService spS = new SPService.SPService();//Webservice class
SPService.UserAuth ua = new SPService.UserAuth(); //Soap Header class
ua.CallingUserName = UserName; // User name
ua.CallingUserPwd = Password; // Password for the Username
spS.UserAuthValue = ua; // assigning the credential to the SoapHeader.
//System.Net.NetworkCredential nc = new NetworkCredential(UName, pwd, Domain);
//spS.Credentials = new NetworkCredential(UName, pwd, Domain);
string[] str = new string[3];
str = spS.TestCredentials(txt_URL.Text,"Shared Documents");
When the Network credential is commented out I get the The request failed with HTTP status 401: Unauthorized. error. If the credential is used then the webservice returns the expected value.
Requirement of the Custom WebService is to use WS-Security to pass the Login credentials and use the same to login into the SharePoint site.
Some help would be useful. Kindly let me know if you need more detail regarding this.
The SPSite constructor will require authentication to intialise correctly as it is accessing Sharepoint. You can instantiate it using credentials you have constructed before hand in a similar manner to what is described here