Secure web service methods - web-services

How to call a web service's methods only through one app?
And other apps can't even use it with a web service address?
I filtered the IP but it didn't work.
An attacker program can be deployed on the same network and the same IP.

You can use different solutions for authentication. I suggest you to use token based schemes like Bearer authentication.
You can get more info about different HTTP authentication methods at : https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication
And more info about Bearer scheme at:
https://www.rfc-editor.org/rfc/rfc6750

Related

Accept only authentificated requests to backend

I have this question. I am quite new in this area.
I have web app.
This consist of services deployed on Docker engine.
The main services/containers are:
Frontend : React on Nginx web server
Backend (API) : Django, DRF on gunicorn on Nginx
For frontend I use Auth0 provider. It works as expected. If user is not authenticated/authorized it is redirected to login page.
Now I want also to "secure" my backend that it only would accept authenticated connections from frontend.
For backend (Django) I also have CORS enabled (django-cors-headers package), but I still can connect from my browser my-site/api/ and get the response.
Does anybody know which strategy should I use.
Should I somehow secure it using JWT tokens. Somehow pass it to backend in my request?
There is various ways of authorizing API calls from your front-end applications to execute actions on your back-end. These will tend to vary in a few aspects:
Complexity
Needing to know who sent the request
Access surfaces
Duration of access
Roles
and so on...
In this case if you have authenticated users on your front-end using AuthO then a JWT could make sense since using this method you can encode specific user data that will allow you to make the decision on your backend as to if that user should have access to that action at that time.
Here is an article explaining a few popular methods of authentication

How access to the JHipster API when authentication is managed by Keycloak

I've built a JHipster application with oauth2 authentication. The latter is implemented by Keycloak through the generated docker-compose file.
Everything works fine in the browser for "human" users. But I need to make some external programs use the API while beng authenticated.
So I started to simulate direct access to API with Postman. I read about XSRF-TOKEN cookie. But to be frank, I don't understand the process of authentication.
Can anyone explain how to perform authenticated requests to the JHipster API regarding keycloak ?
Maybe it isn't the appropriate approach : I also read about implementing a Configuration based on another authentication mecanism, that should be used for controllers exposed on a different endpoint.
Any help figuring out all of that would be really appreciated !
You need machine to machine authentication. Generally Open ID Connect (OIDC) offers client credentials flow for this case. So in theory you just enable it in the Keycloak client configuration and you may use it. But it depends on your API auth implementation. Your API very likely uses different OIDC flow for humans and it may not be ready for client credentials flow.
I got it working: Jan's tip show me the way.
Mainly I followed this tutorial.
The solution would be to add a client configured with Standard flow, Service account and Authorization enabled. Then I added the JHipster client scope provided by the generated docker-compose setup.
Once that was configured, I configured the request to use the Oauth2 authentication. I filled the configuration form for token request according to the tutorial. And I was good to go !
Many thx !

Bluemix, SSO: Calling REST service from mobile app (public client, native application)

I have a Bluemix web application (Liberty for Java), which implements some web services. These web services should be called from a mobile application (Android). I have now secured this web application by binding it to the Bluemix Single Sign On service (SSO) with a cloud directory created in the SSO service. Using the web app from a web browser works fine; but, I have problems obtaining an access token from the SSO service, which would allow the mobile application to invoke the services.
From the OAuth2 specification (IETF RFC 6749), I figured that the appropriate way of doing this would be the "native application" profile with a "public client" (as specified in Clause 2.1 of the OAuth2 Spec) using the "password" grant type (OAuth2 spec, Clause 4.3 "Resource Owner Password Credentials Grant").
I used the Spring for Android framework for this purpose, and code for this would look like this:
ResourceOwnerPasswordResourceDetails resourceDetails =
new ResourceOwnerPasswordResourceDetails();
resourceDetails.setId("dtu-se2-e15-cloud-directory");
resourceDetails.setAccessTokenUri(APP_SSO_API_ACCESS_TOKEN_URI);
resourceDetails.setClientId(APP_SSO_API_CLIENT_ID);
resourceDetails.setClientSecret(APP_SSO_API_CLIENT_SECRET);
resourceDetails.setGrantType("password");
resourceDetails.setScope(Arrays.asList(SCOPE));
resourceDetails.setUsername(USERNAME);
resourceDetails.setPassword(PASSWORD);
OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(resourceDetails);
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
UserPosition newPosition = restTemplate.postForObject(
POST_POSITION_SERVICE_URI, position, UserPosition.class);
But, I don't think that this code matters, and ultimately made my experiments with obtaining access tokens directly with curl:
Actually, I tried using two different clients with different OAuth2 token endpoints:
I created a client (and client credentials) in the Cloud directory, that I had created in the Bluemix SSO service. And I tried the OAuth2 Token Endpoint URI and the created client credentials. But it appears that this endpoint does not support the grant type "password" at all. It appears that this client is not considered a public client by the endpoint.
I also tried the credentials and OAuth Token Endpoint URI for the Web application itself (which I looked up in the VCAP_SERVICES environment variable). This end point seems to support the grant type "password"; but all variants of requests I could think of, kept responding: invalid_resource_owner_credential.
As I said, I used curl to try out many different variations of requests to these
token endpoints:
used the token endpoint URI of both the SSO services with the web app credentials
as well as the one created in the cloud directory API Access
tried GET and POST (did not make any difference)
tried Content-Type: application/x-www-form-urlencoded and
Content-Type: application/json (both of them seemed to work with the same effect)
providing the client_id only (which always was unsuccessful)
providing the client credentials in the body or parameters, as well as
authenication information in the header (actually, I do not like the idea
of providing the client secret to the Android app, but I tried that too);
as user name, I tried the name as I had created it in the web browser redirection
when registering a new user; but I also tried the user name which the Principal of
the security context of a request would provide (when successfully invoking
a service from a web browser with the user logged in); I even tried the principal's
accessId (non of these worked, I always got: invalid_resource_owner_credential)
used different scopes, and none at all
None of the above (and different combinations of that) would result in a successful
response and an access token for the user. The "best" I could get was a response
invalid_resource_owner_credential (making me believe that at least the client was
accepted in some situations).
Unfortunately, I did not find many things that could be configured concerning client
access (and public clients, in particular), and I did not find much documentation on
which subset of the OAuth2 protocol (grant types and profiles) is supported by the
Bluemix SSO service and the attached cloud directory.
Can anyone could tell me how to authenticate with a Bluemix web application
(Liberty for Java) from a mobile app (Android) as a public client or how to set
up the Bluemix web app and the SSO service to which it is bound so that this is
possible. In case it would matter, I am working with Bluemix in the "US South"
region and under an IBM Academic Initiative membership account for Bluemix.
I would prefer a solution, where the mobile app would not need to know the client
secret, but if this is the only way to make this work for now, adding the client
credentials to the mobile app would be OK.
I would appreciate any help with this problem, thanks in advance,
Ekkart
Bluemix has a mobile-specific service called Mobile Client Access that could help to facilitate security for your mobile app. To read about it, log into Bluemix and look for it under the Mobile category. To ask questions about it here, use or search using the [bluemix-mobile-services] tag.

