ABP Framework version: v8.0.0
UI Type: MVC + Flutter
Database System: MongoDB
Tiered (for MVC) or Auth Server Separated (for Angular): no
Exception message and full stack trace: below is the error and hub code with flutter controller code
[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Error parsing handshake response: 'type 'Null' is not a subtype of type 'String' in type cast'
public class ChatMaiHub : AbpHub
{
private readonly IIdentityUserRepository _identityUserRepository;
private readonly ILookupNormalizer _lookupNormalizer;
public ChatMaiHub(IIdentityUserRepository identityUserRepository, ILookupNormalizer lookupNormalizer)
{
_identityUserRepository = identityUserRepository;
_lookupNormalizer = lookupNormalizer;
}
public async Task SendMessage(string targetUserName, string message)
{
var targetUser = await _identityUserRepository.FindByNormalizedUserNameAsync(_lookupNormalizer.NormalizeName(targetUserName));
message = $"{CurrentUser.UserName}: {message}";
await Clients
.User(targetUser.Id.ToString())
.SendAsync("ReceiveMessage", message);
}
}
below is flutter controller
import 'package:mailaundry/presentation/models/authview_model.dart';
import 'package:logging/logging.dart';
import 'package:signalr_netcore/signalr_client.dart';
import '../../mylaundryhub/mylaundryhub_gloabelclass/mylaundryhub_prefsname.dart';
class ChatController {
late HubConnection _hubConnection;
final Function(String message) onMessageReceived;
AuthViewModel authViewModel = AuthViewModel();
final transportProtLogger = Logger("SignalR - transport");
final hubProtLogger = Logger("SignalR - hub");
Future<String> getValidAccessToken() async {
// Ensure this method handles the potential null case appropriately.
return await authViewModel.getValidAccessToken() ?? '';
}
ChatController({required this.onMessageReceived}) {
var httpOptions = HttpConnectionOptions(
logger: transportProtLogger,
transport: HttpTransportType.ServerSentEvents,
accessTokenFactory: () async => await getValidAccessToken());
_hubConnection = HubConnectionBuilder()
.withUrl("$api/signalr-hubs/chat-mai", options: httpOptions)
.configureLogging(hubProtLogger)
.build();
_hubConnection.on('ReceiveMessage', (arguments) {
if (arguments != null && arguments.isNotEmpty) {
onMessageReceived(arguments[0] as String);
}
});
_hubConnection.start();
//.catchError((error) {
//print('Connection Failed. Error: $error');
//});
}
Future<void> sendMessage(String targetUserName, String message) async {
if (_hubConnection.state == HubConnectionState.Connected) {
await _hubConnection
.invoke('SendMessage', args: [targetUserName, message]);
} else {
print('Connection is not established. Message not sent.');
// Optionally, implement a retry mechanism or inform the user.
}
}
}
Okay thanks a lot for your prompt reply.
i tried that , didn't work, creating a self signed certificate installed it with the key still there was same error. anyways what's the difference in both procedures? any security flaw?
it should be documented right? why giving me ref from SO, anyways site is working now will test thoroughly and let you know.
yes thhe file is there still getting same error. can you take remote access and solve as its on high priority now
Hi that file is there , please confirm i should be generating that using this righht? dotnet dev-certs https -v -ep openiddict.pfx -p 00000000-0000-0000-0000-000000000000 then i have followed same steps i had succesfully hosted same setup earlier , just missing some thing at this time or dont know
I hosted production version on cloud iis but now app is not starting getting following in log
Starting web host.
2024-03-03 12:14:52.873 +00:00 [FTL] Host terminated unexpectedly!
Volo.Abp.AbpInitializationException: An error occurred during ConfigureServicesAsync phase of the module Volo.Abp.OpenIddict.AbpOpenIddictAspNetCoreModule, Volo.Abp.OpenIddict.AspNetCore, Version=8.0.0.0, Culture=neutral, PublicKeyToken=null. See the inner exception for details.
---> System.Security.Cryptography.CryptographicException: The system cannot find the file specified.
at System.Security.Cryptography.X509Certificates.CertificatePal.FilterPFXStore(ReadOnlySpan1 rawData, SafePasswordHandle password, PfxCertStoreFlags pfxCertStoreFlags) at System.Security.Cryptography.X509Certificates.CertificatePal.FromBlobOrFile(ReadOnlySpan
1 rawData, String fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
at System.Security.Cryptography.X509Certificates.X509Certificate..ctor(String fileName, String password, X509KeyStorageFlags keyStorageFlags)
at System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(String fileName, String password)
at Microsoft.Extensions.DependencyInjection.OpenIddictServerBuilderExtensions.AddProductionEncryptionAndSigningCertificate(OpenIddictServerBuilder builder, String fileName, String passPhrase)
at MyDhobi.Web.MyDhobiWebModule.<>c.<PreConfigureServices>b__0_3(OpenIddictServerBuilder serverBuilder) in
**ABP Framework version: v8.0.0
UI Type: MVC
Database System: MongoDB
Tiered (for MVC) or Auth Server Separated (for Angular): no
Exception message and full stack trace: let me know if you need complete log**
Yes figured it out , is it documented anywhere??
Well i dont want to show webview of login page instead i am using connect/token api to get the token using below method
` Future<AccessToken> fetchAccessToken({
required String username,
required String password,
required String grantType,
required String clientId,
required String clientSecret,
required String scope,
}) async {
final response = await http.post(
Uri.parse('$api/connect/token'),
headers: <String, String>{
'Content-Type': 'application/x-www-form-urlencoded',
},
body: {
'username': username,
'password': password,
'grant_type': grantType,
'client_id': clientId,
'client_secret': clientSecret,
'scope': scope,
},
);
if (response.statusCode == 200) {
print(response.body);
final accessToken = AccessToken.fromJson(json.decode(response.body));
await storeAccessToken(accessToken.accessToken, accessToken.expiresIn);
await storeRefreshToken(accessToken.refreshToken);
return accessToken;
} else {
throw Exception("Invalid username or password");
}
}
and trying to authorize api using this method
` Future<http.Response> get(String url) async {
String? token = await authViewModel.getValidAccessToken();
return http.get(
Uri.parse(url),
headers: {
'Authorization': 'Bearer $token',
},
);
}`
, you can try reproducing using postman just get the access token using connect/token api and use it as bearer token to access secured api it responds with login page 401 response, check screen shots
and can i please get quick reply , this issue is delaying my deadline.