Enable cross domain not a member of hubConfiguration - vb.net

i have been developing a signalR chat application in vb.net where i'm using the below code:
Public Sub Configuration(ByVal app As IAppBuilder)
Dim config = New HubConfiguration With {.EnableCrossDomain = True}
app.MapHubs(config)
End Sub
it throws the error
Enable cross domain not a member of hubConfiguration
Could anyone please suggest what could be the alternative to enable Cross Domain

The tutorial is explaining this very good:
(http://www.asp.net/signalr/overview/guide-to-the-api/hubs-api-guide-javascript-client)
public class Startup
{
public void Configuration(IAppBuilder app)
{
// Branch the pipeline here for requests that start with "/signalr"
app.Map("/signalr", map =>
{
// Setup the CORS middleware to run before SignalR.
// By default this will allow all origins. You can
// configure the set of origins and/or http verbs by
// providing a cors options with a different policy.
map.UseCors(CorsOptions.AllowAll);
var hubConfiguration = new HubConfiguration
{
// You can enable JSONP by uncommenting line below.
// JSONP requests are insecure but some older browsers (and some
// versions of IE) require JSONP to work cross domain
// EnableJSONP = true
};
// Run the SignalR pipeline. We're not using MapSignalR
// since this branch already runs under the "/signalr"
// path.
map.RunSignalR(hubConfiguration);
});
}
}
}
By the way: In the case you post your code (all) it is easier to search.

Related

SignalR .Net client cannot connect with https

I am using SignalR Core 2.4.1.0.
This is an Owin project, self-hosted.
My configuration:
public void Configuration(IAppBuilder app)
{
app.Use(async (ctx, next) =>
{
Console.WriteLine($"Incoming: {ctx.Request.Path}");
await next();
});
app.UseCors(CorsOptions.AllowAll);
var hubConfiguration = new HubConfiguration();
GlobalHost.Configuration.DisconnectTimeout = TimeSpan.FromSeconds(10);
hubConfiguration.EnableDetailedErrors = true;
app.MapSignalR(hubConfiguration);
}
I am able to connect to https://localhost:9999/signalr/hubs from a web browser fine.
I am also able to connect to SignalR when not using https. (after removing the urlacl )
I also have tried adding a middleware before the SignalR to see the incoming request.
With http the middleware shows the Request and path.
With https the middleware shows the Request from the web browser but never shows any request from the client.
The client just changes states from connecting to disconnected with not exceptions.
My client for testing is .Net console application:
var hub = new HubConnection("https://localhost:9999");
var hubProxy = hub.CreateHubProxy("MyHUB");
hub.Error += (e) =>
{
};
hub.StateChanged += (s) =>
{
Console.WriteLine(s.NewState.ToString());
};
hub.Start();
Console.ReadLine();
I've used SignalR before but this is my first time trying to implement ssl.
In summary, .Net client will connect via http but not https.
Browser can connect to the JS library over https but I haven't tried using the JS library yet.
T.I.A.

Authenticate with Azure AD using ASPNET Core 2 from behind Corporate Proxy

I have an ASPNET Core 2 application which I am trying to Authenticate with Azure AD using OpenId. I just have boilerplate code from selecting Single Organization Authentication in the ASPNET Core 2 templates, so no custom code. I followed the article here.
The app is not able to get metadata from the Azure AD application because of proxy. The same URL returns data if I just paste it in browser.
The error I get is:
HttpRequestException: Response status code does not indicate success: 407 (Proxy Authentication Required).
System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode()
IOException: IDX10804: Unable to retrieve document from: 'https://login.microsoftonline.com/my-tenant-id/.well-known/openid-configuration'.
Microsoft.IdentityModel.Protocols.HttpDocumentRetriever+d__8.MoveNext()
I have another ASPNET 4.5.2 application where I am able to perform authentication with the same Azure AD app as above after setting proxy in code like below:
System.Net.HttpWebRequest.DefaultWebProxy = new WebProxy
{
Address = new Uri("http://my-company-proxy:8080"),
Credentials = new NetworkCredential
{
UserName = "proxyusername",
Password = "proxypassword"
}
};
So Essentially my problem is to get past the Proxy Authentication in ASPNET Core 2.
I have tried Microsoft.AspNetCore.Proxy package. Its pretty much broken and doesn't work for me. Also I tried adding the Proxy entries in machine.config (which are actually not required for 4.5.2 app) but that doesn't work as well. I believe getting past a corporate proxy should be very trivial, but doesn't look like it so far.
Tratcher's comment pointed me in the right direction and I got it working, but just to help everyone with it, below is what you need to do:
builder.AddOpenIdConnect(options => options.BackchannelHttpHandler = new HttpClientHandler
{
UseProxy = true,
Proxy = new WebProxy
{
Credentials = new NetworkCredential
{
UserName = "myusername",
Password = "mypassword"
},
Address = new Uri("http://url:port")
}
});
In Full .net framework setting up a proxy is using a config setting
entry but to use an HTTP proxy in .net core ,you have to implement
IWebProxy interface.
Microsoft.AspNetCore.Proxy is proxy middleware which serves a different purpose (to setup reverse proxy) not as an http proxy .Refer this article for more details
To implement a webproxy in .net core,
public class MyHttpProxy : IWebProxy
{
public MyHttpProxy()
{
//here you can load it from your custom config settings
this.ProxyUri = new Uri(proxyUri);
}
public Uri ProxyUri { get; set; }
public ICredentials Credentials { get; set; }
public Uri GetProxy(Uri destination)
{
return this.ProxyUri;
}
public bool IsBypassed(Uri host)
{
//you can proxy all requests or implement bypass urls based on config settings
return false;
}
}
var config = new HttpClientHandler
{
UseProxy = true,
Proxy = new MyHttpProxy()
};
//then you can simply pass the config to HttpClient
var http = new HttpClient(config)
checkout https://msdn.microsoft.com/en-us/library/system.net.iwebproxy(v=vs.100).aspx

