Cross domain issues while accessing ASP.NET Web API Restful services: - asp.net-mvc

Situation is as per below:
Services are hosted at suppose example_services.com. These services are ASP.NET Web API Restful services.
Windows authentication(NTLM) is enabled on this.
Client is hosted at suppose example_client.com. This is in MVC ASP.NET.
Windows authentication(NTLM) is enabled on this.
ASP.NET impersonation is also enabled on this.
Now client wants to access all services offered by example_services.com by Windows Authentication.
Hence here both are hosted on different domains(cross domain).
Windows authentication is working properly on client side, but we are getting 401(Access Denied Error) while accessing services from example_services.com in example_client.com.
So I have following questions:
How to pass credentials of an "logged on users" to service.
Is it possible to bypass "windows authentication windows pop" every time client tries to access any services.

First of all you need to enable Cross-Origin Requests in your Web API. Follow the instruction from following link Enabling Cross-Origin Requests
Then you have to pass credentials while making any request to your web API from your client. See the information for passing credentials from following link Passing Credentials in Cross-Origin Requests
Hope this helps.
Regards
Arkadas

Now client wants to access all services offered by
example_services.com by Windows Authentication. Hence here both are
hosted on different domains(cross domain).
First, you are going to need to enable Cross Origin Resource Sharing. If you are unfamiliar with this concept, I refer you to RFC6454
Enabling CORS in WebAPI is really, really easy (it is in most web frameworks, actually).
You're going to want to reference System.Web.Cors in your WebAPI Project. Then, to enable controller-based sharing, decorate your ApiController with the following attribute
using System.Web.Http;
namespace Example.WebAPI.Controllers
{
[EnableCors(origins:"example_client.com", headers:"*",methods:"*",SupportsCredentials=true)]
public class ExampleController : ApiController
{
//The kickers in that attribute are the "origins" and "SupportsCredentials"
//Note that SupportsCredentials is not supported with wildcard origins
}
}
What this does is set the [Access-Control-Allow-Origin] response header based on a valid [Origin] request header being set. Doing this should open up your WebAPI to your calling client.
As you might imagine, the "methods" property of the attribute allows you to lock down specific HttpVerbs to access.
How to pass credentials of an "logged on users" to service.
There is also a "SupportsCredentials" property on that attribute that would allow you to pass credentials with a request.
If you're trying to use NTLM Authentication, setting the "SupportsCredentials" property of the EnableCors attribute to true. This will enable the Access-Control-Allow-Credentials HTTPHeader. Your credentials will not be sent down automagically, but you can send credentials by setting withCredentials: true on your XHR.
If your client is comfortable with basic auth, you should be able to do that in this way:
$.ajax({
url: url,
data: {},
username: "corp.domain\corp.username"
password: "69iNgCh1pmunk5"
xhrFields: {
withCredentials: true
}
});
CORS and Windows Authentication
More About Origin, Access-Control-Allow-Origin, and CORS
Enabling Cross Origin Requests in Web API
Is it possible to bypass "windows authentication windows pop" every
time client tries to access any services.
You're likely looking for a Single Sign-On solution. They are non-trivial as well.
[Edit]
withCredentials and basicAuth properties on a CORS Enabled endpoint should bypass the challenge popup. I initially interpreted that question wrong.

Related

How to disable authentication requirement for apiDiscovery feature

