In my asp.net mvc4 project, I am using ApiControllers to serve both web clients and mobile clients. To secure the web services, I am using the [Authorize] annotation.
So for now, the web client is working fine. However, when I tend to invoke some Web API from a mobile application (e.g. Android), I got an error.
when I looked back at code snippet:
[Authorize]
public List<double> GetSomeInfo(int param1, string param2)
{
User user = SessionData.CurrentUser;
// do something using user.UserId
// ....
}
Session Data does hold user connected properties only when he is connected to the Web App. But in the case of mobile clients, Session Data is null. So, is there any appropriate method to resolve this problem.
In my opinion, I think that userId should be provided as a parameter for any Web API that may need it to do achieve some treatment.
What do you think ?
You are talking about two different things :
Session
As Darrel said, Web Api was not design to support Asp.net Session. HTTP and Rest Services are stateless – and as a result each HTTP request should carry enough information by itself for its recipient to process it to be in complete harmony with the stateless nature of HTTP.
So, do not rely on Session Variables, but add more paramters in your request.
Of course, there are a way to use session in Web Api, I suggest you to to use it.
Authentication
Because working with only paramaters ( such as UserId, AccountId, ...) is not very secure, you have to use Authentication and Authorization. I highly suggest you to read the security section in asp.net web api web site. Web Api support many authentications (Basic, OAuth, Windows, Custom, ...). You have to choose what is the best for you.
Web API was not designed to support sessions as they are a HTTP anti-pattern. You can get the currently authenticated user by accessing Thread.CurrentPrincipal if you have setup the necessary authentication mechanisms.
Related
I'm working on an android apps. I am using ionic framework. In some pages I need to get data from a web server and the result is an object json.
My problem is if some one arrives to GET the pages where I get the json data, one can fetch all my database data by changing the http request.
Is there any way that can improve security of my apps?
You should make some kind of authentication mechanism, for example, a token in the header, that way you know wether the user has access to that resource or not.
So when you make your request you can generate a configuration for that particular request.
Example:
var url = "http://yourserver.com/api/your/path";
var config = {
"headers": {
"Authorization": "Bearer someBearerFromTheServer"
}
};
$http.get(url, config);
The backend implementation for this to work depends on the language you use. Here google is your best friend.
A more advanced way to do this, is to use interceptors in the $http service and attach the token to the header in every request, but be careful, you should secure this so you won't send your credentials to every request you make (sometimes your app might need to request data from another server).
You can read more about $http services and its configurations in the $http service documentation.
Regards
Hello all i am making an android app in whiich i have multiple account login at a time now my question is that i for multiple logins i should use sessions to verify every account user that is logged in. Now i am using express on the server side i have read a lot of documentation on storing sessions in node.js
Express-session (Though it is only good for development but not for production but not for my app)
Cookie-session
connect-Redis
connect-mongo
I have also heard about json web tokens where i can generate unique tokens and then i can pass the tokens to the client using res.json({user_id:"user1", token: "generated_token here"})
I have also heard about passport but dont know how it is going to do this also as in passport i use express-session by default will it be good for production or not ??
Now my first question is i have read all of there docs and nowhere it is mentioned where i am creating unique tokens for every user that is signing up.
Second question as i am using my server for android app there will be no use of cookie i will be sending user token as in parameter req.body.token now how to cmpare this with current user_id.
Actually i dont get the flow of control i mean how everything is going on in session in node.js. Also what is this secret is this thing generating unique tokens or what. Also i mean about 100000 of users are registered for my app now please tell me accordingly which way should i use for my app.
I have asked this question previously but there i did not mention that as i am not making a website how to do this(As in my case there will be no use of tokens)
I know this question i am asking is very vague but please bear with me i just want to understand how sessions are used in node.js
Thanks Anways
I'll try to answer this, but it is vague (as you pointed out). I'm going to make an assumption that your Android app is a native Android app and is going to be connecting to some sort of NodeJS backend in the cloud that is based on ExpressJS. If that's not the case, please clarify your thoughts in an update to your question.
The best idea for this specific scenario is to look to the cloud provide. Azure App Service Mobile Apps, for example, allows you to implement authentication - it eventually returns a JSON Web Token (http://jwt.io) to authenticate each request.
If you don't want to be beholden to a cloud provider, but want to run it yourself, you are going to have to implement the token generation and checking yourself. This generally follows the form:
Set up a WebAPI endpoint (maybe /signin) which takes whatever token the identity provider gives you, verifies the information and returns a JWT - there is an NPM module (jsonwebtoken) for producing the JWT. Ensure the JWT includes the identity of your user. I tend to use email address for the identity.
Your Android application will do a WebAPI request to your backend with an Authorization header, the value of which is "Bearer "
Your NodeJS API will use JWT authorization to validate the JWT and extract the user identity so you can use it in your API logic.
The important thing to note in this specific scenario is that your backend code is implementing a WebAPI - there are no cookies nor sessions in the API. The only thing that is linking the user from the client code to the backend code is the JWT.
As a short piece of code, here is how you verify a JWT:
var express = require('express');
var app = express();
var jwt = require('express-jwt');
var jwtCheck = jwt({
secret: new Buffer('your-jwt-secret', 'base64'),
audience: 'your-jwt-audience'
});
app.get('/api/protected', jwtCheck, (req, res) => {
// Your code here
});
app.listen(process.env.PORT || 3000);
Would like to use Retrofit for handling network requests between Android Client and GAE endpoints.
GAE endpoints give Client/Server endpoint libraries to handle all the networking and also Oauth2 authentication which is nice.
Retrofit helps well for asynchronous call, cancellation, parallel calls...so is better than android client asynctask.
So can this Retrofit lib be configured with Appengine GAE endpoints or need to go through normal GAE servlet?
Just to clarify my question and make answers clear for any who read this :
I had for my App :
Client side : cloud endpoint library generated by google plug in for eclipse
Back end side GAE : different API with methods coded in JPA such as :
#ApiMethod(name = "insertMyShareItem")
public ShareItemData insertMyShareItemData(ShareItemData shareitemdata) {
logger.log(Level.SEVERE, "insertMyShareItem");
}
Advantages of google cloud endpoint was endpoint libray , easy use of Auth2 and automatically use of secure connections via HTTPS
Now I want to give up Async task in order to implement Retrofit or Volley. I understood I cannot use google cloud endpoint anymore and need to transform my methods on GAE Back end side in methods which extends HttpServlet so I can access them by URL call with normal setup of Retrofit.
Which means now I need to care :
how I pass my object to Retrofit and how I retrieve them on back end
how I transform Retrofit HTTP call in a HTTPS call for secure connection
how I implement and manage Auth2 and tokens between Client and GAE back end to establish secure authentication.
This is what I understood from search and below answers.Thks
Use the Google Cloud API URL as the base URL and proceed with the normal setup of Retrofit. I don't think it is a big deal. Here is a link to a tutorial that could help you get started with Retrofit.
[source]
I have been doing a lot of research recently on securing my app engine. Currently, I've been reading through the question below and the links in that question:
How do I restrict Google App Engine Endpoints API access to only my Android applications?
However, it doesn't answer my problem. My question is similar to the question above, restricting access to my endpoint API to only my app. The guy seemed to have got it working when he inputs a correct email into the credentials.
My question is if I can achieve the same results without having to input any credentials. I want it so that only my app can use my endpoint API so to prevent other apps from abusing it and using up my quota. I already got a client id for my android application, and have placed it within my #API annotation. To test if it worked, I made a random value for the client id in the #API notation of another api class. However, my app was still able to use methods from both class. Any help?
-Edit-
From reading from the docs and researching further, the endpoint way of authorizing apps is by authenticating the user and for my API to check if user is null. My question is that in the process of authenticating the user, is Google somehow able to read my app's SHA1 fingerprint and authorize it to its list of client ids? If so, how can I replicate this process in my endpoint so that I check the SHA1 fingerprint of the app making the request and compare it to a set value? I don't understand the mechanics behind the endpoints very well, so correct me if I am understanding this wrong.
If the android app has access, then the user has access. A motivated party has many options for inspecting your protocol, including putting the device behind transparent proxy or simply running the app through a debugger. I do suggest running your app through ProGuard before publishing, as this will make the process [a bit] more difficult.
Ultimately, you'll need to make your appengine API robust against untrusted parties. This is simply the state of the web.
How you can protect your endpoint API is described here: http://android-developers.blogspot.com/2013/01/verifying-back-end-calls-from-android.html
The secret is that you request a token from Google Play using the following scope: audience:server:client_id:9414861317621.apps.googleusercontent.com where 9414861317621.apps.googleusercontent.com is your ClientId.
Google Play will look up the id at your endpoints app and return a Google-signed JSON Web Token if it finds the id. Then you pass that id in with your request. Above article says you should pass it in with the body. I would possibly rather add another parameter for that because otherwise you can't pass your own entities anymore. Anyway, your server backend receives the token, and you ask Google as described if it is authentic, before you process the API request.
If you pass in the token using an extra parameter, you can catch it on the server side by adding HttpServletRequest to your endpoint signature and then using request.getHeader("Yourname") to read it out. Make sure you never add the parameter as a URL parameter as it may be logged somewhere.
public void endpointmethod(
// ... your own parameters here
final HttpServletRequest request
) throws ServiceException, OAuthRequestException {
request.getHeader("YourHeaderName") // read your header here, authenticate it with Google and raise OAuthRequestException if it can't be validated
On the Android side you can pass in your token when you build the endpoint api, like this, so you don't have to do it with each and every request:
Yourapiname.Builder builder = new Yourapiname.Builder(AndroidHttp.newCompatibleTransport(), getJsonFactory(), new HttpRequestInitializer() {
public void initialize(HttpRequest httpRequest) {
httpRequest.setHeader(...);
}})
Hope this helps you make your endpoints API secure. It should.
I'm currently designing and prototyping the architecture for a web application that comprises of three parts, a Restful API (JSON, XML) interface served from a Rails app, a Backbone.js application being supported by a second Rails app, and an Android application that accesses data via the API.
Whereas the usual process of authenticating the user (redirecting to the login page) will work for the Backbone.js application, I want to use a single access token from the Android application to authenticate the user. I can see how upon first use the Android app would require a username and password, passing back from the CAS server additional information that would contain the pre-generated single access token. What I can't work out is how I would pass the single access token along with a request from the client and have that authenticated against CAS without redirecting to a login page etc.
What I need to know is whether this possible with CAS or is there a method that is more the "CAS way" that I can use to achieve the same result?
I've experimented with Devise and the CAS plugin devise_cas_authenticatable but this appears to be broken with the latest version of Devise. Ideally I want to use sorcery with my own implementation of single access token generation, all hooked up to CAS. I'm very new to CAS and what it can do so I'm trying to sound out what's possible first and then I'll contribute back to rubycas-client and sorcery if any new development is required that I'm able to code up.
Thanks in advance
I believe you are looking for Proxy Granting Tokens (Section 3.3). This allows one application to proxy a valid authentication to another application. The RubyCAS client supports this via:
class ApplicationController < ActionController::Base
before_filter :authenticate!
protected
def authenticate!
# This triggers RubyCAS client to request a proxy granting ticket
CASClient::Frameworks::Rails::Filter.client.proxy_callback_url = "myservice.com"
CASClient::Frameworks::Rails::Filter.filter(self)
if session[:cas_pgt]
# You will want to pass this as a URL param to your remote service
# whenever you call it. We store it on our base ActiveResource model
# and automatically append to the url params of all requests.
end
# Username is available in session[:cas_user]
end
end
This solution does not use devise.