I've got an apiKey in my swagger definition:
securityDefinition = #SecurityDefinition(
apiKeyAuthDefinitions = {#ApiKeyAuthDefinition(
key= "test",
in = ApiKeyAuthDefinition.ApiKeyLocation.HEADER,
name = "X-AUTH-TOKEN",
description = "LHT-AM API KEY"
)}
)
So SwaggerUI correctly offers authorization.
But how can i tell SwaggerUI to fill this authorization automatically from header?
Related
JWT process is to sign JWT and use JWT to retrieve an access token. This access token is used to call Google APIs.
We use Google auth library to sign JWT. IS this signing process container locally or does it require internet access to another service to sign the JWT?
In order to see the flow for retrieving the access token using the service account, for example, when it sees the script for retrieving the access token using Javascript, the value of jwt can be created without the web access. But, when the access token is retrieved using the jwt, it is required to access the endpoint of Google like https://www.googleapis.com/oauth2/v4/token. Ref
The script for retrieving the access token using the service account is as follows.
const private_key = "###"; // private_key of JSON file retrieved by creating Service Account
const client_email = "###"; // client_email of JSON file retrieved by creating Service Account
const scopes = ["https://www.googleapis.com/auth/drive.readonly"]; // Scopes
const url = "https://www.googleapis.com/oauth2/v4/token";
const header = { alg: "RS256", typ: "JWT" };
const now = Math.floor(Date.now() / 1000);
const claim = {
iss: client_email,
scope: scopes.join(" "),
aud: url,
exp: (now + 3600).toString(),
iat: now.toString(),
};
const signature = btoa(JSON.stringify(header)) + "." + btoa(JSON.stringify(claim));
const sign = new JSEncrypt();
sign.setPrivateKey(private_key);
const jwt = signature + "." + sign.sign(signature, CryptoJS.SHA256, "sha256");
const params = {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
assertion: jwt,
grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer",
}),
};
const obj = await fetch(url, params).then((res) => res.json()).catch((err) => console.log(err));
console.log(obj);
Referencs:
Using OAuth 2.0 for Server to Server Applications
GetAccessTokenFromServiceAccount_js
Is there any annotation based Swagger Documentation creator available for Vert.x yet ? The rest end points are all managed using routers and as such if there is any way available to generate the Swagger documentation, that would be great.
I've gone through the Java Jersey based documentation creator using various annotations, but couldn't find anything for the Vert.x documentation. The official swagger wiki on Git Hub also doesn't house any document related to Vert.x documentations.
Since this question was asked Swagger has been named OpenAPI and Vert.x offers the Web API Contract module. Using this anupsaund created the vertx-auto-swagger repo (in turn based on vertx-openapi-spec-generator). It does:
Read Java Annotations and map them into a openAPI spec.
Serve the openAPI spec out on an end point.
Serve a distributable version of SwaggerUI which presents the swagger spec from point 2.
Which then allows annotations as follows:
#Operation(summary = "Find products by ID", method = "GET", operationId = "product/:productId",
tags = {
"Product"
},
parameters = {
#Parameter(in = ParameterIn.PATH, name = "productId",
required = true, description = "The unique ID belonging to the product", schema = #Schema(type = "string"))
},
responses = {
#ApiResponse(responseCode = "200", description = "OK",
content = #Content(
mediaType = "application/json",
encoding = #Encoding(contentType = "application/json"),
schema = #Schema(name = "product", example =
"{" +
"'_id':'abc'," +
"'title':'Red Truck'," +
"'image_url':'https://images.pexels.com/photos/1112597/pexels-photo-1112597.jpeg'," +
"'from_date':'2018-08-30'," +
"'to_date':'2019-08-30'," +
"'price':'125.00'," +
"'enabled':true" +
"}",
implementation = Product.class)
)
),
#ApiResponse(responseCode = "404", description = "Not found."),
#ApiResponse(responseCode = "500", description = "Internal Server Error.")
}
)
The ASP.NET Security Social Sample has two ways to interact with Google.
UseOAuthAuthentication
app.UseOAuthAuthentication(new OAuthOptions
{
AuthenticationScheme = "Google-AccessToken",
DisplayName = "Google-AccessToken",
ClientId = Configuration["google:clientid"],
ClientSecret = Configuration["google:clientsecret"],
CallbackPath = new PathString("/signin-google-token"),
AuthorizationEndpoint = GoogleDefaults.AuthorizationEndpoint,
TokenEndpoint = GoogleDefaults.TokenEndpoint,
Scope = { "openid", "profile", "email" },
SaveTokens = true
});
UseGoogleAuthentication
app.UseGoogleAuthentication(new GoogleOptions
{
ClientId = Configuration["google:clientid"],
ClientSecret = Configuration["google:clientsecret"],
SaveTokens = true,
Events = new OAuthEvents()
{
OnRemoteFailure = ctx =>
{
ctx.Response.Redirect("/error?FailureMessage="
+ UrlEncoder.Default.Encode(ctx.Failure.Message));
ctx.HandleResponse();
return Task.FromResult(0);
}
}
});
What is the standard name for these two types of authentication and authorization? I.e. is one OAuth and the other OpenID Connect?
When choosing to UseOAuthAuthentication, this is the result.
context
.User.Claims: []
.User.Identity.Name: null
.Authentication.GetTokenAsync("access_token"): ya29.CjAlAz3AcUnRD...
.Authentication.GetTokenAsync("refresh_token"): null
.Authentication.GetTokenAsync("token_type"): Bearer
.Authentication.GetTokenAsync("expires_at"): 2016-07-19T22:49:54...
When choosing to UseGoogleAuthentication, this is the result.
context
.User.Claims: [
nameidentifier: 10424487944...
givenname: Shaun
surname: Luttin
name: Shaun Luttin
emailaddress: admin#shaunl...
profile: https://plus.google.com/+ShaunLuttin
]
.User.Identity.Name: "Shaun Luttin"
.Authentication.GetTokenAsync("access_token"): ya29.CjAlAz3AcUnRD...
.Authentication.GetTokenAsync("refresh_token"): null
.Authentication.GetTokenAsync("token_type"): Bearer
.Authentication.GetTokenAsync("expires_at"): 2016-07-19T22:49:54...
Both UseOAuthAuthentication and UseGoogleAuthentication are OAuth. The difference is that the Google middleware sets some default OAuth options that are specific to Google and adds a GoogleHandler that gets the user profile information.
In other words,
UseOAuthAuthentication is OAuth that retrieves and access token.
UseGoogleAuthentication is OAuth with its options and flow tuned to retrieve an access code and user profile information from Google.
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.
I just "upgraded" to 6.1.0 of the c# SDK and found that the FacebookAuthClient has been removed. I checked the commit log on github and there's not much info there.
Does anyone know how you are supposed to authenticate with the latest version of the SDK?
It has been removed.
Starting with v6 you can now use it with normal FacebookClient.Get() method. http://csharpsdk.org/docs/faq.html
How do I get a Facebook Application Access Token?
var fb = new FacebookClient();
dynamic result = fb.Get("oauth/access_token", new {
client_id = "app_id",
client_secret = "app_secret",
grant_type = "client_credentials"
});
How do I exchange code for access token?
var fb = new FacebookClient();
dynamic result = fb.Get("oauth/access_token", new {
client_id = "app_id",
client_secret = "app_secret",
redirect_uri = "http://yoururl.com/callback",
code = "code"
});
How do I extend the expiry time of the access token?
var fb = new FacebookClient();
dynamic result = fb.Get("oauth/access_token", new {
client_id = "app_id",
client_secret = "app_secret",
grant_type = "fb_exchange_token",
fb_exchange_token = "EXISTING_ACCESS_TOKEN"
});