I'm just curious about how Google app engine's user service works. The way I understand it, the user logged in state is stored in the cookie. To get the cookie, one has to have a http servlet request object (for java servlet at least). But the user service api doesn't require any http servlet request as input, so how does it get the cookie to check the whether the user is logged in or not?
Tim
During requests, user setup is handled by Google's servlet implementation.
[I]f the user is signed in and get the user's email address or OpenID identifier using the standard servlet API, with the request object's getUserPrincipal() method.
During the login process, the service works using redirects, similar to OpenID or OAuth. Take a look a the URLs throughout the login process.
Users are redirected to a URL, which is handled by App Engine, on your app, something like:
http://app.appspot.com/_ah/login?continue=http://app.appspot.com/dosomething
The login handler redirects to the Google login service, something like:
https://www.google.com/accounts/ServiceLogin?service=ah&continue=http://app.appspot.com/_ah/login%3Fcontinue%3Dhttp://app.appspot.com/dosomething<mpl=gm&ahname=Your+App+Name&sig=hf3322hdsk98fd8fh3u29hfh24as
You login, then Google redirects you back to the app engine login handler:
http://app.appspot.com/_ah/login?continue=http://app.appspot.com/dosomething
When Google redirects, some query parameters will be passed to the App Engine login handler, and the built-in login handler will set the cookie.
You are then redirected to the URL you specified, or where you 'started' from. Something like:
http://app.appspot.com/dosomething
What about the in the subsequent calls? For example (continuing from your point 4)
User calls the servlet http://app.appspot.com/dosomethingelse
In the servlet dosoemthingelse, I can again call UserService like this
UserService userService = UserServiceFactory.getUserService();
User user = userService.getCurrentUser();
String userId = user.getUserId();
How does this userService instance gets the cookie to know who is the currently logged in user?
Related
If I want to call request.isUserInRole("SOME_ROLE") this means that the request knows about the user making it (assuming the user is authenticated) , my question is : after the user is authenticated where does his information go so that the request knows about it later ? I know that in case of enterprise application , it's stored in a java.security.Principal object, is this the same in a simple web application ?
can I use request.isUserInRole("SOME_ROLE") while using FORM based authentication <auth-method>FORM</auth-method> .... will the authenticated user be reflected to the request automatically?
Usually in simple webapps, the logged in user information is put into http session.
I read through several q&a on stackoverflow for implementing rest authentication. And in one of those questions found a sample code as well.
https://github.com/philipsorst/angular-rest-springsecurity/blob/master/src/main/java/net/dontdrinkandroot/example/angularrestspringsecurity/rest/AuthenticationTokenProcessingFilter.java
Most of the answers talked about having an interceptor and filtering every request based on the auth header (a token and a user id or login id) and comparing it with the ones stored in the database.
I am implementing an Order management system.
And my url looks like http://myapi.com/customers/{customerId}/Orders/{OrderId}
Currently it is http and we're setting up the https soon.
In the URL, I get the customer ID and the order ID. I do a quick look up in the database with the order id and customer id and if it returns some rows, I return a JSON.
Questions I have:
To protect this endpoint, I can have a security interceptor. But every time I'll have to validate the request against the database. What are my alternatives (cache?) to validate or authorize each requests?
This rest end point is consumed by an android app(angular js)client and a website (a php client). For mobile, I should not re generate token each time the user logs in. So I have configured the token expiry to 30 days. However for the website, it is a session token. How should one handle this scenario?
What you need can be solved with Oauth.
Your backend (REST-API) will require authenticated access to your API operations. In turn, your clients/front-end will need to issue authenticated requests when communicating with the backend. This is achieved by sending access tokens.
Although this could seem complex, it will be very useful for you to take a look at Stormpath. We have a quite a straightforward solution for this. Please take a look at Using Stormpath for API Authentication.
As a summary, your solution will look like this:
You will use the Stormpath Java SDK to easily delegate all your user-management needs.
In your front, when the user presses the login button, your front end will send the credentials securely to your backend-end thorough its REST API.
2.1. By the way, Stormpath greatly enhances all the possibilities here. Instead of having your own login page, you can completely delegate the login/register functionality to Stormpath via its IDSite, or you can also delegate it to our Servlet Plugin. Stormpath also supports Google, Facebook, LinkedIn and Github login.
Your backend will then try to authenticate the user against the Stormpath Backend and will return an access token as a result:
/** This code will throw an Exception if the authentication fails */
public void postOAuthToken(HttpServletRequest request, HttpServletResponse response) {
Application application = client.getResource(applicationRestUrl, Application.class);
//Getting the authentication result
AccessTokenResult result = (AccessTokenResult) application.authenticateApiRequest(request);
//Here you can get all the user data stored in Stormpath
Account account = accessTokenResult.getAccount();
response.setStatus(HttpServletResponse.SC_OK);
response.setContentType("application/json");
//Output the json of the Access Token
response.getWriter().print(token.toJson());
response.getWriter().flush();
}
Then, for every authenticated request, your backend will do:
/** This is your (now protected) exposed operation */
public void getOrder(HttpServletRequest request, HttpServletResponse response) {
Application application = client.getResource(applicationRestUrl, Application.class);
OauthAuthenticationResult result = (OauthAuthenticationResult) application.authenticateOauthRequest(request).execute();
System.out.println(result.getApiKey());
System.out.println(result.getAccount());
//Return what you need to return in the response
doGetOrder(request, response);
}
Please take a look here for more information
Hope that helps!
Disclaimer, I am an active Stormpath contributor.
I'm trying to come up with the best way to do my own authentication in our Java REST API using the Jersey framework (v2.5.1) running on Tomcat 7.
The API will be accessed through our iOS application. In the iOS application we use Facebook authentication (using the Facebook SDK), and then we use the access token in every call to the REST API.
#Provider
#Priority(Priorities.AUTHENTICATION)
public class AuthenticationFilter implements ContainerRequestFilter
{
#Override
public void filter(ContainerRequestContext requestContext) throws IOException
{
// Extract the access token from the HTTP header
// Look up in the database to see if we have a user with that token
// If there is a user found, proceed
// If we can't find a user, we are going to send the token to Facebook to get the user details. If the token is invalid, we throw an exception. If it is valid, we look up if we can match the Facebook details with an existing user. When we can't match, we create a new user.
}
}
This filter will be executed in every API request.
My questions:
Is this a correct workflow?
Should we contact Facebook every time to validate the token? This will cause a lot of overhead.
This filter is executed for every request. How can we exclude certain urls (some resources won't require authentication)? I was thinking of holding a set of urls in the filter class and see if the requested url matches one of the defined public urls (if so, don't do the authentication).
Thanks!
I think it might be better if you can provide this option to your user:
login / login using facebook account.
So you dont have to contact Facebook unless user choose to login using their FB account.
also, the authentication should be session based. session information can includes user, session key, valid time range, maybe source IP too. once the user has successfully logged in, a session is generated. then for every request you only have to check if the session key is still valid.
Is it possible that my FB app to post on users behalf without any interaction from the user (server-side). I suspect that an initial login and request permission phase is needed, but after that I want that my app to post on their behalf for, let's say, the next month.
I'm using Java and I'm leaning towards Spring Social, but any similar framework is acceptable.
I know that this question has been asked, but I don't think with Spring Social.
The class org.springframework.social.facebook.connect.FacebookAdapter (see API) has an updateStatus method which takes a FaceBook and a String. Looks like it would do the trick.
FaceBook itself is instantiated by first acquiring an access token from facebook, and then passing the token as a String to FaceBookTemplate's constructor, like so (copied from Spring's reference docs):
String accessToken = "f8FX29g..."; // access token received from Facebook after OAuth authorization
Facebook facebook = new FacebookTemplate(accessToken);
I believe you could use Quartz to schedule and execute the task itself.
I know this has been asked already, but I am not able to get it to work.
Here is what I would like to get accomplished:
I am using Spring Security 3.2 to secure a REST-like service. No server side sessions.
I am not using basic auth, because that would mean that I need to store the user's password in a cookie on client side. Otherwise the user would need to login with each page refresh/ change. Storing a token is I guess the lesser evil.
A web client (browser, mobile app) calls a REST-like URL to login "/login" with username and password
The server authenticates the user and sends a token back to the client
The client stores the token and adds it to the http request header with each api call
The server checks the validity of the token and sends a response accordingly
I did not even look at the token generation part yet. I know it is backwards, but I wanted to get the token validation part implemented first.
I am trying to get this accomplished by using a custom filer (implementation of AbstractAuthenticationProcessingFilter), however I seem to have the wrong idea about it.
Defining it like this:
public TokenAuthenticationFilter() {
super("/");
}
will only trigger the filter for this exact URL.
I am sticking to some sample implementation, where it calls AbstractAuthenticationProcessingFilter#requiresAuthentication which does not accept wildcards.
I can of course alter that behavior, but this somehow makes me think that I am on the wrong path.
I also started implementing a custom AuthenticationProvider. Maybe that is the right thing?
Can someone give me a push into the right direction?
I think pre-auth filter is a better fit for your scenario.
Override AbstractPreAuthenticatedProcessingFilter's getPrincipal and getCredentials methods.
In case the token is not present in the header, return null from getPrincipal.
Flow:
User logs in for the first time, no header passed, so no
authentication object set in securityContext, normal authentication
process follows i.e. ExceptionTranslation filter redirtects the user
to /login page based on form-logon filter or your custom authenticationEntryPoint
After successful authentication, user requests secured url, pre-auth filter gets token from header authentication object set in
securityContext, if user have access he is allowed to access secured
url