Using Oltu to connect to Doorkeeper - ruby-on-rails

I'm attempting to authenticate against a rails app running as an OAuth2 provider running Doorkeeper.
I'm attempting to modify an example from the Oltu sources. The code that I have currently is:
public class OAuthClientTest {
public static void main(String[] args) throws OAuthSystemException, IOException {
String authUri = "http://smoke-track.herokuapp.com/oauth/authorize";
String callback = "http://localhost:8080";
String clientId = "728ad798943fff1afd90e79765e9534ef52a5b166cfd25f055d1c8ff6f3ae7fd";
String secret = "3728e0449052b616e2465c04d3cbd792f2d37e70ca64075708bfe8b53c28d529";
String tokenUri = "http://smoke-track.herokuapp.com/oauth/token";
try {
OAuthClientRequest request = OAuthClientRequest
.authorizationLocation(authUri)
.setClientId(clientId)
.setRedirectURI(callback)
.setResponseType("code")
.buildQueryMessage();
System.out.println("Visit: " + request.getLocationUri() + "\nand grant permission");
System.out.print("Now enter the OAuth code you have received in redirect uri ");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String code = br.readLine();
request = OAuthClientRequest
.tokenLocation(tokenUri)
.setGrantType(GrantType.AUTHORIZATION_CODE)
.setClientId(clientId)
.setClientSecret(secret)
.setRedirectURI(callback)
.setCode(code)
.buildBodyMessage();
OAuthClient oAuthClient = new OAuthClient(new URLConnectionClient());
//Facebook is not fully compatible with OAuth 2.0 draft 10, access token response is
//application/x-www-form-urlencoded, not json encoded so we use dedicated response class for that
//Own response class is an easy way to deal with oauth providers that introduce modifications to
//OAuth specification
GitHubTokenResponse oAuthResponse = oAuthClient.accessToken(request, GitHubTokenResponse.class);
System.out.println(
"Access Token: " + oAuthResponse.getAccessToken() + ", Expires in: " + oAuthResponse
.getExpiresIn());
} catch (OAuthProblemException e) {
System.out.println("OAuth error: " + e.getError());
System.out.println("OAuth error description: " + e.getDescription());
}
}
}
When I run this example with the original Facebook credentials, it takes me to a page that allows authentication. When I use my rails app, I get a url of the form:
http://smoke-track.herokuapp.com/oauth/authorize?response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A8080&client_id=728ad798943fff1afd90e79765e9534ef52a5b166cfd25f055d1c8ff6f3ae7fd
When I enter this in the browser I am forwarded to the redirect uri followed by:
?code=6d09201b18178ee7737fcdd330563143ef0b60855e9d06621dcec627a9c3f29a
When I enter the code at the prompt, I get the following errors:
OAuth error: invalid_request
OAuth error description: Missing parameters: access_token
I don't get that error when authenticating against Facebook. Any ideas as to what I am doing wrong?

you might try to use OAuthJSONAccessTokenResponse rather than GitHubTokenResponse

Related

Not able to get through webseal authentication using rest-assured

working on an automation assignment and i am trying to test a web service hosted on a webseal server. the issue is i have pretty my tried every method in rest assured to get to the response json but what i am getting is the authentication screen html.
here is some of my non working code. what i was expecting it the json but no matter what authentication method i run i get the webseal's authentication page only.
private String serviceTestGET(WebServiceTest serviceTest) {
System.out.println("Credential : " + userName + " -- " + password);
// RestAssured.
// RestAssured.authentication = basic(userName, password);
// RestAssured.authentication = digest(userId, password);
// RestAssured.authentication = oauth(consumerKey, consumerSecret,
// accessToken, secretToken);//form(userName, password);
// RestAssured.authentication = form(userId, password, config);
RestAssured.useRelaxedHTTPSValidation();
return given().get(serviceTest.getEntryPoint()).asString();
}
I have found the answer after googling a bit.
there are few things we have to consider that webseal is going to authenticate the request by throwing back a authentication form. once that form is authenticated its expected that you will use the same session(cookies) to access the application behind the webseal server.
so here is my working code
System.out.println("Credentials : " + username + " - " + password);
RestAssured.useRelaxedHTTPSValidation();
SessionFilter sessionFilter = new SessionFilter();
Map<String,String> cookies = given().
filter(sessionFilter).
param("username", username).
param("password", password).
param("login-form-type", "pwd").
expect().
statusCode(200).
when().
post("https://your-web-seal-server/pkmslogin.form").getCookies();
Reporter.log("Server Authenticated");
return given().filter(sessionFilter).cookies(cookies).expect().statusCode(200).
when().get(serviceTest.getEntryPoint()).asString();

Spring to Ping: how to configure Spring Rest Service to use External Authorization Server PingFederate

