How to use Basic HTTP Auth with REST webservice (Java+Jersey)? - rest

I am a newbie to REST webservice and have just created my first webservice.
In my service the user can create profile via simple form giving his desired Username and password.
Now how to check user credentials when the user logs-in ??
I mean i have a simple form which validates user has logged in but how to validate user when he is to perform various profile operation of add/update/delete ??
For example:
In FB you sign-in and it stores a cookie which has your credentials and when you perform operations like "Post Status",message a friend...etc... it doesn't ask for your credentials anymore because it has a cookie in which your credentials are there and it just uses that cookie...
But in REST we dont use cookie ,so the next option is HTTP headers.
And i want to know how to send and recieve user credentials via HTTP header .i.e
Basic HTTP Auth

Client Side
To send the credentials to the API you use the HTTP Authorization header, specifying the credentials in a form of Basic username:password. The username:password String has to be encoded using an encoding scheme called Base64. So an example header could look something like this:
Authorization: Basic d2lraTpwZWRpYQ==
As the rest specification states that the client-server communication should be stateless, you have to include the header with the credentials on every request. Normally you will use a session cookie on the client side to identify the user so that he does not have to enter his credentials on every request.
Server Side
To check the credentials inside your Jersey REST Service, you need to catch and intercept all the incoming requests. Jersey provides a concept called ContainerRequestFilters to do this. For example if you use Tomcat you could add filters of this type inside your servlet definition in your web.xml like this:
<init-param>
<param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name>
<param-value>your.package.BasicAuthFilter</param-value>
</init-param>
The referenced class BasicAuthFilter needs to implement Jerseys ContainerRequestFilter interface and override the public ContainerRequest filter(ContainerRequest request) method. Inside the method you will basically do the following:
fetch the Base64 encoded credentials from the Authorization header of the request
decode them (i.e. using javax.xml.bind.DatatypeConverter.parseBase64Binary())
use your UserDao (or other datasource provider) to check if the credentials are valid
return status code 401 Unauthorized if the validation fails (i.e. throw new WebApplicationException(Status.UNAUTHORIZED))
if the credentials are valid, simply return the request in order to delegate it to the Jersey Resource that is responsible for handling it
You can find a very good example in this blog post.

Related

Login and Register Requests in API's

I'm currently working on a small project where I need to create login and register functionalities for a web application. A colleague of mine had the opinion, that a login request should be done with a post request where the user credentials are stored in the body of the request. I was used to do login requests with a Get-Request where the login credentials are stored in the authentication header (e.g. with Basic-Authentication). So I've read some threads and most of them say, that a POST-Request is better than a GET-Request for login. But also some threads said, that it is better to store user credentials in a request header instead of the body. In case the credentials are stored in the header I don't understand why a GET-Request should be better than a POST-Request.
So I was wondering what you think. What are the benefits/disadvantages of Login with POST-Request and User Credentials stored in the Request-Body compared to storing them in the header via Base-Authentication (encrypted with Base64).
Thanks for any opinions.
A POST is preferable for login request, because the authentication information will be sent in the HTTP messages body rather than the URL. Although it will still be sent plain text, unless you're encrypting via HTTPS.
GET method data is sent to the server followed by the URL which will be seen to everyone.
Both GET and POST method are used to transfer data from client to server in HTTP protocol but main difference between POST and GET method is that GET carries request parameter appended in URL string, while POST carries request parameter in message body which makes it more secure way of transferring data from client to server in HTTP protocol.

How to pass a parameter from a URL to an auth0 hook or rule for a machine-to-machine JWT?

