Securing Rest Web Service for Public Authentication - Server to Server - java

I've a have a public RESTful API that is used for user authentication for a web application that accepts the user id and password in clear text (see below). The username is passed in the url path as a path parameter and the password is a query string parameter. The HTTP GET comes from another web application on the server side (http client request), is this API secure? I was under the impression that the URL can not be seen if the request is going from server to server. My main fear is that someone could use something like firebug and see the traffic and get the userid and password.
REST end point:
HTTP GET https://host:80/user/joebob?password=pass123

Someone most definitely could see the username and password with a simple network sniffer. If you are POSTing the request, why are the parameters in the URL? They should be in the body like a normal POST, then at least the SSL protection kicks in and people can't sniff them. Another option would be for you to look at HTTP Basic Auth.

Related

Is it possible to get authorization_code in OAuth 2.0 without web browser in Java?

As I understand, in authorization code flow we need to get authorization code and use it to get token after. We can get this code only when user confirms specified access. After that browser redirects us to redirect_uri and response will contain authorization code as parameter. So, the question: is it possible to get this authorization code without browser or any self made UI? Can we get it in application after correct request to, for example https://mysite.tuz/authorize ?
As you are using authorization code flow, the client requires a user agent (i.e browser or mobile app) to get the authorization code from the authorization server.
The whole purpose of using authorization code is that it can be passed via the user's web browser (user agent) instead of passing the access tokens directly via the web browser (user agent) which is not desired. Using authorization code,the Client then can directly retrieve an Access Token from the authorization server.
So the user agent is required to get the authorization code and act as an intermediary between client and authorization server.
If you do not require a browser then authorization code flow may not the correct choice. OAuth 2.0 supports several different grants i.e ways of retrieving an Access Token. Deciding which one is suited for your case depends mostly on your Client's type.
This might help you in deciding which flow to use
https://auth0.com/docs/api-auth/which-oauth-flow-to-use
You should use client credentials to obtain token without browser or any client. But if you need to use user credentials to get access token and id token of the user without browser or mobile app you need to implement you own client which will do the necessary logic for you and fetch the token for you. I already did it in java for the testing purpose. I don't know why you need to do it but you can implement your own client in almost any programming language . But in case you will decide to go this way you have to handle lot of things.
I expect your authorization server requires Proof-Key for Code
Exchange (PKCE) - so first of all before you start to communication
with server you have to create code verifier and code challenge
(google can help you with that :) in java it is quite simple)
Then you should start communication with server sending get request to url which ends with 'auth' you should send query params as: response_type (which is 'authorization_code' in your case), redirect_uri, client_id, code_verifier, code_challenge, scope, code_challenge_method (probably 'S256')
Then you receive I think two redirects from server so it is better to have some client in java which will automatically call those redirects. I used apache http client for my implementation. It has lot of features.
After successful redirect server will return login page to your client. It depends on authorization server but in this page you should put the data as username and password and submit the page. I have simply parsed the returned page and get the url for user authentication from it and simply make post request to that url with user credentials data sent in encoded form entity. In apache http client you will have all cookies from previous communication set (until you close the client) since apache http client automatically set all cookies returned in previous communication from server.
After make authentication request server will send you two redirects and you can store those redirects int http client context which you will provide for http client when you call authentication url.
In the last redirect there will be query parameter sent be server named "CODE" this is really important for you since you will use it to get token from the server
And finally you have to make one last post request to authorization server with url ended as token. So make a post request with GRANT_TYPE, REDIRECT_URI, CODE (you received in previous redirect), CLIENT_ID, CODE_VERIFIER (you have generated at the beginning);
Then authorization server will send you token and that's all

Secure REST endpoints with service user or public user

I'm writing a mobile app that communicates to a remote Java service via REST. I have protected my (SpringBoot) web service with https protection (due to the nature of the data, it needs to be secure) but my question is about which user/password I use to secure the https calls.
Should the username and password I use in the https header be a service account that the client (mobile app) and Java service knows or should it be the public user's username and password? The easiest option is just to use a service account but this means the mobile app will have those details built into it and distributed publically (albeit in compiled form).
Going the other way and using the user's username and password means I'll have to have the logon REST endpoint open and unsecure (which is fine I guess), but it just makes it slightly more fiddly.
Good question, and I would reckon you to use token based authentication and authorization scheme. Firstly you should have a login page where client logs in by providing username and password which is authenticated by calling some remote login service which maintains it's own user store or may use an existing one in your organization if any. Upon a successful authentication, the auth service should provide the client with a valid token, which then be refreshed time to time. The mobile or web client should pass in the token to the downstream microservices when a request is sent and this token should be sent inside the Authorization HTTP header.
Exposing the username and password while passing it around the network normally not considered as a good solution and that's where token becomes handy too. Token is the normal procedure that people use to secure rest endpoints. Yous rest endpoint should intercept each and every request comes at it, passes the token to the auth provider and verifies that. If the token is valid it will allow the request otherwise it should deny it.
Security is a pretty much larger topic and you have X.509 certificates other than tokens to encrypt the data sent across the wire over https and so forth. I suggest you to take a look at the spring security documentation since that will be a good starting point. Spring Security gives lots of hooks for developers which can be used out of the box with some sensible defaults. You can use JWT style tokens, Oauth tokens and spring security supports all these different forms too.