Does anyone know how to configure a Spring Rest Service to use PingFederate as an External Authorization Server?
Asked this question before, it was closed for god knows why. But here is the answer that I found. I based this on a demo that uses Google as an external authorization server. The problem with the usual demos is that they all use the Spring Authorization Server. Here is the place to start https://arnoldgalovics.com/google-oauth-with-spring-security-as-separated-resource-server/ Then modify the GoogleAccessTokenValidator like this (below). Questions, fire away...
private HttpHeaders createHeaders(final String username, final String password){
return new HttpHeaders() {{
String auth = username + ":" + password;
byte[] encodedAuth = Base64.encodeBase64(
auth.getBytes(Charset.forName("US-ASCII")) );
String authHeader = "Basic " + new String( encodedAuth );
set( "Authorization", authHeader );
}};
}
#SuppressWarnings("unchecked")
private Map<String, ?> getPingResponse(String accessToken) {
//Ping speaks text/html
List<HttpMessageConverter<?>> converters = restTemplate.getMessageConverters();
for (HttpMessageConverter<?> converter : converters) {
if (converter instanceof StringHttpMessageConverter) {
StringHttpMessageConverter stringConverter = (StringHttpMessageConverter) converter;
stringConverter.setSupportedMediaTypes(ImmutableList.of(new MediaType("text", "html", StringHttpMessageConverter.DEFAULT_CHARSET)));
}
}
//URL
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(checkTokenUrl)
.queryParam("grant_type", "urn:pingidentity.com:oauth2:grant_type:validate_bearer")
.queryParam("token", accessToken);
String url = builder.build().encode().toUri().toString();
//Basic Auth (from Ping, OAuth Settings, Manage Clients
HttpEntity<Object> requestEntity = new HttpEntity<Object>(createHeaders("my-trusted-client", "secret"));
//unused Spring exchange variables
Map<String, String> variables = ImmutableMap.of("ping does not", "use this"); //token only in queryParam above
//validation call to Ping
Map map = restTemplate.exchange(url, HttpMethod.POST, requestEntity, Map.class, variables).getBody();
return (Map<String, Object>) map;
}
I tried this using jose4j library
<dependency>
<groupId>org.bitbucket.b_c</groupId>
<artifactId>jose4j</artifactId>
<version>0.7.6</version>
</dependency>
Now, following is the code which validates the JWT and get claims.
String jwtToken = "<token>"
HttpsJwks httpsJkws = new HttpsJwks("<Ping Server Public cert URL>");
HttpsJwksVerificationKeyResolver httpsJwksKeyResolver = new HttpsJwksVerificationKeyResolver(httpsJkws);
JwtConsumer jwtConsumer = new JwtConsumerBuilder()
.setRequireExpirationTime()
.setAllowedClockSkewInSeconds(30)
.setRequireSubject()
.setExpectedIssuer("<Issuer URL>")
.setExpectedAudience("<audience>")
.setVerificationKeyResolver(httpsJwksKeyResolver)
.setJwsAlgorithmConstraints(
AlgorithmConstraints.ConstraintType.PERMIT, AlgorithmIdentifiers.RSA_USING_SHA256)
.build();
try
{
JwtClaims jwtClaims = jwtConsumer.processToClaims(jwtToken);
} catch (InvalidJwtException e) {
System.out.println("Invalid JWT! " + e);
if (e.hasExpired())
{
System.out.println("JWT expired at " + e.getJwtContext().getJwtClaims().getExpirationTime());
}
if (e.hasErrorCode(ErrorCodes.AUDIENCE_INVALID))
{
System.out.println("JWT had wrong audience: " + e.getJwtContext().getJwtClaims().getAudience());
}
}
We can integrate above code via SpringBoot interceptor by extracting the JWT token received in HTTP header.

Microsoft Graph API Authentication_MissingOrMalformed