I'd like to add a custom claim to a JSON web token generated by auth0 for machine-to-machine authentication. Like
color:blue
but I want to make blue a parameter I can pass with my request to auth0 for the token.
I ask for the token like this:
POST https://mydomain.eu.auth0.com/oauth/token
with a request body
{
"client_id":"myID",
"client_secret":"mySecret",
"audience" : "https://mydomain.eu.auth0.com/api/v2/",
"grant_type" :"client_credentials"
}
I see from How can I add claims to a JWT assigned with auth0 for a machine-to-machine application type? how to use a hook or rule to add a fixed claim, but I want to add a variable something like
?color=blue
to my request URL or request body and have that accessible from my hook code to be added as a claim.
Is that possible, please? How?
When you process an authorization request with a custom rule you get access to at least a part of the request properties by the request object of the context function argument. I tried it out but unfortunately the fields of the request object seem to be limited to only a few fields of the original request.
If your user information resides in Auth0 you could check out writing preferences into the user's metadata by using the Auth0 metadata API. This works well. But you will be able to only set metadata after the user has logged in, not before. Also you'll have to deal with two different Auth0 API endpoints now.

Keycloak as IDP with custom authenticator cant read http POST params login_hint

I have a saml Keycloak client which contains an Authentication Flow Override to a custom keycloak SPI authenticator built in java and deployed in the keycloak env. The authenticator is pretty simple, it displays a username field and takes that username, does a 3rd party check, then returns a verdict (go/nogo, yes/no, etc.)
I have a SAML SP sending a request to this keycloak client (as an IDP). The SP request has a LoginHint. When the Custom Authenticator receives this request in the authenticate method, it cannot retrieve the HTTP Post parameters because there are none.
When user enters their information into the custom authenticators form and clicks submit, and when the action method takes over, the new HTTP POST params are there.
I need to retrieve the loginHint in the authenticate method from the incoming SP SAML request.
anyone know how to do this? i cant read in the login_hint for the life of me.
login_hint and variations thereof belong to OpenID Connect (OIDC) implementations. In SAML you have to use RelayState (recommended) or an authentication request extension.

Access Restful Service which is OWASP CSRFGuard protected from Different Domain

My application has been built using SPRING MVC and I have exposed few Restful URIs. (Working Fine)
e.g - http://example.org/alert/alerts //get list of Alerts for the logged in user.
I have configured the application for Cross Site Request Forgery (CSRF) using OWASP CSRFGuard by following the link - (Working Fine) https://www.owasp.org/index.php/CSRFGuard_3_Configuration#Overview
The Restful services is currently been consumed by the same application's UI without having any issues. (Working Fine)
e.g - A data Grid which is part of the same WebApp is displaying list of Alerts by calling this Restful service (AJAX request)
Issue: When I try to access the same Restful services from a different domain/ Chrome Rest Client, it's doesn't return any data except for 302.
If I set The "unprotected pages" property in csrfguard.properties for the restful URIs, I am able to access the Restful service from RestClient/different domain.
Please suggest if I need to do any other configuration so that the same Restful services which are protected by CSRF can be accessed from a different domain/Chrome rest Client.
1.if you are generating CSRF Token at server side then
provide one get request inside that request validate session and send the created CSRF Token as hidden to client, now remaining request should be POST,PATCH,PUT or DELETE which are getting CSRF Token in every request header.
2. if you are generating CSRF Token at client side then from first request which is authentication or authorization get the value of Token and compare it with every request in your custom filter.

how to obtain WindowsIdentity from Negotiate HTTP header value

I am working on securing some REST services and I want to support Windows Authentication. When the HTTP client has sent no authentication credentials my service responds with an Unauthorized response and a WWAuthenticate value of 'Negotiate'. This prompts the browser to pop a username and password dialog box. I enter my windows credentials and the request comes back to my service. This time there is an Authorization header with a Negotiate scheme that has a value which I assume is some form of my windows identity. How can I take this header value and translate it into a WindowsIdentity object (or some other object that lets me know who the authenticated user is)?
Edit: My logic is actually occurring in a http handler higher up in the webapi pipeline.
If you are using WebAPI2 you can do
request.GetRequestContext().Principal.Identity
otherwise you can dig the principle out of the Properties dictionary on the request message.
The Controller has a User property which can be used to get the name:
User.Identity.Name
User.identity is a System.Security.Principal.Identity.