.Net core2 CORS - How SetIsOriginAllowed works?

Want to allow my API to be accessed from different sites. For this had:
services
.AddCors(options =>
{
options.AddPolicy(PolicyName, builder =>
{
builder
.SetIsOriginAllowedToAllowWildcardSubdomains()
.WithOrigins(
"http://*.my-api.com",
"http://*.my-api.service"
)
...
This doesn't seem to allow httpS or when I specify the port in the request.
Ex.:
https://www.my-api.com:3000
Thought could replace the WithOrigins with SetIsOriginAllowed()
services
.AddCors(options =>
{
options.AddPolicy(PolicyName, builder =>
{
builder
.SetIsOriginAllowed(IsOriginAllowed)
where IsOriginAllowed function is defined as:
private static bool IsOriginAllowed(string host)
{
var corsOriginAllowed = new[] { "my-api.com", "my-api.service" };
return corsOriginAllowed.Any(origin =>
Regex.IsMatch(host, $#"^http(s)?://.*{origin}(:[0-9]+)?$", RegexOptions.IgnoreCase));
}
but this doesn't work at all, even the regular expression is returning true when I want.
Does anyone know why this doesn't work and can show me the right way to allow httpS (besides duplicating all the domains in WithOrigins() with httpS and different ports.
Thanks
SetIsOriginAllowed() does work. Was testing with Postman and as was told, Postman doesn't care about headers returned from the server. It's the browser who enforces the Cors headers.
To test properly created a little html page under a test site with below javascript
<html>
<script>
fetch('http://test.com:5000/v2/campaign/hallo3').then(function(response) {
return response.json();
}).then(function(j) {
alert(JSON.stringify(j));
});
</script>
</html>
when domain is NOT included in the Cors allowed list browser doesn't display the returned values from API
After adding test domain to allowed domains list browser display the data and get the content Cors headers
Another problem was that with just the SetIsOriginAllowed() server was not sending the 'Vary' header. Had to set both:
.SetIsOriginAllowed(IsOriginAllowed)
.WithOrigins(corsOriginAllowed)
23/12/2022
For anyone struggling with this in NET CORE 7 try this on Program.cs:
Add the variable:
...
var MyHosts = "myHosts";
var builder = WebApplication.CreateBuilder(args);
...
Add the new CORS policy:
if (builder.Environment.IsDevelopment())
{
///Add a CORS policy to allow certain hosts
builder.Services.AddCors(options =>
{
options.AddPolicy(name: MyHosts,
policy =>
{
policy.AllowAnyOrigin().WithOrigins("http://localhost:59028").AllowAnyHeader().AllowAnyMethod();
});
});
}
U have to add the AllowAnyHeader and AllowAnyMethod or u'll get another pre-flight error.
Don't forget to add the new policy below:
app.UseCors(MyHosts);

Redirect HTTP to HTTPS in MVC4 Mobile Application

In My MVC4 Mobile application i have registration, login page and remaining pages. i would like to redirect user to HTTPS connection for all sensitive information pages like registration and login pages and HTTP to remailing pages.
I prefer you to use conditional functionality putting the class
public class RequireHttpsConditional : RequireHttpsAttribute
{
protected override void HandleNonHttpsRequest(AuthorizationContext filterContext)
{
var useSslConfig = ConfigurationManager.AppSettings["UseSSL"];
if (useSslConfig != null)
{
if (!string.Equals(filterContext.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase))
{
throw new InvalidOperationException("The requested resource can only be accessed via SSL.");
}
var request = filterContext.HttpContext.Request;
string url = null;
int sslPort;
if (Int32.TryParse(useSslConfig, out sslPort) && sslPort > 0)
{
url = "https://" + request.Url.Host + request.RawUrl;
if (sslPort != 443)
{
var builder = new UriBuilder(url) { Port = sslPort };
url = builder.Uri.ToString();
}
}
if (sslPort != request.Url.Port)
{
filterContext.Result = new RedirectResult(url);
}
}
}
}
and using this [RequireHttpsConditional] above the action result.
i have got this code somewhere in internet and is working fine for me.
in web.config appsettings use <add key="UseSSL" value="443" />
and in the controller above the action result you need put
[RequireHttpsConditional]
public ActionResult SignIn()
{
}
In IIS where you have your project right click and click "Edit Bindings" then you add a custom type https and port no 443 (you can change it)
Note this will work only in production environment. when executed locally it wont be working.
When you execute it locally you have request.Url.Host which will return you only localhost and missing your port number. so if you use it in MVC you will find error loading page for your pages where you put this code.
So this will work when you have the host assigned instead of using the localhost with a specific port number.
Within the controller actions that you wish to be HTTPS add the following code to the top of the method (of course you can simply add this to its own method and then call it):
if (!HttpContext.Request.IsSecureConnection)
{
var url = new UriBuilder(HttpContext.Request.Url);
url.Scheme = "https";
Response.Redirect(url.Uri.AbsoluteUri);
}
It is recommended though that you keep HTTPS on throughout your site to protect against a MITM attack against the auth cookie.

Communication between AngularJS and a Jersey Webservice which are on a different domain. Can't access correct session

Lately I've been playing around with AngularJS and Java EE 6. I've build an webservice with Jersey and deployed the project on Glassfish. Because I needed some kind of authentication and an OAuth implementation or an JDBCRealm seemed overkill I decided to just create a session if the user successfully logged in.
#POST
#Path("/login")
#Produces({MediaType.APPLICATION_JSON})
#Consumes({MediaType.APPLICATION_JSON})
public Response login(LoginDAO loginData, #Context HttpServletRequest req) {
req.getSession().invalidate();
loginData.setPassword(PasswordGenerator.hash(loginData.getPassword()));
User foundUser = database.login(loginData);
if(foundUser == null) {
return Response.status(Status.CONFLICT).build();
}
req.getSession(true).setAttribute("username", foundUser.getUsername());
return Response.ok().build();
}
#GET
#Path("/ping")
public Response ping(#Context HttpServletRequest req) {
if(req.getSession().getAttribute("username") == null) {
return Response.ok("no session with an username attribute has been set").build();
}
return Response.ok(req.getSession(true).getAttribute("username")).build();
}
This seems to work alright, if I post to /login from Postman or from a basic jQuery webpage deployed on glassfish I do get the correct username back and a session has been placed. If I then send a GET request to /ping I do get the username back from which I logged in.
I've an AngularJS application deployed on a node.js webserver which needed to login. Because this server is on another port its on another domain and I had to go through the pain of enabling cors. I did this by building a container response filter which sets the response headers.
public class CrossOriginResourceSharingFilter implements ContainerResponseFilter {
#Override
public ContainerResponse filter(ContainerRequest creq, ContainerResponse cresp) {
cresp.getHttpHeaders().putSingle("Access-Control-Allow-Origin", "http://localhost:8000");
cresp.getHttpHeaders().putSingle("Access-Control-Allow-Credentials", "true");
cresp.getHttpHeaders().putSingle("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
cresp.getHttpHeaders().putSingle("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With");
return cresp;
}
}
This did made it possible for me to send different types of HTTP requests from AngularJS to Java EE 6 application deployed on glassfish.
The problem is that when I send a POST request from AngularJS to the /login method, a session is created and I do get my username back. But when I send a GET request to the /ping method I get the "no session with an username attribute has been set" notice.
I believe this has to do with cross domain prevention and that I've to set the withCredentials tag when I send a xhr request. I've been trying to do this in AngularJS but haven't found out how to do this.
function LoginCtrl($scope, $http) {
$scope.login = function() {
$http.post("glassfish:otherport/api/login", $scope.credentials).
success(function(data) {
console.log(data);
}).
error(function(data, error) {
console.log(error);
});
};
};
And in another controller:
$scope.getUsername = function() {
$http.get("glassfish:otherport/api/ping", {}).
success(function(data) {
$scope.username = data;
}).
error(function() {
$scope.username = "error";
})
}
I've tried to set withCredentials is true
$http.defaults.withCredentials = true;
This however didn't solve my problem. I also tried to send it with every request in the config parameter but this didn't solve my problem either.
Depending on the version of AngularJS you are using you might have to set it on each $http.
Since 1.2 you can do:
$http.get(url,{ withCredentials: true, ...})
From 1.1.1 you can globally configure it:
config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.withCredentials = true;
}]).
If you're using an older version of Angular, try passing a config object to $http that specifies withCredentials. That should work in versions before 1.1:
$http({withCredentials: true, ...}).get(...)
See also mruelans answer and:
https://github.com/angular/angular.js/pull/1209
http://docs.angularjs.org/api/ng.$http
https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS?redirectlocale=en-US&redirectslug=HTTP_access_control#section_5
just an update to #iwein anwser, that we can now set in config itself
config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.withCredentials = true;
}]).
https://github.com/angular/angular.js/pull/1209
(available only after unstable version: 1.1.1)
In 1.2 version, this doesn't work for me:
$http({withCredentials: true, ...}).get(...)
if I read the doc, the shortcut method should take the config object
$http.get(url,{ withCredentials: true, ...})
$http is a singleton, That's the only way to mix in a same application requests with and without credentials.