I am using oauth2/token to authenticate my application and get the access_token. Bellow is the java code which is working fine.
private String getToken() throws Exception {
String access_token = "";
String url = "https://login.windows.net/MyApplication_ID_here/oauth2/token";
HttpClient client = HttpClients.createDefault();
HttpPost post = new HttpPost(url);
post.setHeader("Content-Type", "application/x-www-form-urlencoded");
List<NameValuePair> urlParameters = new ArrayList<NameValuePair>();
urlParameters.add(new BasicNameValuePair("grant_type", "client_credentials"));
urlParameters.add(new BasicNameValuePair("client_id", "MyApplication_ID_here"));
urlParameters.add(new BasicNameValuePair("client_secret", "MyApplication_secret_here"));
urlParameters.add(new BasicNameValuePair("resource", "https://graph.microsoft.com"));
post.setEntity(new UrlEncodedFormEntity(urlParameters));
HttpResponse response = client.execute(post);
System.out.println("Sending 'POST' request to URL : " + url);
System.out.println("Post parameters : " + post.getEntity());
System.out.println("Response Code : " + response.getStatusLine().getStatusCode());
String responseAsString = EntityUtils.toString(response.getEntity());
System.out.println(responseAsString);
try {
access_token = responseAsString.split(",")[6].split("\"")[3]; // get the access_token from response
} catch (Exception e) {
e.printStackTrace();
return null;
}
return access_token;
}
Response :
{"token_type":"Bearer","expires_in":"3599","ext_expires_in":"0","expires_on":"1493011626","not_before":"1493007726","resource":"https://graph.microsoft.com","access_token":"eyJ0e..."}
then I am using access_token to load the memberOf value which is not working and gives me the Access Token missing or malformed error. Bellow is the java code
private void getMemberOf()
{
HttpClient httpclient = HttpClients.createDefault();
try
{
URIBuilder builder = new URIBuilder("https://graph.windows.net/MyApplication_ID_here/users/test#testABC.onmicrosoft.com/memberOf?api-version=1.6");
URI uri = builder.build();
HttpGet request = new HttpGet(uri);
request.addHeader("Authorization", "Bearer " + access_token);
request.addHeader("Content-Type", "application/json");
HttpResponse response = httpclient.execute(request);
HttpEntity entity = response.getEntity();
System.out.println("Response Code : " + response.getStatusLine().getStatusCode());
if (entity != null) {
System.out.println(EntityUtils.toString(entity));
}
}
catch (Exception e)
{
e.getMessage();
}
}
Response :
Response Code : 401
{"odata.error":{"code":"Authentication_MissingOrMalformed","message":{"lang":"en","value":"Access Token missing or malformed."},"date":"2017-04-24T04:39:38","requestId":"c5aa2abe-9b37-4611-8db1-107e3ec08c14","values":null}}
Can someone please tell me which part of the above request is wrong? Am I not setting access_token correctly?
According to your code , your access token is for resource "https://graph.microsoft.com"(Microsoft Graph API) ,But the access token is used for "https://graph.windows.net"(AAD Graph API) :
URIBuilder builder = new URIBuilder("https://graph.windows.net/MyApplication_ID_here/users/test#testABC.onmicrosoft.com/memberOf?api-version=1.6");
If you want to call Azure AD graph api , you need to get access token for Azure AD Graph API .
I got this issue while performing the CRUD operation on Azure AD B2C service via AD Graph API for user management.
The idea is to get the access token for the resource "graph.windows.net" instead I was using my tenant App Id URI as it was suggested here.
*might help people who faced the same issue and landed up here

403 Response From Adobe Experience Manager OAuth 2 Token Endpoint

