Get parameter from curl command in REST web serivce - java

I want to get username and password from curl command in REST web service using Plain Java Class.
My java class is
#GET
public Response check(String username,String password)
{
authenticate.....
}
I use Netbean IDE with jersey framework. I created web service in POJO java class.
Do anyone know how to get username and password in web service java class?
My curl command is like :
curl -u username:password http://localhost:8080/project/resources

If this is building on the code from your question here, then getting the username is a matter of adding a new property to the resource annotated with #Context of type javax.ws.rs.core.SecurityContext (let's call it securityContext). Then you can access the username like this:
String username = securityContext.getUserPrincipal().getName();
The password is not available through this API though. This approach will only work if the user has already been authenticated by the container. To get at the password, the property would need to be of type javax.ws.rs.core.HttpHeaders (let's call it httpHeaders). Using this object, you'd have to call
String authHeader = httpHeaders.getRequestHeader("Authorization").get(0);
Using the curl command you listed would default to using HTTP basic authentication, giving you the username and password in a base64 encoded string consisting of username:password. To get those values you would need to parse, base64 decode, and parse again. The curl command you provided would add the following header to the request:
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
In the code snippet I provided before, authHeader would have the value
Basic dXNlcm5hbWU6cGFzc3dvc.mQ=
Getting the username and password would be like so
String[] pair = base64decode(authHeader.split(" ")[1]).split(":");
In that code substitute base64decode with your base64 decoding library of choice. After this call the username would be in pair[0] and the password would be in pair[1]. Note that all of this code is lacking null and boundary checks as well as exception handling that production code would require. It also only supports basic authentication. If you needed to support other authentication methods you would need to handle whatever decoding and parsing that method requires.
It seems to me that JAX-RS is geared more towards using the SecurityContext approach and relying on the container to authenticate the request, so understand all of the caveats with using the HttpHeaders approach.

Related

Creating Issue in Jira using REST API

I have to create a issue in jira with POST method using REST API in java but the problem is I am having SSO (Single sign-on) authentication in my system.When I am trying to create ,I am getting 401 (Unauthorized) error.I already have administrator role in project on jira . But I am able to create the issue using POSTMAN(getting 201 response code).I can't understand how POSTMAN is able to do that.
Please provide how to do authorization if I have system with SSO authentication.I can't create jira API token as it is restricted to me.
Creating a new "JIRA issue" using REST API in java
I am taking help from this link but here its doing basic authentication.
You have to use Basic Authentication or OAuth to access the rest api.
public static string GetEncodedCredentials(string userid, string password)
{
string mergedCredentials = string.Format("{0}:{1}", userid, password);
byte[] byteCredentials = UTF8Encoding.UTF8.GetBytes(mergedCredentials);
return Convert.ToBase64String(byteCredentials);
}
Call this method with userid as your username/email, and password using the same password you use in POSTMAN. It is weird that you can do it on POSTMAN and not in your application because I'm assuming you have used this in POSTMAN. This is C# code however so you might need to find the java code for this.
If needed search: Basic Authentication Java
Then you will find it.

Kubernetes Java API does not use username password supplied

This is in regards to version 0.2 of the Kubernetes Java client. I'm guessing the way to use basic authentication in the Java API is to do this
ApiClient client = Config.fromUserPassword( "https://....:6443", "user", "password", false );
Configuration.setDefaultApiClient( client );
CoreV1Api api = new CoreV1Api();
// Make api call like
api.listNode(...)
However the above code always returns 403 Forbidden. From the response message, it doesn't look like the user/pass is being used in the request.
{"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"nodes is forbidden: User \"system:anonymous\" cannot list nodes at the cluster scope","reason":"Forbidden","details":{"kind":"nodes"},"code":403}
I also debugged through the code a bit and I may be answering my own question but it looks like in CoreV1Api's methods, it never add basic auth as an authentication method and only uses BearerToken. Is basic auth supported or should I be using another API class?
Many kubernetes clusters do not set up basic auth, only bearer token auth. Are you sure your cluster configured basic authentication?
https://kubernetes.io/docs/admin/authentication/#static-password-file
Answering my own question but it doesn't look like the current version of the client actually executes the user/pass authentication. BearerToken is working however.
The java client ignores the HttpBasicAuth object, but if you use the ApiKeyAuth object and set the key prefix to "Basic" and the API key to the base64 encoded credentials, it will work.
For example:
String credentials= new String(Base64.getEncoder().encode("user:password".getBytes()));
ApiClient defaultClient = Configuration.getDefaultApiClient();
defaultClient.setBasePath("https://256.256.256.256");
ApiKeyAuth fakeBearerToken = (ApiKeyAuth) defaultClient.getAuthentication("BearerToken");
fakeBearerToken.setApiKey(credentials);
fakeBearerToken.setApiKeyPrefix("Basic");
This works because the kubernetes client will simply concatenate the API key prefix with the prefix, and put the result in the "Authorization" header.

Making my own Kerberos Authentication Ticket

I am using the Java class org.apache.hadoop.security.
authentication.server.AuthenticationFilter from Apache
Hadoop 2.5.0 as a filter in front of a Tomcat 6 Servlet we
wish to add Kerberos authentication to.
I am attempting to write some test cases against this filter
so that we have a better understanding of how it
works and what it does.
In order for the filter to authenticate a user, it is reading the
'Authorization' header of the HTTP request,
expecting the value to contain 'Negotiate '
My understanding of how Kerberos works leads me to believe that I
should be able to write code while creating my
HTTP request that looks something like this:
// normally the server principal keytab is not available from the client side,
// but for the purpose of making test cases I see no problem with sharing the keytab
// between the client side and the server side
javax.security.auth.kerberos.Keytab kt = KeyTab.getInstance("keytab");
KerberosKey keys[] = kt.getKeys("HTTP/voltage-pp-0000.albert.int#ALBERTS.INT");
SomeTokenType token = new SomeTokenType();
<code to set token parameters>
// my understanding of Kerberos is that the only cyphertext key
// needed on this token
// is one of the server principal's keys from the Keytab file
// (which does contain ~5
// keys of different sizes and types, I've checked)
EncryptedTokenType etoken = <encrypt token with a key from keys>
byte[] array = etoken.getBytes();
httprequest.addHeader("Authorization","Negotiate " + new Base64(0).encode(array));
So, questions here:
What is the Java Class that embodies the Kerberos Auth Token sent
in "Authorization Negotiate"?
What fields of that auth token have to be set to what values?
What is the encryption algorithm used to encrypt the auth token
against the keytab key?
What is the best keytab key to use?
What is the mechanism for byte-serializing the auth token, once
encrypted?
You are correct in that it is possible to "forge" a ticket in this manner. However, I know of no standard kerberos API that would do this.
You'll essentially need to reverse engineer the entire kerberos protocol to
create a service ticket based on the keytab. The service ticket format is
documented here
https://www.ietf.org/rfc/rfc4120.txt
You can use any of the keys in the keytab to encyrpt the service ticket. Once
you have the service ticket, you'll need to implement this RFC to create the
negotiation header.
https://www.rfc-editor.org/rfc/rfc4559
Generally, it's a lot simpler to just get a keytab for a client principal and use that and kinit to get a service ticket for testing. Your approach could work
and there is probably hacker code out there somewhere to implement it, but it's
an extremely non-standard way to do testing in a kerberos environment.

How to set username and password using RESTEasy client builder?

I have a url which needs authentication (like a browser pop up appears asking username and password.)
Generally, we can use the following format to achieve this:
http://username:password#url.com
Using RESTEasy client builder
Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://url.com");
How to achieve it without having to construct the http://username:password#url.com myself? I've seen if there are any methods which I could use to set it with no luck. Also I'm not sure how these credentials are passed, headers, cookies etc..
Looks like Basic Authentication. If that's the case, you just need to set the Authorization header to Basic base64encode(username:password).
For example:
String credentials = "username:password"
String base64encoded = Base64.getEncoder().encodeToString(credentials.getBytes());
Response response = target.request()
.header(HttpHeaders.AUTHORIZATION, "Basic " + base64encoded)....
The Base64 class I used is from Java 8. If you're not using Java 8, there are libraries that have Base64 support. Prior to Java 8, there's a com.sun internal Base64 class, but it's advised not to use those.
If you just want to run a quick test (and don't have Java 8 or don't want to go looking for a lib), you can go to this site and just type in your username:password and encode it, then just copy and paste to your code.
For example:
base64encode(username:password) == dXNlcm5hbWU6cGFzc3dvcmQ=

passing parameter in http header with REST service

Right now i'm using java to build rest service, and trying to use spring security to securing my service.
I have a few parameter that server needs to process the service (ex: application ID, username, password, consumer ID) . For username and password, I put in on http header "authorization", encoded with base64. Is there a way to put another parameters above (ex. AppID, consID) into http header?
Some sample of code would help, thanks.
You can put whatever you want in a whatever header you like. You can create custom headers. So you can have a App-Id header where you pass the appId. Alternatively you can pass those as parameters in the URL. That way you'll get rid of the option that some (stupid) proxy trims your headers.
Btw, I would suggest not to send the password, unless you are using https. Generally, I can recommend two similar scenarios:
use OAuth - let the user grant access to the API client via the OAuth dance. The client ends up with a token which it uses on each request.
use a custom, simplified token scheme - login once (with username and password, over https), and send a short-lived token in response. Each subsequent request can be made over an unsecured connection by providing the token, and (optionally) some HMAC of the request parameters, using a consumer secret as a key, so that you can verify the client is legit.

Categories