Authenticating with Rest Service in Java/Groovy - java

Goal
I am a newbie on Groovy and Drupal 7. My project is to create a node on Drupal 7 via REstfull services using Groovy language. I have setup Rest Server on Drupal 7 and checked with mozilla plugin Poster with sending some authentication and creation Post requests. It works perfectly fine.
Problem
However problem comes while establishing same process with Groovy/Java. I used HttpBuilder that basically works on top of Apache HttpClient.
In order to authenticate I need to send username/password to a /user/login URI. Next time I need to do something, such as a POST request ( e.g. create a Drupal node ), I need to use a different URI e.g. /node and somehow pass that auth data (session_name and a session_id that Drupal sends back the first time) with that POST request => that currently does not seem to work:
401 Unauthorized: Access denied for user 42 "trader785876"
I Tried
to copy cookies from the first (auth) request to the second
to extract cookies from the first request, and set them in a header of the second
to extract cookies from the first request, and set them in the POST parameters of the second, etc..

have you tried authenticating using the method here http://groovy.codehaus.org/modules/http-builder/doc/auth.html ?
...
authClient.auth.basic 'myUsername', 'myPassword'
...

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

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.

Read POST form in Angular submitted by external websites

I am developing a website with Java for the backend and Angular for frontend. There is a situation when some external websites may send data to my website using POST form. For instance,
▼ General
Request URL: https://myangularwebsite/
Request Method: POST
...
▼ Request Headers
Content-Type: application/x-www-form-urlencoded
Host: myangularwebsite
Origin: https://externalwebsite
Referer: https://externalwebsite/send.form?id=0
...
▼ Form data
ID: 0000000
TIME: 2017.06.04 11:53:58
SIGNATURE: ...geirgmGKFGJWR...
...
Now, I need to capture the form in Angular somehow, send/redirect it to the backend to validate the signature and return the answer back to Angular to proceed working with this website.
I tried posting to my website to test how it might work using Postman, but get Cannot POST /.
I know how to work with GET and URL query parameters in Angular but I think I need to process a POST request based on headers I see with Chrome DevTools 'Network' section when coming from externalwebsite to myangularwebsite.
Should I dedicate a route in the backend and expose it, for example, .../api/external in my backend and tell these websites to use this link instead of directly posting to my Angular website's homepage?
I have already read another question ( How to read form post data in Angular 2 typescript? ) which is somewhat similar but I do not think using PHP is the right way for me as the website I am developing already has an older version written in PHP.
The answer at the link you provided is correct: you cannot do it in just Javascript, you have to use some server-side code. They mention PHP as an example, but any server-side component will do, and as you have Java at your backend, let it be Java.
So, when an HTTP request comes from an external site, you have to use a server-side component to handle it. But there are some options.
If this request is made using your user browser (so it is something like a redirect, but using a POST method), then you can do the following: catch that request at your backend, output some javascript with some data to the user's browser and process that data in your Angular code. Or this could be a redirection to your main Angular entry point, it is up to you.
If this request is made by some other means (for example, this is a server-to-server request made with with curl like a notification from a Credit Card processing), with no browser involved, then you don't need to have any Javascript (Angular or whatever it could be) as they are needed for browser only. In this case you just handle the request at your server-side.
In both cases, it seems plausible to dedicate some special endpoint for handling (or landing) such externally-originated requests.

Can we read cookies using core-java that has been written using .NET MVC code?

Can we read cookies using core-java, that has been written using .NET MVC code? I have not find any help how to read cookies using core java code?
More Background Details -
Actually we have a java desktop application and we are planning to launch that java desktop application using JWS and that is working absolutely fine.
The issue is -- we ask some user related information from user on web page and launch java desktop application using JWS. Now we would like to have that information provided by user on web page in our java application.
We have write that information into cookies and how can we read that information from java code ?
Yes, you can receive cookies that have been set by another application (as long as the path value in the cookie matches). Cookies are part of the HTTP protocol and it does not matter how thay were defined. The client sends them in future requests depending on the URL path.
To access cookies in Java, have a look at getCookies() in HttpServletRequest.
update
The cookies set by your web-application that launches the Java client will have been set in the context of the browser client. Cookies are added to a HTTP response and cached by the client receiving them.
In the case that you describe you cannot access the same server-session from the Java client without trickery.
The solution I would use is to generate a unique ID in the web-app that is passed as argument to the Java client which can in turn request the values needed from the other session using a fetch of a URL using the generated ID as parameter. (This in essence connects the two HTTP sessions as being part of the same user process.)
For instance you could use a HttpURLConnection and a URL like <web-app>/data?id=<ID> to fetch/download the values as XML from your web application.
Core-java? Then try java.net.*:
A cookie is just a header line with "Set-Cookie: " before the URL content.
http://www.hccp.org/java-net-cookie-how-to.html

createLoginURL creates invalid request URL in GAE

I get the following error from following piece of code. I am trying to login to Google sites service through GAE apps.
"The page you requested is invalid. "
String authenticationUrl = userService.isUserLoggedIn()
? userService.createLogoutURL(MainServlet.MAIN_URL)
: userService.createLoginURL(MainServlet.MAIN_URL+"?close=1");
googleData.setAuthenticationUrl(authenticationUrl);
The complete url for login
https://www.google.com/a/example.com/ServiceLogin?service=ah&passive=true&continue=http://myapp.appspot.com/_ah/login?continue=http://myapp.appspot.com/main%3Fclose%3D1&ltmpl=ga&ahname=Myapp+Google+Sites&sig=7cbc9f7c9e6ca443ed49f7ce9465e775
I think that you may have misunderstood the use and purpose of createLoginURL. This method is intended to provide a URL that allows someone to log in to your application and your application alone. It does not provide a means to log in to other Google services such as Sites.
It is possible to have your application log on to and access Sites or any other secured web application, but Google AppEngine does not provide a canned means of doing so. You will need to write the code to do it yourself.
Generally, what will happen is that you will request a URL and the response will have an HTTP status code of 302 with the URL of the login page located in the Location header field. You would then send a request to that page which should come back with a 200 response and somewhere inside the body of the response would be a username and password field that you would need to provide and POST back. If the credentials were valid, the server might then return an authentication cookie which you would pass on each subsequent request.
If you are versed at all in Python, you can see an example of how this works in some code from my AppEngine MVC framework project. Look at this file:
http://code.google.com/p/gae-mvc-engine/source/browse/trunk/MVCTests.py and check out the ActiontestCase.run_action method. It handles making a request to an AppEngine application that requires authentication. It is not yet terribly-well commented -- and for that I aplogize -- but I hope that it will provide a useful example. If, indeed, I have understood the nature of your problem correctly.

Categories