I am using Postman to test OAuth 2 from a vanilla AEM install.
Postman can successfully obtain the authorization code from /oauth/authorize after I grant access:
But when it tries to use the code to obtain a token from /oauth/token it receives the following response:
HTTP ERROR: 403 Problem accessing /oauth/token. Reason: Forbidden
Powered by Jetty://
Looking in Fiddler it is doing a POST to /oauth/token with the following Name/Values in the body:
client_id: Client ID from /libs/granite/oauth/content/client.html
client_secret:
Client Secret from /libs/granite/oauth/content/client.html
redirect_uri: https://www.getpostman.com/oauth2/callback
grant_type: authorization_code
code: Code returned from previous request to oauth/authorize
Am I missing something?
Would help if you can list some code snippets on how you are building the url and fetching the token.
Here's an example of how we've implemented very similar to what you are trying to do, maybe it'll help.
Define a service like below (snippet) and define the values (host, url, etc) in OSGI (or you can also hard code them for testing purposes)
#Service(value = OauthAuthentication.class)
#Component(immediate = true, label = "My Oauth Authentication", description = "My Oauth Authentication", policy = ConfigurationPolicy.REQUIRE, metatype = true)
#Properties({
#Property(name = Constants.SERVICE_VENDOR, value = "ABC"),
#Property(name = "service.oauth.host", value = "", label = "Oauth Host", description = "Oauth Athentication Server"),
#Property(name = "service.oauth.url", value = "/service/oauth/token", label = "Oauth URL", description = "Oauth Authentication URL relative to the host"),
#Property(name = "service.oauth.clientid", value = "", label = "Oauth Client ID", description = "Oauth client ID to use in the authentication procedure"),
#Property(name = "service.oauth.clientsecret", value = "", label = "Oauth Client Secret", description = "Oauth client secret to use in the authentication procedure"),
#Property(name = "service.oauth.granttype", value = "", label = "Oauth Grant Type", description = "Oauth grant type") })
public class OauthAuthentication {
...
#Activate
private void activate(ComponentContext context) {
Dictionary<String, Object> properties = context.getProperties();
host = OsgiUtil.toString(properties, PROPERTY_SERVICE_OAUTH_HOST,new String());
// Similarly get all values
url =
clientID =
clientSecret =
grantType =
authType = "Basic" + " "+ Base64.encode(new String(clientID + ":" + clientSecret));
}
public static void getAuthorizationToken(
try {
UserManager userManager = resourceResolver.adaptTo(UserManager.class);
Session session = resourceResolver.adaptTo(Session.class);
// Getting the current user
Authorizable auth = userManager.getAuthorizable(session.getUserID());
user = auth.getID();
password = ...
...
...
String serviceURL = (host.startsWith("http") ? "": protocol + "://") + host + url;
httpclient = HttpClients.custom().build();
HttpPost httppost = new HttpPost(serviceURL);
// set params
ArrayList<BasicNameValuePair> formparams = new ArrayList<BasicNameValuePair>();
formparams.add(new BasicNameValuePair("username", user));
formparams.add(new BasicNameValuePair("password", password));
formparams.add(new BasicNameValuePair("client_id", clientID));
formparams.add(new BasicNameValuePair("client_secret",clientSecret));
formparams.add(new BasicNameValuePair("grant_type",grantType));
UrlEncodedFormEntity postEntity = new UrlEncodedFormEntity(formparams, "UTF-8");
httppost.setEntity(postEntity);
// set header
httppost.addHeader("Authorization", authType);
response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
if (response.getStatusLine().getStatusCode() == 200) {
if (entity != null) {
object = new JSONObject(EntityUtils.toString(entity));
}
if (object != null) {
accessToken = object.getString("access_token");
////
}
}
}
I found the answer myself and thought I'd share the process I went through as well as the answer because it might help other people new to AEM.
How to find the cause of the error:
Go to CRXDE Lite.
Select console.
Then deselect the stop button to allow new console logs to appear (this is very counter-intuitive to me).
From here I was able to see the cause of the issue:
org.apache.sling.security.impl.ReferrerFilter Rejected empty referrer header for POST request to /oauth/token
Because postman does not place a referrer in the request header I had to tell Apache Sling to allow empty request headers.
To do this:
Go to /system/console/configMgr
Open the Apache Sling Referrer Filter Config
Select the Allow Empty check box
Good way to allow this to list the allowed hosts, otherwise this is against best practices for AEM security checklist.
Its fine for development environment not for production.

How to get access_token of Exact Online API using apache OAuth 2.0

We are trying to use Exact Online API. It is using Apache OAuth 2.0 framework. For that we followed the below document.
https://developers.exactonline.com/#OAuth_Tutorial.html%3FTocPath%3DAuthentication%7C_____2
I successfully able to get the authorization code but failing to get the access_token with exception like below.
OAuthProblemException{error='invalid_request', description='Missing parameters: access_token', uri='null', state='null', scope='null', redirectUri='null', responseStatus=0, parameters={}}
My code is like this.
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
PrintWriter out = response.getWriter();
try {
OAuthAuthzResponse oar = OAuthAuthzResponse.oauthCodeAuthzResponse(request);
String code = oar.getCode();
OAuthClientRequest oAuthrequest = OAuthClientRequest
.tokenLocation("https://start.exactonline.co.uk/api/oauth2/token")
.setGrantType(GrantType.AUTHORIZATION_CODE)
.setClientId("my client id")
.setClientSecret("my client secret")
.setRedirectURI("http://localhost:8080/SampleServlet/AuthServlet")
.setCode(code)
.buildBodyMessage();
OAuthClient oAuthClient = new OAuthClient(new URLConnectionClient());
GitHubTokenResponse oAuthResponse = oAuthClient.accessToken(oAuthrequest, "POST",GitHubTokenResponse.class);
out.println("Access Token = " + oAuthResponse.getAccessToken());
} catch (OAuthSystemException ex) {
Logger.getLogger(AuthServlet.class.getName()).log(Level.SEVERE, null, ex);
} catch (OAuthProblemException ex) {
Logger.getLogger(AuthServlet.class.getName()).log(Level.SEVERE, null, ex);
} finally {
out.close();
}
}
Can some one please help me to sort this out.
Finally i resolved this issue with a simple change. The problem is with the line
GitHubTokenResponse oAuthResponse = oAuthClient.accessToken(oAuthrequest, "POST",GitHubTokenResponse.class);
Instead of this we have to use either of the below lines to get the access token properly.
OAuthJSONAccessTokenResponse oAuthResponse = oAuthClient.accessToken(oAuthrequest, OAuth.HttpMethod.POST);
(Or)
OAuthAccessTokenResponse oAuthResponse =oAuthClient.accessToken(oAuthrequest,OAuth.HttpMethod.POST);

Resources