I am trying to use MQTT in a Flutter project to test the prototype. And I am using custom certificate-based authentication.
I am using mqtt_client package.
before connect SecurityContext giving this error in web Unsupported operation: default SecurityContext getter
below is my sample code
try {
SecurityContext securityContext =
SecurityContext(withTrustedRoots: false);
securityContext.setTrustedCertificatesBytes(caCertificate);
securityContext.useCertificateChainBytes(caCertificate);
securityContext.setClientAuthoritiesBytes(clientCertificate,
password: String.fromCharCodes(privateKey));
} catch (e) {
print(e);
}
_client = MqttClient('m.test.com', _identifier);
_client.port = 8883;
_client.keepAlivePeriod = 20;
_client.onDisconnected = onDisconnected;
_client.secure = true;
//_client.securityContext = securityContext;
_client.onBadCertificate = ((X509Certificate cert) => false);
_client.logging(on: true);```
this worked for me but I don't understand what (dynamic a) is doing ... perhaps someone can explain it in more detail ?
void initializeMQTTClient() async {
_client = MqttServerClient(_host, _identifier);
_client.port = 8883; //1883
_client.keepAlivePeriod = 20;
_client.onDisconnected = onDisconnected;
_client.secure = true; // false
_client.logging(on: true);
_client.securityContext = SecurityContext.defaultContext;
// _client.useWebSocket = false;
/// Add the successful connection callback
_client.onConnected = onConnected;
_client.onSubscribed = onSubscribed;
_client.onBadCertificate = (dynamic a) => true;
Related
I managed to stream all runtime data in my MQTT broker however I want to display specific data based on their ID name using card widget in flutter.. How can I do that? This is my current code. Do I need to use write function?
MqttServerClient client = MqttServerClient(host, id);
Future<Stream<List<MqttReceivedMessage<MqttMessage>>>?> mqttSubscribe(
{required String topic}) async {
// init client
client = MqttServerClient(host, id);
client.port = port;
client.autoReconnect = true;
client.logging(on: true);
client.keepAlivePeriod = 60;
client.pongCallback = pong;
client.onDisconnected = onDisconnected;
final connMess = MqttConnectMessage()
.authenticateAs(username, password)
.withClientIdentifier(id)
.startClean(); // Non persistent session for testing
print('EXAMPLE::Mqtt client connecting....');
client.connectionMessage = connMess;
// Connect to mqtt broker
try {
await client.connect();
// if connected, subscribe to a topic
if (client.connectionStatus?.state == MqttConnectionState.connected) {
// subscribe to topic
client.subscribe(topic, MqttQos.atMostOnce);
return client.updates;
} else {
return null;
}
} on NoConnectionException catch (e) {
log(e.toString());
}
}
void pong() {
print('ping response arrived');
}
void onDisconnected() {
print('disconnected');
}
Client code
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
IdentityModelEventSource.ShowPII = true;
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
{
options.AccessDeniedPath = "/Authorization/AccessDenied";
})
.AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.Authority = "https://jpprojectsso.inthink.top:5000"; //
options.RequireHttpsMetadata = false;
options.ClientId = "TestClient";
options.ClientSecret = "Client Secrets";
options.SaveTokens = true;
options.ResponseType = "code id_token";
options.GetClaimsFromUserInfoEndpoint = true;
options.Scope.Clear();
options.Scope.Add(OidcConstants.StandardScopes.OpenId);
options.Scope.Add(OidcConstants.StandardScopes.Profile);
});
}
The controller looks like this:
[Authorize]
public IActionResult Privacy()
{
var user = User.Identity.Name;
return View();
}
ids4 connection client success. But the client always 302 redirect to sso and sso successfully redirects to client... in loop.
My sso use Jp project ids4. How can I resolve this problem?
Thanks,
I found the bug...
in void Configure function.
app.UseAuthorization() should be executed after app.UseAuthentication()
Then it works.
I have written this application to use mqttnet library but connection failed.
How is it possible to get mqttnet with a trace?
Do you notice something wrong with the connection?
Here my code
var mqttClient = new MqttFactory(new MQTTnet.Diagnostics.MqttNetLogger("MyCustomId")).CreateMqttClient();
var caCert = X509Certificate.CreateFromCertFile("C:\\ca.crt");
var clientCert = new X509Certificate2("C:\\certificate.pfx", "uno");
var options = new MqttClientOptionsBuilder()
.WithCredentials("ut", "pwd")
.WithTcpServer("mydns", 8883)
.WithTls(new MqttClientOptionsBuilderTlsParameters
{
UseTls = true,
SslProtocol = System.Security.Authentication.SslProtocols.Tls13,
Certificates = new List<X509Certificate>()
{
caCert, clientCert
},
CertificateValidationCallback = (X509Certificate x, X509Chain y, SslPolicyErrors z, IMqttClientOptions o) =>
{
return true;
}
})
.Build();
MQTTnet.Client.Connecting.MqttClientAuthenticateResult r=await mqttClient.ConnectAsync(options, CancellationToken.None);
Thank you
any help would be appreciated
I have replaced "CreateMqttClient" with "CreateManagedMqttClient" and modified the subsequent part of the code and all has worked
I've created .NET Framework API which contains authentication, I launch the Web API using Jetbrains Rider and I run my Xamarin.Forms application using Visual Studio and I can't access any data from my Web API nor post any.
The Webservice class:
private readonly HttpClient _client;
public AccountService()
{
_client = new HttpClient
{
MaxResponseContentBufferSize = 256000
};
}
public async Task RegisterAsync(string email, string password, string confirmPassword)
{
var url = "http://169.254.80.80:61348/api/Account/Register";
var model = new RegisterBindingModel()
{
Email = email,
Password = password,
ConfirmPassword = confirmPassword
};
var json = JsonConvert.SerializeObject(model);
HttpContent content = new StringContent(json);
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var response = await _client.PostAsync(url, content);
}
The initiation of the registration
private async void Register()
{
try
{
using (UserDialogs.Instance.Loading())
{
await _accountServices.RegisterAsync
(Email, Password, ConfirmPassword);
}
UserDialogs.Instance.Alert("Register Successful");
await _navigation.PushAsync(new LoginPage());
}
catch
{
UserDialogs.Instance.Alert("Something wrong happened, Try again");
}
}
I've tried to access the localhost through Emulator using these IPs:
10.0.3.2
10.0.2.2
169.254.80.80
And I've tried my default gateways and my local IP address with and without ports, in regardless using postman i can work with my api flawlessly.
I don't get errors but the connection status code is not successful and I don't get any data and the newly registered account won't be posted to the api.
EDIT:
As for the answers I've changed my method to this:
public async Task<string> RegisterAsync(string email, string password, string confirmPassword)
{
var client = new HttpClient()
{
BaseAddress = new Uri("http://169.254.80.80:61348/")
};
var postData = new List<KeyValuePair<string, string>>();
var nvc = new List<KeyValuePair<string, string>>();
nvc.Add(new KeyValuePair<string, string>("email", email));
nvc.Add(new KeyValuePair<string, string>("password", password));
nvc.Add(new KeyValuePair<string, string>("confirmPassword", confirmPassword));
var req = new HttpRequestMessage(HttpMethod.Post, "api/Account/Register") { Content = new FormUrlEncodedContent(nvc) };
var res = await client.SendAsync(req);
if (res.IsSuccessStatusCode)
{
string result = await res.Content.ReadAsStringAsync();
string test = JsonConvert.DeserializeObject<string>(result);
return test;
}
return null;
}
and i call the web api using postman like this:
http://localhost:61348/api/Account/Register
I always prefer Newtonsoft Json.NET to carry out web request here is the code I have implemented in my case and it works great for me.
public static async Task<string> ResgisterUser(string email, string password, string confirmPassword)
{
var client = new HttpClient(new NativeMessageHandler());
client.BaseAddress = new Uri("http://192.168.101.119:8475/");
var postData = new List<KeyValuePair<string, string>>();
var nvc = new List<KeyValuePair<string, string>>();
nvc.Add(new KeyValuePair<string, string>("email", email));
nvc.Add(new KeyValuePair<string, string>("password", password));
nvc.Add(new KeyValuePair<string, string>("confirmPassword",confirmPassword));
var req = new HttpRequestMessage(HttpMethod.Post, "api/Vendor/Register") { Content = new FormUrlEncodedContent(nvc) };
var res = await client.SendAsync(req);
if (res.IsSuccessStatusCode)
{
string result = await res.Content.ReadAsStringAsync();
string test= JsonConvert.DeserializeObject<string>(result);
return test;
}
}
Hope it works for you.
I have created a native app in Azure using App Registration and added required permissions for VSTS Agent
Now, I am able to login using oauth authentication with "ADAL" and able to get the token but when trying to access the web api request it gives Http 403 Response
Here is the code example below
using (HttpClient client = new HttpClient())
{
client.BaseAddress = new Uri(vstsCollectionUrl);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("X-TFS-FedAuthRedirect", "Suppress");
client.DefaultRequestHeaders.Authorization = authHeader;
HttpResponseMessage res = client.GetAsync(webapiURL).Result;
}
Please let me know what i am missing
thanks in advance
Seems it's an authentication issue, Just check the value of authHeader.
You can reference below samples for the authentication with header:
Sample 1- auth-samples here ;
Sample 2 - REST API
Post the auth sample as reference here:
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using System;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
namespace DeviceProfileSample
{
public class Program
{
//============= Config [Edit these with your settings] =====================
internal const string vstsCollectionUrl = "https://myaccount.visualstudio.com"; //change to the URL of your VSTS account; NOTE: This must use HTTPS
internal const string clientId = "872cd9fa-d31f-45e0-9eab-6e460a02d1f1"; //update this with your Application ID from step 2.6 (do not change this if you have an MSA backed account)
//==========================================================================
internal const string VSTSResourceId = "499b84ac-1321-427f-aa17-267ca6975798"; //Static value to target VSTS. Do not change
public static void Main(string[] args)
{
AuthenticationContext ctx = GetAuthenticationContext(null);
AuthenticationResult result = null;
try
{
DeviceCodeResult codeResult = ctx.AcquireDeviceCodeAsync(VSTSResourceId, clientId).Result;
Console.WriteLine("You need to sign in.");
Console.WriteLine("Message: " + codeResult.Message + "\n");
result = ctx.AcquireTokenByDeviceCodeAsync(codeResult).Result;
var bearerAuthHeader = new AuthenticationHeaderValue("Bearer", result.AccessToken);
ListProjects(bearerAuthHeader);
}
catch (Exception ex)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Something went wrong.");
Console.WriteLine("Message: " + ex.Message + "\n");
}
}
private static AuthenticationContext GetAuthenticationContext(string tenant)
{
AuthenticationContext ctx = null;
if (tenant != null)
ctx = new AuthenticationContext("https://login.microsoftonline.com/" + tenant);
else
{
ctx = new AuthenticationContext("https://login.windows.net/common");
if (ctx.TokenCache.Count > 0)
{
string homeTenant = ctx.TokenCache.ReadItems().First().TenantId;
ctx = new AuthenticationContext("https://login.microsoftonline.com/" + homeTenant);
}
}
return ctx;
}
private static void ListProjects(AuthenticationHeaderValue authHeader)
{
// use the httpclient
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(vstsCollectionUrl);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("User-Agent", "VstsRestApiSamples");
client.DefaultRequestHeaders.Add("X-TFS-FedAuthRedirect", "Suppress");
client.DefaultRequestHeaders.Authorization = authHeader;
// connect to the REST endpoint
HttpResponseMessage response = client.GetAsync("_apis/projects?stateFilter=All&api-version=2.2").Result;
// check to see if we have a succesfull respond
if (response.IsSuccessStatusCode)
{
Console.WriteLine("\tSuccesful REST call");
Console.WriteLine(response.Content.ReadAsStringAsync().Result);
}
else if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized)
{
throw new UnauthorizedAccessException();
}
else
{
Console.WriteLine("{0}:{1}", response.StatusCode, response.ReasonPhrase);
}
}
}
}
}
Aren't you missing what authentication,
string credentials = Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(string.Format("{0}:{1}", "", token)));
using (HttpClient client = new HttpClient())
{
client.BaseAddress = new Uri(vstsCollectionUrl);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new
System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", credentials)
HttpResponseMessage response = client.GetAsync(uri).Result;
response.EnsureSuccessStatusCode();
var responseStream = await response.Content.ReadAsStreamAsync();
}
I hope this helps.