Is it possible to restrict web service access to it's own web app?

Is it possible to block connections to a web service (server) from outside its domain?
For example consider a web app that fetches data from Twitter's API using Twitter's "application only auth". The web app's client uses AJAX to call it's own server, which in turn calls Twitter's API with Twitter's token.
While the token is never exposed to the client side code is there anything to stop an outside server side app from calling the web app's server using the URLs used by the client and for example exhausting the Twitter tokens rate limits?
Is it possible to block connections to a web service (server) from outside its domain?
Certainly. Set your web server's access control lists to drop connections from outside of your IP range. Alternately, install a firewall. That's very straightforward, but I suspect you mean something else by "outside its domain?"
From your description, you seem to be really asking whether you verify that you're only talking to your own client application. As a general rule, no. You can authenticate users. That's easy. If the user isn't logged in and authorized to use your service, you don't forward requests to Twitter. But you can't authenticate applications.
If you're going to accept any user who shows up, you can't stop them from using whatever client they want. There is no way to ensure that it is your unmodified client if you've allowed it to be run on their machine. They can always modify it, and they can always send you arbitrary traffic from other programs and you can't tell the difference. On the network, bytes are bytes.
It's not all hopeless; there are things you can do. See https://stackoverflow.com/a/9183066/97337 for another version of this question, and links to several other versions of the question. (They're not exactly duplicates in how they're asked, but they all wind up being basically the same answer.)
You should secure your web service with user and password security or certificate security. The basic idea is that the web service client must authenticate in order to call your web service.
Here are some technics (there are others or variations):
1) HTTP basic authentication and HTTPS
2) Mutual SSL authentication - Also called two-way authentication, is a process in which both entities authenticate with each other. The server presents a certificate to the client and the client present a certificate to the server.
3) With SOAP web services you can use WS-Security standard.
4) OAuth framework
5) With Rest services you can use options 1), 2), 4). Or implement one by your own. This are good recomendations.
As you can see, there are a lot of ways to secure a web service.

Handle Authentication and Authorization in jax-rs webservice with cxf

I have a webapp which has jsps. am not using any struts or mvc framework. We have JAX-RS service build using Apache CXF.
Now i want to do following
Allow user to login with username and password.
For all subsequent calls to webservice, same authentication info should be used.
Logged in user has some details (profile photo, full name), which i want to keep it constant across session.
Also, its role are defined. Based on role(s) only certain jax-rs calls will be allowed.
Roles are also used in JSP to restrict access to functionality.
Web services can be accessed outside so authentication and authorization info should be used.
As far as i understand, We should not use session in jax-rs services. What is the best way to handle above situation ?
The best way depends on how you estimate it.
My way of doing this is to
Run Rest service and JSP on the same instance
Use web.xml and CXF to set up security policy, which allows user/pw authentication and authorization, ROLES binded to both jax-rs urls and JSP urls.
Based on 2, jax-rs services can be called directly outside, but user/pw is required as you specified.
Hope this can help you a bit.
Think cxf security validation as any other http or https validation. you have to intercept the request and pass it to the rest service. You can use any of the tools like siteminder, else can write CXF interceptor to do your own security validation. In the interceptor you can call SSO kind of token generator server in case you have the infrastucture or call the DB if your architecture is built that way. You can use caching to reduce the resource hits and can look at custom or hibernate cache. enabling Https has to be done in server configuration. If you have certificate , you can use the same else you can generate your own using openssl.