I'm new to Google Cloud Endpoints and I am currently looking for an alternate way to receive the User method parameter.
In the documentation on Authenticating Users, the only way of receiving information about the user that is shown is to receive an instance com.google.api.server.spi.auth.common.User as a method parameter.
There appears to be no annotation I can use to request this principle elsewhere other than directly on the endpoint method. This can obviously be made to work, but I am very interested in the following scenario:
/*
* in an injection provider
*/
CustomUserClass getUser(#EndpointsUser User user) throws UnauthorizedException{
if(user == null) throw new UnauthorizedException("If we're requesting the user be injected, we should reject unauthenticated requests");
//datastore code to lookup and return my representation of a user
}
/*
* in the endpoint class
*/
#Inject
CustomUserClass userProfile;
//endpoint methods here
Does anyone know how to do the above? I realize I could simply move this logic into my endpoint class, but this is a case of cross-cutting concerns and is not only bad programming, but less easily tested.
Yes, I know I can role my own solution (pun intended), but cloud endpoints is supposed to make this kind of thing easy, isn't it?
This is currently not possible, as Guice use cases weren't common when the frameworks were written. You can file a feature request.
Related
I am looking at building a class implementing the IdentityServer IResourceStore interface. My goal is to serve IdentityResource and ApiResource collections as defined in a custom repository.
Ideally, I will receive requests for these resources and respond with the subset relevant to the query. In short: You only get what you ask for.
The GetAllResources()method makes me leery: Is IdentityServer actually requiring that I pull the entire set of my Identity and API resources from my repository and make this available? At this point I have no idea how large those collections will grow, or the cost of pulling them from the repository.
What are the consequences of simply responding with a null or empty lists of resources?
-S
It's used in the GetAllEnabledResourcesAsync method in the IResourceStoreExtensions class, which in turn is used by the DiscoveryEndpoint. So, if you don't implement this method the Discovery endpoint will not be able to display any scopes or claims.
By don't implement I mean return some empty lists or something, not throw a NotImplementedException or return null... That would break everything.
Contemplating building an Angular 2 front-end to my website. My question is not necessarily related to Angular but I want to provide full context.
Application logic that displays content to user would shift to the client. So on the server side, I would need to expose data via a RESTful JSON feed. What worries me, is that someone can completely bypass my front-end and execute requests to the service with various parameters, effectively scraping my database. I realize some of this is possible by scraping HTML but exposing a service with nicely formatted data is just a no-brainer.
Is there a way to protect the RESTful service from this? In other words, is there a way to ensure such service would only respond to my Angular 2 application call? Authentication certainly isn't a solution here - I don't want to force visitors to authenticate and the scraper could very well authenticate and get access, anyway.
I would recommend JWT Authorization. One such implementation is OAuth. Basically you get a json web token ( JWT ) that has been signed by an authority you trust that tells about the user and what resources they can access on your api.
If the request doesn't include an Authorization token - your API rejects it.
If the token has been tampered with by someone trying to grant themselves privledges after the token is signed by the authorization authority - your API rejects it.
It is a pretty cool piece of kit.
This site has information about OAuth implementations in different languages, hopefully your favorite is listed.
Some light bed time reading.
There is no obvious way to do it that I know of, but a lot of people seem to be looking at Amazon S3 as a model. If you put credentials in your client code, then anyone getting the client code can see them. I might suggest that you could write the server to pass a time limited token back to the browser with the client code. The client code would be required to pass it back to the server for access. This would prevent anyone from writing their own client code, as only client code sent by the server would work, though only for some period of time. The user might occasionally get timeouts, but that depends on how strict you want to make the token timeouts. Of course, even this kind of thing could be hacked by someone making a client request to get a copy of the token to use with their own client API, but at that point you should be proud that someone is trying so hard to use your API! I have not tried to write such a thing, so I don't have any practical experience with the issue. I myself have wondered about it, but also don't have enough experience with this architecture to see what, if anything, others have been doing. What do angularJS forums suggest?
Additional References: Best Practices for securing a REST API / web service
I believe the answer is "No".
You could do some security by obscurity type stuff. Your rest API could expose garbled data and you could have some function that was "hidden" in your code un-garble it. Though obviously this isn't fool proof, but if you expose data on a public site it's out there regardless of server or client rendering.
I've exposed a few APIs using go-endpoints. The APIs work fine, but what I'd like to do is restrict usage of the APIs to only a few referers. Since I'm not passing any authentication information, I do not need OAuth (actually, I really do not want to use OAuth as I expect anonymous users to utilize a front-end that uses this API... I just want that front-end and perhaps another one to use my API).
Apparently the way to do this is to make a Public API Key using the Google Developers Console (Project --> APIs and auth --> Credentials --> Create new Key).
I've changed my JavaScript to use this key, by passing it as a param: https://my-app-id.appspot.com/_ah/api/myService/v1/doSomething?key=key_from_developer_console
However, when I make the call, I get a 403 back with this error:
"Access Not Configured. The API () is not enabled for your project. Please use the Google Developers Console to update your configuration."
Well, initially I set the referer to my-app-id.appspot.com/*, which is only place I want my API to be used from. So I figured I'd remove it just to see, but I get the same issue.
There are some old posts here about having to enable Contacts API and Google + API. I tried that, and it didn't work either.
So what gives? There is virtually no documentation from Google on this Public API Key feature. This is really driving me up a wall...
I had this exact same problem yesterday. I decided to generate my own key and added in my own logic to check for the 'key' param from the request. I just added the self-generated key to my env_variables and it works. However, if you try to redeploy after taking this approach, you may still see the access configuration issues..at least I have still.
I've created an application using Google Web Toolkit and Google App Engine that saves objects based on user selections into a RPC Service Implementation.
It was my understanding that everytime GWT "creates" this service, the data is reinstantiated with the default values. Unfortunately it seems like when a user on one computer saves a change to the data, another user on another computer is seeing the data change on their end. Im not using a datastore or anything so why is this happening?
EDIT: After some research I am seeing that I need to use sessions to handle the delivery of the objects. However, in my RemoteServiceServlet I am calling this.getThreadLocalRequest and it's returning null. Why does this.getThreadLocalRequest() return null??
UPDATE: Answering my own questions here : ) You cannot getThreadLocalRequest() in the constructor of your Servlet. duh.
The problem was that I was calling getThreadLocalRequest() in the constructor of my servlet. Good thing to be aware of - the local request doesnt happen until the servlet is loaded.
I have the beginnings of a standard Silverlight/ RIA/ EF application that is just working straight away as expected.
I wanted to restrict my entire DomainService to only authenticated users, as the application will eventually live on the public internet, and all data access needs to be user authenticated.
The problem I have, is that I cannot use the auto-generated DomainContext class in my Silverlight app unless I wrap all of its Load methods inside a custom class that verifies the authentication status of the user before attempting to retrieve data - which seems like a long and tedious coding task.
Surely there must be a simple solution that Ive missed ?
This stuff was easy in ASP.NET because the moment you lost (or never had) authentication you were redirected to a login page (as configured in web.config).
Im really suprised theres no similar mechanism in Silverlight, as it seems to be to be a standard business application requirement.
Requiring authentication in your DomainService is easy. Just add a [RequiresAuthentication] or [RequiresRole] attribute to either the class (applies to all operations) or operation you want to authorize. You might find these links helpful.
How to: Enable Authentication in RIA Services
RequiresAuthenticationAttribute
I am not 100% sire if this is the answer you want and if it's a good practice to do it like this but you could implement a message inspector that inspects whether the user is authenticated like this:
public class ClientCustomHeadersDispatchMessageInspector : IDispatchMessageInspector
{
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
if (!HttpContext.Current.User.Identity.IsAuthenticated) {
throw new SecurityException("User not authenticated");
}
return null;
}
public void BeforeSendReply(ref Message reply, object correlationState)
{
}
}