I want to send broadcast messages from server (using laravel) to clients (using java).
What I'm using
Pusher as boradcast driver.
laravel passport for api authentication.
What I've done in server side
I've configured my Pusher credentials in .env file.
Uncommented App\Providers\BroadcastServiceProvider::class line in config/app.php file.
In config/auth.php file I've added the following:
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'devices' => [
'driver' => 'session',
'provider' => 'devices',
],
'api' => [
'driver' => 'passport',
'provider' => 'devices',
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
// using devices table to authenticate over api guard
'devices' => [
'driver' => 'eloquent',
'model' => App\Device::class,
],
],
In App\Providers\BroadcastServiceProvider class I added the following to boot() function:
Broadcast::routes(['prefix' => 'api', 'middleware' => 'auth:api']);
In routes/channels.php I added the following:
Broadcast::channel('device.{device_id}', function ($device, $device_id) {
return $device->id === $device_id;
});
Created an event AdvertisementAdded by running php artisan make:event AdvertisementAdded, added implements ShouldBroadcast then added the following to its broadcastOn() method:
return new PrivateChannel('device.'.$this->device_id);
What I've done in client side
Because I'm just testing now, I got my access_token and device_id by sending a login request from postman
I copied that accessToken to my java client and stored it in accessToken variable as String, here's the code:
String accessToken = "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6ImY3ZTVlMTAzZWE3MzJjMTI5NzY1YTliMmMzOTM0N2ZhOGE4OTU5MjRjNDA5ZjgyOTA4ZDg5NTFjZTBkOGZlNTA2M2M1YTI1MDBlOTdhZDdiIn0.eyJhdWQiOiIxIiwianRpIjoiZjdlNWUxMDNlYTczMmMxMjk3NjVhOWIyYzM5MzQ3ZmE4YTg5NTkyNGM0MDlmODI5MDhkODk1MWNlMGQ4ZmU1MDYzYzVhMjUwMGU5N2FkN2IiLCJpYXQiOjE1NTkwOTYyNDgsIm5iZiI6MTU1OTA5NjI0OCwiZXhwIjoxNTkwNzE4NjQ3LCJzdWIiOiI3Iiwic2NvcGVzIjpbXX0.FKeE9Z-wv2yUNQPl-qsbu9baYGTdbQ6DuzaI1R8azR6l1CIP9uRI4hCaoWvgx0GXWWLPRNhfQl-YD3KP2YOraW16-h4ie_95B9VQrpFxXnlqKojsfh1xSrSNSl5HncslMWQPVjoesBpM5y_cpG19PGgu-SWo0W6s9Fiz_Nm70oyyZB9mSqU8PVQvAOSNr6TMR0aC3iMLFfkyZkTSwj8EoRyD2LGW6v4PFriqx8JLbZASCOiUYBlYnunWrTFDOAenZcoa5Sw7u7kbSvYehjDKRwKjQM6zmPfi0A3Mp0CHjHE599OXb-NG2IMH-wmlT0vEZjP2U97hxmsNW1RtHNXWaRKFL9T-WVmZbJf3fH5hXqTv495L3MQfq_m5YFHyc5NuIqK4K4xMJB956a33ICnH8DmvPmJgderNAhqEX1JHUAsR63K7xbZxRBDS8OlQYcEf-_v75X0kT1s067enSvI8Vs212AVnI6k0FmgQNM8DfJUq6YduD0m2F2ZWpKPrwdd6PdW5ZlZTEv-D8dYIEQ_CwOWohNoENATmTqxDpPBxK5c723MEt8S7Sa9MEGAo56HW3-9pbazbEdY1GqPWKVkov7K_6eBFcWsV67AgJpoKFt6RiBfRvokgiH96WG89qBB_Ucpm8uBahX93FaOXhVLW0VjJH2LQKrGw0bb5LS8Ql5o";
String deviceId = "7";
Map<String, String> authHeaders = new HashMap();
authHeaders.put("Authorization", accessToken);
HttpAuthorizer authorizer = new HttpAuthorizer("http://localhost:8000/api/broadcasting/auth");
authorizer.setHeaders(authHeaders);
PusherOptions options = new PusherOptions();
options.setAuthorizer(authorizer).setCluster(PUSHER_CLUSTER);
Pusher pusher = new Pusher(PUSHER_APP_KEY, options);
pusher.subscribePrivate("private-device." + deviceId, new PrivateChannelEventListener() {
#Override
public void onEvent(String channelName, String eventName, final String data) {
System.out.println(String.format("Received event on channel [%s]", channelName));
}
#Override
public void onSubscriptionSucceeded(String string) {
System.out.println(String.format("Subscribed to channel [%s]", string));
}
#Override
public void onAuthenticationFailure(String string, Exception excptn) {
System.out.println(string);
}
});
pusher.connect(new ConnectionEventListener() {
#Override
public void onConnectionStateChange(ConnectionStateChange change) {
System.out.println("State changed to " + change.getCurrentState() +
" from " + change.getPreviousState());
}
#Override
public void onError(String message, String code, Exception e) {
System.out.println("There was a problem connecting!");
}
});
// Keeping main thread alive
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
When running the code above, it outputs the following on console:
State changed to CONNECTING from DISCONNECTED
State changed to CONNECTED from CONNECTING
java.io.IOException: Server returned HTTP response code: 403 for URL: http://localhost:8000/api/broadcasting/auth
I'm sure that auth:api middleware is working as I expect on other requests.
Here's a snippet from my routes/api.php:
Route::middleware('auth:api')->group(function () {
Route::prefix('advertisements')->group(function () {
Route::get('/request', 'AdvertisementsController#getDeviceAdvertisements')
->name('advertisements.getDeviceAdvertisements');
});
});
And here's a test to that route from postman (with the same access token as above):
And here's a test to api/broadcasting/auth route from postman (with the same access token as above):
What's the problem? Why all api routes under auth:api middleware working properly but not api/broadcasting/auth route??
Note
I tried working with public channels with no problems.
After a whole day of searching, finally It's solved.
The error happens when authorizing the channel, not when authenticating the request using auth:api middleware.
My private channel authorizing function in routes/channels.php always returns false meaning it will reject all subscribing requests to private-device.{device_id} channel:
Broadcast::channel('device.{device_id}', function ($device, $device_id) {
// this always return false, because of inequality of types
return $device->id === $device_id;
});
Authorizing function above always return false, because of inequality of types between $device->id (which is of type int) and $device_id (which is of type string).
So, in order to solve the problem, I cast both of them to int and then checked for equality.
Here's the code I used to solve the problem:
Broadcast::channel('device.{device_id}', function ($device, $device_id) {
return (int) $device->id === (int) $device_id;
});
Related
I am working in an application : Java Backend and Angular frontend. I am using angular Fromly, data is coming to service, but from the service it is not going to server.
lets share the code snipts:
Service Code:
export class RecommendationRequestService {
readonly ROOT_URL = environment.apiUrl + '/am/v1/recommendation-requests';
constructor(private http: HttpClient, private configService: RecommenderConfigService) {
}
updateData(interviewStatus: InterviewStatusRecommendation): Observable<any> {
console.log(interviewStatus);
return this.http.put<any>(this.ROOT_URL, interviewStatus);
}
}
This line is printing intended data set : console.log(interviewStatus);
The server is running.
The code from where the service is being called :
onSubmit() {
this.model.recommendationRequest.agentInitiationId = this.agentInitiationId;
const subs = this.service.updateData(this.model).subscribe(response => {
console.log('------' + response);
if (response === 'OK') {
this.notify.success('Request Recommendation Update success.');
} else {
this.notify.error('Request Recommendation Update fail.');
}
},
err => {
if (err.error.hasOwnProperty('code') && err.error.code === 1000) {
this.notify.error(CommonEnum.VALIDATION_ERROR);
}
});
subs.unsubscribe();
}
console.log('------' + response); this line should print at least -----, But nothing.
I have checked the network monitor from the browser, no call is going.
What might be the possible issue, any thing from fromly?
You are doing it incorrect as Aldin Bradaric also updated in the comment, as soon as you make the call on the very next moment you are unsubscribing it. This is what you should do :
public subs: [] = [];
onSubmit() {
this.model.recommendationRequest.agentInitiationId = this.agentInitiationId;
const subs = this.service.updateData(this.model).subscribe(response => {
console.log('------' + response);
if (response === 'OK') {
this.notify.success('Request Recommendation Update success.');
} else {
this.notify.error('Request Recommendation Update fail.');
}
},
err => {
if (err.error.hasOwnProperty('code') && err.error.code === 1000) {
this.notify.error(CommonEnum.VALIDATION_ERROR);
}
});
//subs.unsubscribe(); // remove it and add it to the lifecycle hooks
this.subs.push(subs);
}
ngOnDestroy() {
// create an array of subscription
this.subs.forEach(sub => sub.unsubscribe() )
}
I'm very new to working with backend server stuff and nodejs. I'm trying to set up Stripe with my app and now trying to create a Connected account with stripe. Was following this https://stripe.com/docs/connect/collect-then-transfer-guide but I don't understand enough to make it work. How do I get information from the server or send it through to make the account.
this is what I got so far
binding.connectWithStripe.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String redirect = "https://www.example.com/connect-onboard-redirect";
String url = "https://connect.stripe.com/express/oauth/authorize" +
"?client_id=" + "ca_Hdth53g5sheh4w4hwhw5h4weh5" +
"&state=" + 1234 +
"&redirect_uri=" + redirect;
CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
CustomTabsIntent customTabsIntent = builder.build();
customTabsIntent.launchUrl(view.getContext(), Uri.parse(url));
}
});
const express = require('express');
const app = express();
app.use(express.json());
const { resolve } = require("path");
const stripe = require('stripe')('sk_test_xxxx');
app.get("/", (req, res) => {
// Display landing page.
const path = resolve("./index.html");
res.sendFile(path);
});
app.get("/connect/oauth", async (req, res) => {
const { code, state } = req.query;
// Assert the state matches the state you provided in the OAuth link (optional).
if(!stateMatches(state)) {
return res.status(403).json({ error: 'Incorrect state parameter: ' + state });
}
// Send the authorization code to Stripe's API.
stripe.oauth.token({
grant_type: 'authorization_code',
code
}).then(
(response) => {
var connected_account_id = response.stripe_user_id;
saveAccountId(connected_account_id);
// Render some HTML or redirect to a different page.
return res.status(200).json({success: true});
},
(err) => {
if (err.type === 'StripeInvalidGrantError') {
return res.status(400).json({error: 'Invalid authorization code: ' + code});
} else {
return res.status(500).json({error: 'An unknown error occurred.'});
}
}
);
});
const stateMatches = (state_parameter) => {
// Load the same state value that you randomly generated for your OAuth link.
const saved_state = 'sv_53124';
return saved_state == state_parameter;
}
const saveAccountId = (id) => {
// Save the connected account ID from the response to your database.
console.log('Connected account ID: ' + id);
}
app.listen(4242, () => console.log(`Node server listening on port ${4242}!`));
The sign up page opens and can enter the test info but after submiting it's not actually creating the account in Stripe dashboard. Any help would be much appreciated
enter image description here
After you complete the Express account sign up, Stripe redirects your customer to the redirect URI you specified on your Connect OAuth url (looks like yours is https://www.example.com/connect-onboard-redirect).
You should redirect to a real page of yours here. The redirect URL will append query params containing the authorization code e.g. https://www.example.com/connect-onboard-redirect?code=ac_1234
where ac_1234 is the OAuth authorization code.
You need to parse out that authorization code and send it to your backend and complete the OAuth connection to actually connect that Express account to your Platform: https://stripe.com/docs/connect/oauth-express-accounts#token-request
Got the last piece of my puzzle. Didn't know how to communicate with nodejs and use the GET method. I used volley with this piece of code
RequestQueue queue = Volley.newRequestQueue(getContext());
StringRequest stringRequest = new StringRequest(Request.Method.GET, "http://10.0.2.2:4242" + "/connect/oauth",
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d(">>>>>>>>CONNECTED?", ">>>CONNECTED!!!<<<");
// enjoy your response
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d(">>>>>>>>>>ERRRRRRROR", error.toString());
// enjoy your error status
}
});
queue.add(stringRequest);
Hope that helps anyone else starting to learn nodejs :)
If i execute following code, sha.getLogin() and sha.getPasscode() outputs null !?
What is wrong with the code?
Client:
var socket = new SockJS('/ws');
stompClient = Stomp.over(socket);
stompClient.connect("123","456", function (frame) {
//...
});
Server:
#EventListener
private void onSessionConnect(SessionConnectedEvent event)
{
StompHeaderAccessor sha = StompHeaderAccessor.wrap(event.getMessage());
System.out.println(sha.getLogin());
System.out.println(sha.getPasscode());
}
But if execute following command, the login and passcode is contained.
sha.getMessageHeaders().toString()
Output (no json):
{
simpMessageType=CONNECT_ACK,
simpConnectMessage=GenericMessage[
payload=byte[0],
headers={
simpMessageType=CONNECT,
stompCommand=CONNECT,
nativeHeaders={
login=[123],//<<<Login
passcode=[PROTECTED],//<<<Passcode
accept-version=[
1.1,
1.0
],
heart-beat=[
10000,
10000
]
},
simpSessionAttributes={},
simpHeartbeat=[J#4b5cea63,
stompCredentials=[PROTECTED],
simpSessionId=xhojby2n
}
],
simpSessionId=xhojby2n
}
You can use accessor.getPasscode() method instead of accessor.getFirstNativeHeader(PASSWORD_HEADER)
bacause default StompDecoder protect passcode when setting
public void setPasscode(#Nullable String passcode) {
setNativeHeader(STOMP_PASSCODE_HEADER, passcode);
protectPasscode();
}
private void protectPasscode() {
String value = getFirstNativeHeader(STOMP_PASSCODE_HEADER);
if (value != null && !"PROTECTED".equals(value)) {
setHeader(CREDENTIALS_HEADER, new StompPasscode(value));
setNativeHeader(STOMP_PASSCODE_HEADER, "PROTECTED");
}
}
Spring is accessing the session data when you call sha.getLogin() or sha.getPasscode() but your user isn't authenticated on session, when you send connect ACK you need to intercept the message and authenticate user on the session.
Take a look at Spring Security WebSocket Support & Sessions
Have been struggling for last few days with this error Authentication of type {http://service.soap.xcompany.com}AuthenticationHeader had undefined attribute {http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd}Id while invoking a service call from a C# WCF client (targeting .Net 4.5 framework) to a Java Soap Service hosted externally with end-to-end encryption (both client and service certificates are used). When I tested the service using SoapUI with a JKS file, request was processed successfully.
So to see what's difference between the two requests, I did the followings:
Used Fiddler Inspector to capture two requests, one from SoapUI which was successful and one from C# which failed with 500 error
Extracted these two Xml messages into two C# classes (named them RequestByJava and RequestByDotNet, respectively) using the VS2017 feature Edit/Paste Special/Paste Xml as Classes.
Use XmlSerializer to de-serialize the two requests into the two objects of the types created in 2) and compared their properties.
With the Soap error message in mind, I narrowed down the difference between two Authentication headers - interestingly there is one extra property "Id" in the RequestByDotNet object whereas the RequestByJava object does not have. And the 500 Soap error message seemed to indicate that there was a schema validation error due to that undefined element "Id"
Also noticed that the RequestByDotNet.Header.Security.BinarySecurityToken.ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" but RequestByJava (SoapUI) has a different ValueType "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509PKIPathv1"
Another difference, not sure it matters, is that the Request from .net codes has a "mustunderstand" value under the Header.Security set to true while the one from Java does not.
My questions are:
Why is the difference?
How can this be fixed without having to write a Java client?
Some codes used binding and endpoint behavior:
private static CustomBinding BuildCustomBinding()
{
var binding = new CustomBinding();
var textMessageEncoding = new TextMessageEncodingBindingElement()
{
MessageVersion = MessageVersion.Soap11
};
var securityBindingElement =
SecurityBindingElement.CreateMutualCertificateBindingElement(
MessageSecurityVersion.WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10, true);
binding.Elements.AddRange(textMessageEncoding, securityBindingElement, new HttpsTransportBindingElement());
return binding;
}
private static void CallAccountService()
{
//credential for test
const string applId = "testuser";
const string pwd = "password";
//for client certificate, import client.pfx to LocalMachine's Trusted Root Certification Authorities and make sure the thumbprint matches
var client = new NOLWSAccountSvc.WSAccountv1Client(BuildCustomBinding(), GetAccountServiceEndpointAddress());
client.ClientCredentials.ClientCertificate.SetCertificate(StoreLocation.LocalMachine,
StoreName.Root, X509FindType.FindByThumbprint, "thumbprintvalue");
//for service certificate, import service-provider.cer to same store location and store name and make sure the thumbprint matches
client.ClientCredentials.ServiceCertificate.SetDefaultCertificate(StoreLocation.LocalMachine, StoreName.Root,
X509FindType.FindByThumbprint, "thumprintvalue");
client.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode =
X509CertificateValidationMode.PeerOrChainTrust;
client.Open();
var header = new NOLWSAccountSvc.AuthenticationHeader()
{
application_id = applId,
password = pwd
};
var getActiveAccountsFunc = new NOLWSAccountSvc.getActiveAccounts() { applRef = "softact-dev", resetRows = true };
try
{
var response = client.getActiveAccounts(header, getActiveAccountsFunc);
Console.WriteLine(response.moreData);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
client.Close();
}
}
Thanks for your time! Your help will be highly appreciated.
#jdweng Yes, I did; here were two request bodies, first from .Net and 2nd from SoapUI:
.Net Request:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"><s:Header><h:Authentication u:Id="_2" xmlns:h="http://service.soap.xcompany.com" xmlns="http://service.soap.xcompany.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><application_id>testuserid</application_id><password>testpassword</password></h:Authentication><ActivityId CorrelationId="d7085e6f-b757-46e8-b3eb-319a51d568a3" xmlns="http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics">00000000-0000-0000-0000-000000000000</ActivityId><VsDebuggerCausalityData xmlns="http://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink">uIDPo8DAzaQVkApDpl1Tc1YTHQwAAAAAMbeMEvBLCUqoD7kEDPHDKYukgggNOf5FtHBB/Sa7ggkACQAA</VsDebuggerCausalityData><o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"><o:BinarySecurityToken u:Id="uuid-eb310312-396a-4d00-8922-f77de97138cb-3" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">MIIDYzCCAkugAwIBAgIEaGKzJDANBgkqhkiG9w0BAQsFADBiMQswCQYDVQQGEwJ1czEPMA0GA1UEChMGU3ByaW50MREwDwYDVQQLEwhQcm9qZWN0czEMMAoGA1UECxMDQk1QMQwwCgYDVQQLEwNUUEExEzARBgNV</o:BinarySecurityToken><Signature xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/><SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/><Reference URI="#_1"><Transforms><Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/></Transforms><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><DigestValue>WCpRwVjx89ceVctR8lp9LNGKHeA=</DigestValue></Reference><Reference URI="#_2"><Transforms><Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/></Transforms><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><DigestValue>8/PErh8BL9To5zazpP9CbPFTAa8=</DigestValue></Reference></SignedInfo><SignatureValue>hOtpz7lXvZPPbBD6sV1hxyx3Hc39vj0q2GYKMd8oQbgTbbuKC7QKcZOjktqUxayrzc6h/V0j7Kx3APPONe4F3A2581nK4AQ72yYonsaeXQW0yzSxW/VTsN04uoqCP6IpKXqlAz40VeWGUPJOeGthCKy/9A+NSuqS</SignatureValue><KeyInfo><o:SecurityTokenReference><o:Reference ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" URI="#uuid-eb310312-396a-4d00-8922-f77de97138cb-3"/></o:SecurityTokenReference></KeyInfo></Signature></o:Security></s:Header><s:Body u:Id="_1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><getActiveAccounts xmlns="http://service.soap.xcompany.com"><applRef>dev</applRef><resetRows>false</resetRows></getActiveAccounts></s:Body></s:Envelope>
SoapUI Request:
(somehow it won't let me past whole xml here.. )
Well, my colleague helped me figure out way to remove the extra headers from the request before it was posted to the Java SOAP service endpoint - the key was to use IClientMessageInspector and implement some logic in the BeforeSendRequest to remove the unwanted headers that were rejected by the service provider; then add a custom FormattingBehavior class to inherit from IEndpointBheavior and in the IEndPointBehavior.ApplyClientBehavior, attach the MyClientMessageInspector; finally add the customer endpoint behavior to the web service client. Here are the codes:
Where and how to remove unwanted request headers:
public class MyClientMessageInspector : IClientMessageInspector
{
public MyClientMessageInspector(ServiceEndpoint endpoint)
{
}
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
//Console.WriteLine(request.ToString());
var lstUnwantedStuff = new[]
{
new KeyValuePair<string, string>("Action", "http://www.w3.org/2005/08/addressing"),
new KeyValuePair<string, string>("VsDebuggerCausalityData",
"http://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink")
};
foreach (var kv in lstUnwantedStuff)
{
var indexOfUnwantedHeader = request.Headers.FindHeader(kv.Key, kv.Value);
if (indexOfUnwantedHeader>=0)
{
request.Headers.RemoveAt(indexOfUnwantedHeader);
}
}
...
Where and how to use the custom ClientMessageInspector:
internal class MyFaultFormatterBehavior : IEndpointBehavior
{
...
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
clientRuntime.MessageInspectors.Add(new MyClientMessageInspector(endpoint));
}
}
Where and how to attach custom EndpointBehavior:
private static void CallAccountService()
{
var client = new WSAccountv1Client(BuildCustomBinding(), GetAccountServiceEndpointAddress());
//Set client certificate
client.ClientCredentials.ClientCertificate.SetCertificate(StoreLocation.LocalMachine,
StoreName.Root, X509FindType.FindByThumbprint, "xxxxxxxxxx");
//for service certificate
client.ClientCredentials.ServiceCertificate.SetDefaultCertificate(StoreLocation.LocalMachine, StoreName.TrustedPeople,
X509FindType.FindByThumbprint, "xxxxxxxxxxxxxxxxy");
client.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode =
X509CertificateValidationMode.PeerOrChainTrust;
//add faultformattingbehavior so we can intercept the fault reply message
client.Endpoint.EndpointBehaviors.Add(new MyFaultFormatterBehavior());
client.Open();
var header = new AuthenticationHeader()
{
application_id = applId,
password = pwd
};
var getActiveAccountsFunc = new getActiveAccounts() { applRef = "test", resetRows = true };
try
{
//MyClientMessageInspector.BeforeSendRequest is entered when this called is made
var response = client.getActiveAccounts(header, getActiveAccountsFunc);
Console.WriteLine(response.moreData);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
client.Close();
}
}
What else?
In the proxy classes, need to set the Authentication ProtectionLevel to None while on the Service level it needs to be set as ProtectionLevel.Sign:
Request level:
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[System.ServiceModel.MessageContractAttribute(IsWrapped = false)]
public partial class getActiveAccountsRequest
{
[System.ServiceModel.MessageHeaderAttribute(Namespace = "http://service.xcompany.com"
, ProtectionLevel = System.Net.Security.ProtectionLevel.None
)]
public AuthenticationHeader Authentication;
Service (Interface) Level:
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(Namespace = "http://service.xcompany.com",
ConfigurationName = "WSAccount"
, ProtectionLevel = ProtectionLevel.Sign
)]
public interface WSAccount
{
I have created a simple app using REST in java which return string value successfully with REST client. Now I want to get string value using Http rest client in Angular2. I have created service for getting data from rest client in angular2 which saying successfully access rest but when I am printing data like {{serverData}} it's print nothing.
service.ts
#Injectable()
export class HttpSiftgridService {
private url:string = "http://localhost:8080/app-rest/rest /get/getData";
constructor(private _http: Http) {}
getSiftgridData() {
alert(this._http.get(this.url).map(res => res.json));
alert("hh");
return this._http.get(this.url).map(res => res.json);
}
private handleError(error : Response) {
console.error(error);
return Observable.throw(error.json().error || ' error');
}
}
app.component.ts
export class AppComponent implements OnInit{
serverData: string;
constructor(private _httpService:HttpSiftgridService) {}
ngOnInit() {
this._httpService.getSiftgridData()
.subscribe(
data => this.serverData = JSON.stringify(data),
error => console.log("Error in getting Data"),
() => console.log("Successfully")
);
}
}
my rest app running on tomcat.
Change:
return this._http.get(this.url).map(res => res.json);
To:
return this._http.get(this.url).map(res => res.json());
I know it's not a real answer but that wouldn't work as comment:
If you change it to
ngOnInit() {
this._httpService.getSiftgridData()
.subscribe(
data => {
this.serverData = JSON.stringify(data);
console.log(data);
},
error => console.log("Error in getting Data"),
() => console.log("Successfully")
);
}
is the data printed?
Is Successfully printed?