How to achieve login in java consuming a web service?

I have a project in java which utilize j_security_check and ldap for authentication. Now my employer want to change it to an authentication using a webservice provided . What they gave me is actually a link as shown below
"http://11.111.111.111/ADManager/ADlogin.asmx"
I am a total newbie to java and webservice.All I know is if we provide some data to a webservice it will give a response. my doubts are
Is it possible to create a login consuming that link they provided?
Should I ask them for more info?
Is it posible to replace the j_security_check and ldap already configured in my java project?
P.S : The one who assigned me this task doesn't seems to have much knowledge either.
The short answer is you can.
You need to do the following:
Each web resource is protected by a (servlet) filter. This filter checks each incoming request and validates the token which needs to be on the http header. If the token is valid then the request is served. If the token is invalid the filter is going to send back http 401 unauthorized. Then redirect to the loin page.
Login with rest service:
1) Create a custom login page with username/password field.
2) Create a rest web service, receives username/password. It will check the credentials against an external access management infrastructure like OpenAM.
3) First, call auth(username, password) rest api to get the auth token. If the given credentials are okay then just send back the auth cookie to the client with HTTP 200 response code.
4) Then, you can call protected rest apis. You need to send auth cookie with your request each time.
5) Servlet filter (or something similar) checks each incoming request and validates the token. If the token is valid then the request goes forward to the rest method, if not you need to generate an http 401/403 response.
I suggest you not to write your own authentication layer, please use an existing one, for example OpenAM.
This forum topic explain everything you.

Security Problem: For REST URLs and Static HTMLs

I have a design like that:
There is a core part runs Spring on it with REST.
There is another part which has a Tomcat Server and has just HTML files(not jsp or anything else.) So if I want to change a page at tomcat side there is no need to restart application also design and code part separated. Let's accept that I am listing users at my web side(tomcat side). Then my web side makes a GET request and response comes as JSON. PUT, DELETE and POST happens with same methodology.
I have 2 security problem at this point.
First, When a user wants to see an URL at server side how I will check authorization and authentication? And how can I limit an authorized person to get my web page with a too wget?
Second, How can I hide my REST URLs. For example if a user debugs my JavaScript code he/she will see that I am making a DELETE request to an URL with some parameters so he/she will try to do the same(or can make thousands of GET request to my core server if learns the URL)
Thanks for advices.
Firstly, why do you use Tomcat to serve static files ?
The approach I would take is this one:
use a static server to serve static files (apache, lighttpd, nginx).
This server will do authN and authZ (using an LDAP directory e.g. or any other suitable auth backend).
AuthN is done using scheme like Http Basic + SSL, Http Digest, WebID, ...
This is a solution to your 1st problem
Configure the static server to reverse proxy your app server and use the same auth rules.
URI are not "hidden", but they are no more accessible to anyone. Since the user is already authenticated to the static page, no auth should be necessary to request "rest uri".

Supplying credentials safely to a RESTFUL API

I've created a RESTful server app that sits and services requests at useful URLs such as www.site.com/get/someinfo. It's built in Spring.
However, these accesses are password protected. I'm now building a client app that will connect to this RESTful app and request data via a URL. How can I pass the credentials across? Currently, it just pops up the user/password box to the user, but I want the user to be able to type the username and password into a box on the client app, and have the client app give the credentials to the RESTful app when it requests data. The client is built using Struts.
Cheers
EDIT - I don't think I made the question clear enough. I'm already forcing HTTPS, my question is more, in-code, when I'm requesting data from www.site.com/get/someinfo, how do I pass my credentials alongside making the request?
You more or less have 3 choices:
HTTP Auth
Roll your own protocol, ideally HMAC challenge/response based
OAuth
OAuth is currently susceptible to a variation of a phishing attack, one that is largely undetectable to the target. As such I wouldn't recommend it until the protocol is modified.
OAuth should also be a lesson about how difficult it is to design secure protocols, and so I'm hesitant to reccomend the roll your own route.
That leaves HTTP auth, which is likely best if you can use it.
All that said, almost everything on the internet uses form based authentication, and many don't even bother with https for transport level security, so perhaps simply sending the password text in the clear is "good enough" for your purposes. Even still I'd encourage using https, as that at least reduces the dangers to a man in the middle attack.
If you can add HTTP headers to your requests you can just add the Authorization header:
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
where you're using basic authentication and the QWxhZGRpbjpvcGVuIHNlc2FtZQ== bit is "username:password" base64 encoded (without the quotes). RFC 2617
Well, https has nothing to do with authentication, it's just transport-level encryption.
if you interact with an HTTP api, be it that it's https or not, and the dialog box pops up, it means its using HTTP authentication, either basic or digest. If your client instantiates an http client to read data from those "services", then you can pass those credentials when you instantiate the object.
If you use client-side script, XmlHttpRequest supports http authentication as well.
So in terms of code, how you pass the credentials to the RESTful services is dependent on the http client you're using (the object you instantiate to retrieve the data). You can simply collect such a username / password yourself from the client, and use it to call the other service.
look at existing solutions. In this case, oauth

Categories