I am currently using Google management API for analytics v2.4, but the way i do the authentication is deprecated (function setUserCredentials), so I need to migrate to OAuth2.0 authentication, but I am having some problems to understand google documentation, about it.
DataQuery query = new DataQuery(new URL(DATA_URL));
query.setIds(tableId);
query.setStartDate(startDate);
query.setEndDate(endDate);
query.setDimensions(dimensions);
query.setMetrics(metrics);
query.setMaxResults(10000);
query.setStringCustomParameter("key", "API_key");
return query;
}
private static DataFeed getDataFeed(String username, String password, String startDate, String endDate, String dimensions, String metrics) throws ServiceException, IOException {
AnalyticsService myService = new AnalyticsService("xxxxxx");
myService.setUserCredentials(username, password);
DataQuery query = getQuery(GA_ID, startDate, endDate, dimensions, metrics, 1);
DataFeed data = null;
try{
data = myService.getFeed(query, DataFeed.class);
}catch(Exception e){
e.printStackTrace();
}
return data;
}
Can I still use the v2.4 and do the authentication with OAuth2.0 ?
I'm sorry to say that the v2.4 API is also deprecated. If it isn't already shutdown it might be without warning.
If you already have rewrite your code because of the auth issue, you should upgrade to Analytics Reporting API v4 and Analytics Management API v3. See the quick start
guides.
Related
I'm transitioning for Spring to Quarkus and wanted to try to code a simple login/register backend. The registration part works perfectly, but I have no clue how I can manually log in the user. Using spring I just used to have an endpoint that received the username and the password:
public void login(HttpServletRequest req, String user, String pass) {
var authReq = new UsernamePasswordAuthenticationToken(user, pass);
var auth = authManager.authenticate(authReq);
var sc = SecurityContextHolder.getContext();
sc.setAuthentication(auth);
var session = req.getSession(true);
session.setAttribute(SPRING_SECURITY_CONTEXT_KEY, sc);
}
But with Quarkus there doesn't seem to be a way to do that. What am I supposed to do? What I have so far:
new AuthenticationBuilder().addUsername(username).addPassword(password).build().digest(AuthenticationDigest.forRepository());
But I have no clue how to continue
As far as I know, there is no implementation of session-based authentication (SBA) in Quarkus. In the official security documentation of the framework there are no references to SBA.
I have this very basic authentication for my app:
MapVerifier mapVerifier = new MapVerifier();
mapVerifier.getLocalSecrets().put("user", "pass".toCharArray());
ChallengeAuthenticator guard= new ChallengeAuthenticator(null, ChallengeScheme.HTTP_BASIC, "Secured Resources");
guard.setContext(getContext());
guard.setVerifier(mapVerifier);
How do I adapt this to use Google authentication scheme? That, instead of showing the Username/Password browser popup, it will go to the Google authentication page.
I think that you aren't in the context of a challenge authentication and you need to leverage the authentication service of Google.
Here is an implementation of this approach (not tested) if you want a custom Restlet Authenticator implementation:
public class GoogleAuthenticator extends Authenticator {
private UserService userService;
public GoogleAuthenticator(Context context) {
super(context);
this.userService = UserServiceFactory.getUserService();
}
protected User createUser(com.google.appengine.api.users.User googleUser,
Request request, Response response) {
return new User(googleUser.getUserId());
}
protected boolean authenticate(Request request, Response response) {
// Get current Google user
com.google.appengine.api.users.User googleUser = userService.getCurrentUser();
// Check if the user is authenticated
if (googleUser!=null) {
// Authenticated through Google authentication service
request.getClientInfo().setUser(
createUser(googleUser, request, response));
return true;
} else {
// Not authenticated. Redirect to the login URL
response.redirectSeeOther(userService.createLoginURL(
request.getRequestURI()));
return false;
}
}
}
However such authenticator exists in the extension org.restlet.ext.gae for a while. It leverages the service UserService of GAE. So I think that you have it with the version of Restlet you use. Here is a sample of use below:
public Restlet createInboundRoot() {
Router router = new Router(getContext());
(...)
GaeAuthenticator guard= new GaeAuthenticator(getContext());
guard.setNext(router);
return guard;
}
Edited:
You can notice that the GAE authenticator can use the GAE enroler for this purpose (i.e. if it's an admin one).
To implement this, you simply need to instantiate such enroler and set it on your authenticator, as desribed below:
GaeEnroler enroler = new GaeEnroler();
GaeAuthenticator guard = new GaeAuthenticator(getContext());
guard.setEnroler(enroler)
guard.setNext(router);
Within your server resource, you can then check the role, as described below:
protected boolean hasAdminRole() {
ClientInfo clientInfo = getClientInfo();
List<Role> roles = clientInfo.getRoles();
boolean isAdmin = false;
for (Role role : roles) {
if (role.getName().equals("admin")) {
isAdmin = true;
break;
}
}
return isAdmin;
}
#Post
public XX handlePost(YY content) {
if (!hasAdminRole()) {
throw new ResourceException(Status.CLIENT_ERROR_FORBIDDEN);
}
(...)
}
Hope it helps you,
Thierry
I haven't fully understood what's ur question is ? If u wanted to integrate Google authentication in yours system check the link
google Oauth2
It's not depend upon any framework it's simply redirection and callback which u can do with plain servlets , obviously you can do with restlets too
I have written an simply library to integrate google and Facebook oauth 2, you can check this to see how it works
java oauth2 gae
I am using a (little modified) workaround from this course, to fetch the userId, which is null if the request was sent from an Android client.
/**
* This is an ugly workaround for null userId for Android clients.
*
* #param user A User object injected by the cloud endpoints.
* #return the App Engine userId for the user.
*/
private static String getUserId(User user) {
String userId = user.getUserId();
if (userId == null) {
LOG.info("userId is null, so trying to obtain it from the datastore.");
AppEngineUser appEngineUser = new AppEngineUser(user);
ofy().save().entity(appEngineUser).now();
AppEngineUser savedUser = ofy().load().key(appEngineUser.getKey()).now();
userId = savedUser.getUser().getUserId();
LOG.info("Obtained the userId: " + userId);
}
return userId;
}
Although I am not able to get the userId.
INFO: Obtained the userId: null
This workaround has already worked perfectly in other projects, so the problem must be elsewhere. My endpoints api is annotated with the following scopes, clientIds and audiences:
scopes = {
Constants.EMAIL_SCOPE
},
clientIds = {
Constants.API_EXPLORER_CLIENT_ID,
Constants.WEB_CLIENT_ID,
Constants.ANDROID_CLIENT_ID
},
audiences = {
Constants.ANDROID_AUDIENCE
}
Constants.ANDROID_AUDIENCE and Constants.WEB_CLIENT_ID are the same. I am not using a web client, but Google told me to add a web client id. Does this client id need to have redirect uris and javascript origins specified?
In my Android client I am using the following to specify the audience.
mCredential = GoogleAccountCredential.usingAudience(
EndpointService.this,
"server:client_id:IDIDIDID.apps.googleusercontent.com"
);
Please help me to figure this one out.
I just understood why this workaround works. I need to begin a new objectify session so the cache is not used and the userId can be populated.
Objectify objectify = ofy().factory().begin();
AppEngineUser savedUser = objectify.load();
I have a set of RESTful web services built on DropWizard. Currently I am using BasicAuth to authenticate the users to use the API .
That involves an overhead of having another DB with user/password details. I was looking about token based authentication and found that DropWizard supports Oauth2 out of the box.
Can anyone help me with a sample implementation of this Oauth2 based authentication ? And what would be the architecture to implement so ?
Any help would be appreciated.
This question has been around for a while, but for future visitors I place an article here which explains how to do it with custom annotations very well:
Implement secure API authentication over HTTP with Dropwizard on Automation Rhapsody
Basically the idea is to implement our own annotations with our own logic (which in this case is using JWT), but the post also points out what custom settings are reqired for Dropwizard.
Even though this question is four years old I wasn't able to find a fully working example of an application that plugs into dropwizard Oauth2 library with your own validation mechanism.
So for the benefit of people who stumble upon this post from google search in future, here is a full working example running on latest dropwizard version 1.3.8
Good luck!
There is an example of OAuth2 authentication in Dropwizard GitHub repo.
Below there is an example for latest version of Dropwizard (v0.7.1):
...
public OAuthFactory(final Authenticator<String, T> authenticator,
final String realm,
final Class<T> generatedClass) {
super(authenticator);
this.required = false;
this.realm = realm;
this.generatedClass = generatedClass;
}
private OAuthFactory(final boolean required,
final Authenticator<String, T> authenticator,
final String realm,
final Class<T> generatedClass) {
super(authenticator);
this.required = required;
this.realm = realm;
this.generatedClass = generatedClass;
}
#Override
public AuthFactory<String, T> clone(boolean required) {
return new OAuthFactory<>(required, authenticator(), this.realm, this.generatedClass);
}
public T provide() {
try {
final String header = request.getHeader(HttpHeaders.AUTHORIZATION);
if (header != null) {
final int space = header.indexOf(' ');
if (space > 0) {
final String method = header.substring(0, space);
if (PREFIX.equalsIgnoreCase(method)) {
final String credentials = header.substring(space + 1);
final Optional<T> result = authenticator().authenticate(credentials);
if (result.isPresent()) {
return result.get();
}
}
}
}
} catch (AuthenticationException e) {
LOGGER.warn("Error authenticating credentials", e);
throw new InternalServerErrorException();
}
if (required) {
throw new WebApplicationException(Response.status(Response.Status.UNAUTHORIZED)
.header(HttpHeaders.WWW_AUTHENTICATE, String.format(CHALLENGE_FORMAT, realm))
.type(MediaType.TEXT_PLAIN_TYPE)
.entity("Credentials are required to access this resource.")
.build());
}
return null;
}
#Override
public Class<T> getGeneratedClass() {
return generatedClass;
}
...
Complete code, here!
I'm facing an issue in socialAuth java library. I used that library for logging to my app by using social networks. Login with Facebook is working properly. But when i try to use google and yahoo is does not work for me. Error occur when after authentication process, redirection part is not working properly,
#SuppressWarnings("unused")
#RequestMapping(params = "code")
private String oauth2Callback(final HttpServletRequest request,
HttpServletResponse response,
Model model) throws Exception {
String serviceReturnUrl = request.getParameter("service");
String clientAppKey = request.getParameter("app_key");
org.brickred.socialauth.AuthProvider provider = null;
SocialAuthManager manager = socialAuthTemplate.getSocialAuthManager();
if (manager != null) {
try {
provider = manager.connect(SocialAuthUtil.getRequestParametersMap(request));
} catch (Exception e) {
e.printStackTrace();
}
} else {
response.sendRedirect(appLoadConfigurer.getProperty("caslk"));
return "";
}
When redirecting Facebook to my app this method catch the request. but when it comes to google, i could not catch the request from google by using this method. request is not comes to here. Any one can idea to fix my issue as soon as possible
For google you will have to use
#RequestMapping(params = "openid.claimed_id")
Because google doen't return any attribute with name 'code' that's why it is not matching with this.