Is there any way to disable the authentication requirement for accessing the API Documentation endpoints provided by the apiDiscovery-1.0 feature?
I have the apiDiscovery-1.0 feature enabled on Liberty 16.0.0.4.
I am able to see the swagger documents when I access /ibm/api/explorer as expected, but I am required to authenticate.
I am only able to authenticate by using credentials defined in a basicRegistry element within my server.xml. However, I want to eliminate this basicRegistry from my server configuration.
You can do that in the latest Beta (https://developer.ibm.com/wasdev/downloads/liberty-profile-beta/)
With that driver, you only need apiDiscovery-1.0 (SSL is optional).
The default address for the public endpoint is http://host:port/api/explorer
You can change the "/api" portion by using the publicURL attribute in the apiDiscovery element in server.xml, for example:
<apiDiscovery publicURL="/myPublicAPI" />
This is targeted for Liberty's next release, 17.0.0.1.
Please note that in the public endpoint, internal endpoints (such as JMX, Batch, etc) are not displayed - only your deployed applications.
For the internal endpoints, you can use /ibm/api/explorer (which remains requiring SSL and authentication).
I believe you can't remove the requirement for authentication for apiDiscovery for security reasons.
I doubt this helps but, you shouldn't "only be able to authenticate using credentials defined in a basicRegistry element within my server.xml" and instead any supported authentication mechanics should work like quickStartSecurity, LDAP, etc (and they can be set in any configuration file that is read by the server, not just server.xml). For example, you should be able to use quickStartSecurity in wlp/usr/shared/config to apply an Admininistrator role for all servers under that /wlp/usr/servers/ directory.

Disable security verify SSL in oracle apex

I'm using Oracle Application Express 11g.
To secure RESTful services I want to create Third Party Authentication for it.
According to this article : http://www.oracle.com/technetwork/developer-tools/rest-data-services/documentation/listener-dev-guide-1979546.html
In order to register my third party user I need to access this url : https://server:port/ords/resteasy/ui/oauth2/clients/ as I don't have SSL every time I face this error(entring the url in http) :
403-Forbidden
This resource must be accessed over HTTPS only
The Question is : how can I disable "security verify SSL" in apex, in order that I never face this error again.
Note that there is no error like this in other pages because I'm not forced to use https, and I'm receiving this error entring the url in http.
https://docs.oracle.com/cd/E37099_01/doc.20/e25066/install.htm#AELIG7183
1.4.5 Using OAuth2 in Non HTTPS Environments
RESTful Services can be protected with the OAuth2 protocol to control access to nonpublic data. To prevent data snooping, OAuth2 requires all requests involved in the OAuth2 authentication process to be transported using HTTPS. The default behavior of Oracle REST Data Services is to verify that all OAuth2 related requests have been received using HTTPS. It will refuse to service any such requests received over HTTP, returning an HTTP status code of 403 Forbidden.
This default behavior can be disabled in environments where HTTPS is not available as follows:
Locate the folder where the Oracle REST Data Services configuration is stored.
Edit the file named defaults.xml.
Add the following setting to the end of this file just before the </properties> tag.
<entry key="security.verifySSL">false</entry>
Save the file.
Restart Oracle REST Data Services if it is running.
Note that it is only appropriate to use this setting in development or test environments. It is never appropriate to use this setting in production environments because it will result in user credentials being passed in clear text.

401 when accessing Dynamics CRM 2016 Web APIs

I am struggling to access the Dynamics 2016 CRM OData Web APIs from a console application.
We have Dynamics CRM 2016 installed, configured with Claims-based authentication, and using AD FS v3.0.
My understanding is that a console app (or web app) should be able to access the Web APIs using Windows integrated authentication (i.e. NTML or Kerberos) without any special treatment ... or maybe the OAuth flow should work when enabled.
For a regular user accessing Dynamics "pages", the authentication works fine (redirection to AD FS log in page), but accessing the OData APIs does not seem to work (for instance : https://crm.domain.org/api/discovery/v8.0/ ) :
in a browser I get a Windows login prompt and typing valid credentials always results in a HTTP 401 unauthorized error
in a brower, if I navigate to a Web API url after having logged on on the pages , then I can access the Web APIs (i.e. some cookies must be set and I am already implicitly authorized)
from code, using an HttpClient with specific valid credentials (or current credentials) , I also get a 401
Things I have tried :
if I disable Claims-based authentication completely , HttpClient works fine and I can access the OData APIs
if I leave Claims-based authentication enabled, and activate OAuth via PowerShell Add-PSSnapin Microsoft.Crm.PowerShell ; $ClaimsSettings = Get-CrmSetting -SettingType OAuthClaimsSettings; $ClaimsSettings.Enabled = $true ; Set-CrmSetting -Setting $ClaimsSettings ;.
Windows integrated authentication still does not work, but using Bearer authentication is now possible. I can use this snippet to retrieve the OAuth Endpoint for token generation, and use AuthenticationContext.AcquireTokenAsync to issue a token, and then pass it in the Authorization HTTP Header ... but then, no matter what, I get this error :
Bearer error=invalid_token, error_description
=Error during token validation!, authorization_uri=https://our.adfs.domain.org/adfs/oauth2/authorize, resource_id=https://crm.domain.org/
Am I missing something ? is that possibly a configuration issue ?
From this answer from the dynamics community forum, it looks like the api is pretty strict about the parameters and headers it requires. When doing the request, make sure you have the Cache-Control: no-cache and Content-Type: application/x-www-form-urlencoded headers set.
In the subsequent request to access the api with the retrieved token you should set the Authorization header in the form of Bearer: TOKEN (worth noting since a lot of people actually thought they could directly put the token), the OData-Version: 4.0, Cache-Control: no-cache and Accept: application/json ones too.
Looking at the different OAuth endpoints and the previously linked answer, I'm not sure the authorization uri is the right one (eg https://login.windows.net), so do you make sure that's correct. It's also stated that you should use the OAuth endpoint url and use the WWW-Authenticate header that returns the valid one, even if this route will respond with a 401. I'm sure you already saw this example, but it provides a pretty complete overview of an auth flow and how the token is retrieved using AcquireTokenAsync where you pass your resource and clientID. I might also be looking at an updated page and it's not relevant in your case.
You also want to check if the resource id you specified is the correct one, some people reported to have to specify one in the form of https://crm3.domain.org/ or https://crm4.domain.org/ instead of the bare one, so that could be one thing.
It could also be a configuration issue, given what #l said about the fact an IP would work instead of the domain name. It could very well be a certificate problem, where it's not validated correctly or untrusted, thus creating the error you see even if it's not the appropriate message. Also make sure your 443 port is allowed through your firewall(s).
One interesting post where the author explains that the Form Authentication setting of the AD FS Management Console was required for him to proceed (it's CRM 2013, but might still be related).

Deny access to a rails route if request does not originate from app

I have a route in my application that returns results from an LDAP query. I'm using a privileged account for this as it needs to return information that a regular account can't access.
Is there a way to deny users access to this route if they're not using it via one of the application's views? What I'm trying to prevent is a someone reverse engineering it and building their own app to gain access to the PII.
There is no reliable way to say this request originated from this view vs. this request originated from (e.g.) the command line.
An HTTP URL request doesn't have a verifiable source of origination. There is a "referrer" HTTP header which is intended for saying where the previous request originated, but it is not for security and completely spoofable, and not even always included in the request.
Somehow you'll need to authenticate the request. Don't invent your own way. Use devise or some other tested tool to build an authentication strategy, and figure out how to modify your application to work with existing conventions of HTTP request authentication (secure token, cookie based auth, etc.)

asp.net mvc authentication when call from client app

I use asp.net mvc controller instead of Web Service in my project.
When I call the controller from my client app,there will be a authentication problem. If I use Web Service ,I can use SOAP Header , but now in asp.net mvc, There is no soap header.
Please help.
I am really know a little about the web security.
Normal way of doing this when you come to http services is to pass it in authorization header in following format (if you are doing request from fiddler)
Authorization: Basic user123:pass123
user123:pass123 string is normally base64 encoded and you have to decode it on server side, check it against user store and authenticate the user. One example can be found here
You have several options.
Use a request header to contain some security token.
Include security tokens in the message that you send in the request body.
If your application uses something like Forms Authentication, you can ask consumers to call a login action, then grab the Forms Auth cookie and include that cookie in subsequent calls.
Since you are not using soap. You may use a simple http way. Which means you start a HttpRequest and handle result via HttpResponse. Thus you have to simulate a authenticate action as signing in from web browser.
You need to get the security token or cookie from the reponse. And put them into your following request. Thus your controller will recognize the request's identity.

Resources