making authenticated api calls from gaej - java

I want to access google AuditService api from google app engine application.user is already logged in to my app using UserService via google credentials.
Is there a way I can make authenticated calls without the need of user re authenticating my app.
AuditService service = new AuditService("userEmail", "password", "domain name", "application name");
in the above call I don't have userEmail and password,but I have the user object which I got using UserService ,when user first logged in to my application.Any way to use this user object to make authenticated calls ?

It looks like you can do this by storing and providing an authentication token instead of the user's credentials. On the first request, proceed with the username/password authentication as normal, then generate an authorization token using service.getAuthToken(...). Store that token with your user model. For subsequent requests, instead of using the AuditService constructor that takes the user's credentials, use the one that omits them: AuditService(domain, applicationName). Once constructed, call service.setUserToken(token) to provide the stored token. You should then be able to make authenticated requests. Be sure to handle AuthenticationExceptions that will be raised by invalid/expired tokens.

Related

Spring Boot: What is the Right Way to Implement Basic Auth with httpheaders

I am consuming a secured Restful Service that grants access through Basic Auth (Username and Password). I have successfully accessed the API service and consumed its API; however, I am still confused as to what is the right way to implement HTTP headers with Basic Auth. I would assume I should authenticate only once, but the way I have constructed my code, it looks like I need to authenticate API with each service method I create.
Should I create a helper method with the authentication and call it on each service?
If you are using Basic Auth you need to always include credentials with your request. In case of OAuth, tokens have expiry. In this case, a token caching mechanism for the duration of a little bit less than the expiration duration would do the trick.
The Basic Auth is a kind of no status authentication. That means the server wouldn't record. Every time you need to provide username and password with your request. Each request is equal to the Server.
For another authentication called OAuth, the first time you request with username and password, the server will return a token to the frontend, which has an expiration period. So, you request every time with the token through the filter, where checks the expiry of the token. If it's not expired, using the same token for requests, otherwise, making a request to get another token.

Custom Authentication without username/password

I'm developing a web application (Back end : JAVA/ stateless REST API) (Front end : Angular) which eventually be placed inside another web application.(let's say parent app).
The parent app which is session based handles authentication by username/password and create token for each user. Once a user is able to login the parent application he or she should also able to access my application. It is good to mention the token can also be used to retrieve user data by a SOAP call from my application.
My idea is to get this token with my front end component and send it to my REST Api. I'm going to keep those tokens inside a concurrent hash map and for each call coming from FE I'll check the token on BE for authorization. I wonder if it is a correct approach?
When the parent app's session expires or the user logs out is the token invalidated?
If yes, how does your app know the token was invalidated? Is that the check the token on the BE? (which would need to be done for every request)
If a shared session is not an option then your approach is reasonable.
Also, for security the REST calls should always be HTTPS (refuse the request if not), and consider passing the token in a header instead of on the URL as a query parameter.

Spring Security: Different authentication methods depending on entity

first post here, hope im doing right.
In a project, we have a scenario where we have a single web application with multiple entities. Currently, the login is managed via default JDBC Spring Security provider, working fine.
For a new requirement, we need that each entity can have their own login method (currently 2 methods would be available, the JDBC one, which is the current one, and the second method would be authentication via SAML, with each entity defining their own IdP, but this is another story)
I need some guidelines on how this can be achieved, I have done some search and I have found providers for different URL's, etc... But not different login methods for the same app and url's depending on the user type or entity.
Is a good approach to have a custom single entry point where we can check the entity user and then use the suitable authentication provider?
Kind regards,
Alex
As each of your users might be using a different IDP you will in any case need to determine the username before proceeding with initialization of the authentication process - but you already know this.
One approach to take (similar to what Microsoft is using with the Office 365 for corporate users) is:
display a login page with fields for standard username + password
once user enters username and blurs the input field, you make an AJAX call (to your custom API made for this purpose) and fetch information about authentication type + IDP to use for this user
in case the type is password you simply let user continue with filling in the password field and POST to the same place as you're used to for processing with the JDBC provider
in case the type is federated authentication you initialize authentication with the correct IDP by redirecting to /saml/login?idp=xyz and continue with the SAML flow
It's possible to avoid any APIs by submitting the form once user enters the username, or let user click a "Continue" button. It would then make sense to use a custom EntryPoint which:
redirects user to the main login page in case it wasn't provided with a username
displays either login page with username/password or redirects to the correct IDP, once username was provided

User Authorization for Cloud Endpoints

