I'm trying to extract information from an URL using my Java code. But the URL has a pop-up authentication scheme. How would I know the authentication scheme used? I have the credentials for it.
A browser typically shows an authentication "popup" when the server responds to an HTTP request with a "401 Unauthorized" response message. The response header includes a "WWW-Authentication" header which tells you the authentication scheme to use (among other things).
There are various ways to deal with this in a Java application, depending on how you are attempting to fetch the web resource associated with the URL. For instance, if you are using HttpUrlConnection, you can extract the "WWW-Authentication" header, parse it, and extract the authentication scheme.
Normally the authentication is based on HTTP. There are several techniques to use (HTTP basic authentication Kerberos NTLM and so on) Each of this technologies applies additional information into HTTP header. So the authentification is not URL based but HTTP Header based.
Please give us more information about your problem, to help you
Related
Issue description:
Assuming I have one web application(Java+Saml2.0) who has a Sign in button to call ADFS(an identity provider) to authenticate.
It's using Javascript(Ajax has same issue) to call one endpoint of ADFS 2016. Since the request if sending from Javascript/Ajax, the browser would throw CORS error. (The ADFS2016 server side doesn't support modifying CORS header/response/origins)
And I heard from someone that one way to avoid the CORS error is to use redirect instead of using Ajax/Javascript to directly call one URL/endpoint.
Can someone give some insights for this situation? How can I modify my code to do such redirect without causing CORS?
PS: I don't want to lower browser security level to bypass CORS and I also don't want to upgrade to ADFS2019 though it supports customizing CORS origins.
Im not sure if you are trying to achieve some special case by using javascript like this. But normally when authenticating a using using SAML you issue a HTTP redirect from the backend as a response to the user clicking the login button.
To understand it all it is important to first understand the SAML authentication flow as I go through in this post.
The user triggers authentication by navigating to a protected page or in this case clicking a button
The application, or Service Provider(SP) in SAML speak, builds a SAML authentication request and sends it to the IdP by adding it as a URL parameter and sending a backend HTTP Redirect to the user. The authentication request can also be sent using HTTP POST explained here
The IdP authenticates the user in the way it sees fit.
The IdP send the user back to the SP using HTTP POST together with a SAML Response and SAML Assertion. This contain the result of the authentication as well as any extra information about the user.
The SP, you application, interprets the SAML Response and lets the user through to the protected application.
This redirect contains a encoded SAML authentication request in the URL that is parsed by ADFS to understand where the authentication request is coming from and how authenticates the user.
There are several libraries and frameworks for managing SAML trafic including the sending the messages using redirect or other methods. If you are using Java, Spring has SAML management as a part of their security framework. Another library is the PAC4J which provides a SAML module
While both of these work well for the most general use case of building a SP to integrate with a existing IdP, if you need to do more custom cases or build a IdP on your own OpenSAML can be an alternative.
OpenSAML is a more low level library for handling SAML. In this write up on my blog I show how to build and send a SAML authentication request using redirect from OpenSAML.
Below is a simplifies example for using OpenSAML. For a full example see the sample code here and here
The authentication request is build using OpenSAML
AuthnRequest authnRequest = OpenSAMLUtils.buildSAMLObject(AuthnRequest.class);
authnRequest.setIssueInstant(Instant.now());
authnRequest.setDestination(IPD_SSO_DESTINATION);
authnRequest.setProtocolBinding(SAMLConstants.SAML2_ARTIFACT_BINDING_URI);
authnRequest.setAssertionConsumerServiceURL(SP_ASSERTION_CONSUMER_SERVICE_URL);
authnRequest.setID(RANDOM_ID);
authnRequest.setIssuer(ISSUER);
authnRequest.setNameIDPolicy(NAME_ID_POLICY);
Add the message to a message context and set set destination
MessageContext context = new MessageContext();
context.setMessage(authnRequest);
SAMLPeerEntityContext peerEntityContext = context.getSubcontext(SAMLPeerEntityContext.class, true);
SAMLEndpointContext endpointContext = peerEntityContext.getSubcontext(SAMLEndpointContext.class, true);
endpointContext.setEndpoint(MESSAGE_RECEIVER_ENDPOINT);
Send the message using HTTP Redirect
HTTPRedirectDeflateEncoder encoder = new HTTPRedirectDeflateEncoder();
encoder.setMessageContext(context);
encoder.setHttpServletResponse(httpServletResponse);
encoder.initialize();
encoder.encode();
For those who want to dig in deeper I have have written a book on working with OpenSAML, A Guide to OpenSAML, as well as book on SAML as a framework, SAML 2.0: Designing secure identity federation.
I also have a ton resources on my blog
Where can I find the basic HTTP authentication credentials (username and password) in the incoming request to my server?
Is it somewhere in the Request object, or is there some other way to get them?
thanks
When a browser sends HTTP Basic authentication info, it basically sends an HTTP Header named Authorization
with a value of
Basic somethinghere.
The part after Basic is really just Base64.encode("${username}:${password}")
Check out this basic description of the procedure.
Here is a SO answer that describes how you can easily obtain the authentication credentials from the HTTP Header.
When a html page makes a call to a rest webservice, how can the service credentials be sent in the request?
The username and pwd needed by the service can be sent in the request itself by using (usename:pwd#service.com) notation, but that would not be wise sending in the creds in the request itself.
Any other ways to solve this problem?
If it uses BASIC authentication, it is sent along the request as a header (in clear). Have a look at:
http://en.wikipedia.org/wiki/Basic_access_authentication
This can be hardened by using a secure protocol (https), with which you encode your request (basic authentication included).
http://en.wikipedia.org/wiki/HTTP_Secure
This requires additional configuration on the server-side
HTTP specification says;
HTTP access authentication is described in "HTTP Authentication:
Basic and Digest Access Authentication" [43]. If a request is
authenticated and a realm specified, the same credentials SHOULD
be valid for all other requests within this realm (assuming that
the authentication scheme itself does not require otherwise, such
as credentials that vary according to a challenge value or using
synchronized clocks).
I don't really understand what this means, but here is my scenario is there anything against HTTP specs here? I use Java Rest service
Client sends username:password using HTTP Authorization header using HTTP Basic
Server sends back a token
Now client sends a custom authorization token instead of password for further requests still in the HTTP authorization header still using HTTP Basic username:token
Now this does not feel right since what I am really doing with the auth token is NOT an actual HTTP Basic authorization. Also usage of the very same header is inconsistent between requests.
But on the other hand I do not want create yet another custom header for the token exchange. Because its hard to base64 encode them with test tools when you use a custom header. And still inconsistent headers between requests.
Note: these requests refers to different endpoints
What do you advice?
If you do that, since you are using the same headers, aren't you going to need server side logic to differentiate when the login is the actual login, as opposed to your token? At the end of the day, HTTP Authorization is already a token (only a simple encoded version of the username/password string), so in all cases you are receiving a token, now you have to decode it, decide if it's one of your session tokens, or if it's a username/password, and therefore check against two sources of "good tokens".
I would advice against this, but not because you're breaking standards, it just feels convoluted.
Why do you need to change username/password to a token on the first place? Are you redirecting to an endpoint where you no longer require HTTP Basic Auth?
I have created a web-service that uses basic authentication in JDeveloper 11.1.1.4.
When i test my application using a client application is runs correctly so i know that the authentication mechanism has no problems.
How can i pass authentication info into the HTTP Analyzer by right clicking on Webservices and selecting Test Web Service?
I have tried to pass credentials through SOAP Headers > :WS-Security:Header like below but is not working
I have also tried to pass authentication through Credentials option like shown below
In both cases i get this error 500 HTTP Analyzer Server Error The server sent HTTP status code 401: Unauthorized: .....
How can i get through this?
Thanks
UPDATE
I also tried to pass Authentication option to Request HTTP Headers but get the error message :
Error 403--Forbidden
From RFC 2068 Hypertext Transfer Protocol -- HTTP/1.1:
10.4.4 403 Forbidden
The server understood the request, but is refusing to fulfill it. Authorization will not help and the request SHOULD NOT be repeated. If the request method was not HEAD and the server wishes to make public why the request has not been fulfilled, it SHOULD describe the reason for the refusal in the entity. This status code is commonly used when the server does not wish to reveal exactly why the request has been refused, or when no other response is applicable.
If you're using Basic authentication, all you need is set request header Authorization. Value of this header: prefix Basic, one space, Base64 encoded string with usrname:password, so your header for Aladin:sesam open should be like this: Basic QWxhZGluOnNlc2FtIG9wZW4=.
On screenshot i see section Request HTTP headers, add Authorization header to it.
I am aware that this is an old post , but this may benefit those who run into this issue.
I am using Jdeveloper 11.1.2. I have secured the JAX-RPC web service (created by exposing PL/SQL poackage) using basic authentication. I attached the security policy: "Auth.xml" using the wizard.
I was able to test this using HTTP Analyzer. I just passed the user credentials in the SOAP Headers as shown below and it worked fine for me.(I also passed invalid creds and no creds to see if the security works as expected.)
Hope this helps !!!