I'm working on a cloud endpoints backend and want to restrict certain operations to admin users.
My current code works like this:
#ApiMethod(httpMethod = "PATCH", name = "item.update", path = "items")
public Item update(Item newObject, User user)
throws UnauthorizedException, OAuthRequestException {
OAuthService oAuthService = OAuthServiceFactory.getOAuthService();
if (!oAuthService.isUserAdmin()) {
throw new UnauthorizedException("Only admin users can modify content.");
}
...
}
I know app engine has a concept of user roles, but I'm curious if Endpoints
do. I've tried using the OAuthService.isUserAdmin() call but that doesn't
seem to be working out very well and the docs have a big old warning saying
Note: You should not confuse Endpoints auth with the auth for
non-Endpoints App Engine web apps described in the article on configuration settings
https://developers.google.com/appengine/articles/auth in the Admin
Console, where you also specify the user login requirement in your
web.xmlhttps://developers.google.com/appengine/docs/java/config/webxml#Security_and_Authentication
file. That approach is not used with Endpoints."
Do I have to create some sort of authorization myself that uses the User object that's passed into the update method? Any thoughts?
I had similar issues. Indeed OAuth user service has nothing to do with AppEngine user service. What I ended up doing was having a dedicated user type entity in my datastore where I store a specific flag (regular/admin) for each user. This flag is updated when I use AppEngine user service (i.e. so that the administrators I specified in the console get the proper admin flag).
In my endpoints API I get the current user authDomain and id, look up in my datastore to check whether it has the admin flag. The key of my user entity is composed of "authDomain:userId" and as I only support google user for now, it looks like (gmail.com:123456789)
This means that an administrator has to login once using the AppEngine UserService (i.e. a dedicated webpage in my case) so that the flag is properly updated
I needed to do the same thing and validate some endpoint to grant access only to admin members listed in the project console and used the same implementation presented above, but the oAuthService.isUserAdmin() accept one or more string parameters, this parameters are scopes that you specify and the Oauth uses to get user informations, in my case i just set this parameter and it works like the code bellow.
OAuthService authService = OAuthServiceFactory.getOAuthService();
User user;
try {
com.google.appengine.api.users.User currentUser =
authService.getCurrentUser(Constants.EMAIL_SCOPE);
if (currentUser != null && authService.isUserAdmin(Constants.EMAIL_SCOPE)) {
user = new User(currentUser.getEmail());
return user;
}
...
The EMAIL_SCOPE constant is defined by
public static final String EMAIL_SCOPE = "https://www.googleapis.com/auth/userinfo.email";
In my case i implemented an authenticator, to pass user information to endpoint only if it's admin user, you can read more about the authenticators if you want.
https://cloud.google.com/appengine/docs/java/endpoints/javadoc/com/google/api/server/spi/config/Authenticator

How to add a role filter on request combined with OAuth

I would like to develop a portal which contains some modules
The portal and each module consume data provided by a webservice based on Jersey and secured with OAuth 1.0
For the moment I have almost implement the OAuth provider
A user can connect to the portal and access to a module
Each app or module has a specific access token to consume resource
What I want to do is to add a role implementation
For example for the module1, the user can have 2 roles (role1 and role2) but can't use the 2 roles in parallel
First the user uses the access (module1 / user1 / role1) and he will have a token and later the user uses the access (module1 / user1 / role2) and he will have an other token
Depending on the role, I would like to filter the request with a RolesAllowed annotation for example
I have read this article: http://objecthunter.congrace.de/tinybo/blog/articles/89
When the user is authenticated to the web service I could persist in a database the username, and the role used for the module and the RolesAllowedResourceFilterFactory could use the realm to check if the user is in the role and can access to the resource
But can I by-passed the auth method?
Anyway I really need your help to implement this role filter thing
I will try to give you more details if you need
Thanks
The Jersey oauth filter sets the security context based on what access token was used. You just have to make sure your custom implementation of the oauth provider assigns a token with the right return values from the isInRole() method when called with various roles. The role for a given token can be established during the token authorization flow (e.g. the client can request a particular role using a custom parameter that it passes to the server when requesting a request token (this gets passed in the parameters parameter to the provider.newRequestToken() method).
The security context that the oauth filter sets will delegate to the token isInRole() method when determining the roles - and the RolesAllowedResourceFilterFactory relies on the security context. So, everything should work as expected if OAuthToken.isInRole() returns the right value. Are you facing any issues?
I know it is an old post but I was facing similar issue. In my case I solved it exactly the same way as Martin described. During token authorisation I set allowed roles:
String verifier = provider.authorizeToken(token, sContext.getUserPrincipal(), roles);
where provider is #Context DefaultOAuthProvider, token is DefaultOAuthProvider.Token and roles is a Set of roles I want to allow the access by this token:
Set<String> roles = new HashSet<String>();
roles.add("someRole");
Then in my service I just use a #Context SecurityContext method isUserInRole("someRole") which gives me true in case the user is in specified role and false if not:
if (sContext.isUserInRole("someRole")) {
....
}
Hope it will help somebody.

Categories