How to Integrate NetSuite and Salesforce using username and password? - salesforce

I want to integrate Netsuite with Salesforce, How to integrate using Netsiute username and password.
I have tried below code in salesforce but getting error code 500 please see the attach image.
String authHeader = 'NLAuth nlauth__account=xxxxxxx,nlauth_email=xxxnetsuiteusername#xxx.com,nlauth_signature=xxxpasswordxxx';
String endpoint = 'https://xxxxx.restlets.api.netsuite.com/app/site/hosting/restlet.nl?script=1501&deploy=1';
HttpRequest req = new HttpRequest();
req.setEndpoint(endpoint);
req.setMethod('GET');
req.setHeader('Content-Type','application/json');
req.setHeader('Authorization',authHeader);
req.setbody('body');
Http http = new Http();
HTTPResponse response = http.send(req);
System.debug('response Status: '+response.getStatusCode());
System.debug('response Body: '+response.getBody());
ERROR:Error

Related

IDP Initiated Login

I'm trying to implement an IDP Initiated login in my company, we hire a platform that generates a SAML XML response for me and posts it to my backend (.NET Core 3.1).
This SAML Response is a Base64 hash and has already been converted to XML. The lib has some specific method to deal with SAML response in this scenario?
Thanks!
It is more or less the samme as the TestWebAppCore sample expect to recive in the AssertionConsumerService method. The code show a post binding, you can change it to redirect if the authn response is send as a query parameter.
var binding = new Saml2PostBinding();
var saml2AuthnResponse = new Saml2AuthnResponse(config);
binding.ReadSamlResponse(Request.ToGenericHttpRequest(), saml2AuthnResponse);
if (saml2AuthnResponse.Status != Saml2StatusCodes.Success)
{
throw new AuthenticationException($"SAML Response status: {saml2AuthnResponse.Status}");
}
binding.Unbind(Request.ToGenericHttpRequest(), saml2AuthnResponse);
await saml2AuthnResponse.CreateSession(HttpContext, claimsTransform: (claimsPrincipal) => ClaimsTransform.Transform(claimsPrincipal));
var relayStateQuery = binding.GetRelayStateQuery();
//var some_value = relayStateQuery.ContainsKey("some_key");
return Redirect("...some_url...");

How to add an organizer to Online meeting created using Microsoft Graph API

I have an admin account to create Online meetings of Graph API. Suppose I want to create online meetings for others to be the organizer, how should I do it? I do not see any parameter for that while creating the meeting.
You can request /me/onlineMeetings/createOrGetAPI, and then add the organizer to the request body.
please see: here
Try this:
var client = new RestClient("https://graph.microsoft.com/v1.0/me/onlineMeetings");
var request = new RestRequest(Method.POST);
request.AddHeader("cache-control", "no-cache");
request.AddHeader("content-type", "application/json");
request.AddHeader("authorization", "Bearer "+token);
request.AddHeader("accept-language", "en");
request.AddHeader("accept", "application/json");
request.AddParameter("application/json", "{\"startDateTime\": \"2020-09-
28T19:30:34.2444915-07:00\",\n\"endDateTime\": \"2020-09-
28T20:00:34.2464912-07:00\",\"subject\": \"User Token Meeting\"}",
ParameterType.RequestBody);
var response = client.Execute(request);
To retrieve the token:
var client = new RestClient("https://login.microsoftonline.com/{tenant-
Id}/oauth2/v2.0/token");
var request = new RestRequest(Method.POST);
request.AddHeader("cache-control", "no-cache");
request.AddHeader("content-type", "application/x-www-form-urlencoded");
request.AddHeader("grant_type", "password");
request.AddParameter("application/x-www-form-urlencoded",
"grant_type=password&client_id={client-Id}&client_secret={client-
secret}&scope={scopeurl}&userName={username}&password={password}",
ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
var json = response`.`Content;
var JSONObject = JObject.Parse(json);
var token = (string)JSONObject["access_token"];

Azure B2C - 401 unauthorised trying to read id_token in code after logging in

I am trying to use the token granted by a secured AAD domain when using my web app
I followed the advice on this link: Retrieve Access Token within a AAD secured Azure Web App
I have managed to get as far as logging in and verifying the ./me URL correctly shows me my token
However when I try and call same token in code I get 401 unauthorised
I have been using the Resource Explorer to configure the additionalLoginParams and have tried to put the app ID as well as the graph URL but nothing has solved the problem
async public Task<string> GetToken()
{
HttpClient _client = new HttpClient();
string _token = "";
HttpResponseMessage response = await _client.GetAsync("https://alfreton.azurewebsites.net/.auth/me");
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
ReadUserToken readUserToken = new ReadUserToken();
readUserToken = JsonConvert.DeserializeObject<ReadUserToken>(responseBody);
_token = readUserToken.id_token;
return _token;
}
}
}
EDIT Following the advice below the code now looks like this but I am still getting an Unauthorized error messsage
async public Task<string> GetToken()
{
HttpClient _client = new HttpClient();
string _token = "";
string accessToken = this.Request.Headers["X-MS-TOKEN-AAD-ACCESS-TOKEN"];
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
HttpResponseMessage response = await _client.GetAsync("https://alfreton.azurewebsites.net/.auth/me");
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
ReadUserToken readUserToken = new ReadUserToken();
readUserToken = JsonConvert.DeserializeObject<ReadUserToken>(responseBody);
_token = readUserToken.id_token;
return _token;
}
When I read through the headers, I find there is X-MS-TOKEN-AAD-ID-TOKEN - can I use that to get an access token?
I agree with #juunas, the URL expects the authentication cookie to be passed in the request when you aceess ./me URL.
The provider-specific tokens are injected into the request header, so you can easily access them. Your provider is AAD, so it should be
string accessToken = this.Request.Headers["X-MS-TOKEN-AAD-ACCESS-TOKEN"];
OK I figured it out, what I needed to do is get X-MS-TOKEN-AAD-ID-TOKEN from the Request Headers after logging in then pass that in as the Bearer and that in turn got me a X-MS-TOKEN-AAD-ACCESS-TOKEN which I can use for accessing the API
Thanks loads!

Getting Forbidden/Access Denied error from Azure AD Graph Education API

I am using Graph education API, want all information about the user
profile.
Getting below error in response/json objects
Forbidden
AccessDenied
Required claim values are not provided.
public async Task<ActionResult> GetUserDetails()
{
List<User> listUser = new List<User>();
List<UserRole> userRole = new List<UserRole>();
string clientId = configuration.GetValue<string>("AzureAd:ClientId");
string clientSecret = configuration.GetValue<string>("AzureAd:ClientSecret");
//var email = User.Identity.Name;
//AuthenticationContext authContext = new AuthenticationContext("https://login.windows.net/LPExamDev.onmicrosoft.com/oauth2/token");
AuthenticationContext authContext = new AuthenticationContext("https://login.windows.net/LPExamStaging.onmicrosoft.com/oauth2/token");
ClientCredential creds = new ClientCredential(clientId, clientSecret);
AuthenticationResult authResult = await authContext.AcquireTokenAsync("https://graph.microsoft.com/", creds);
HttpClient http = new HttpClient();
string url = $"https://graph.microsoft.com/v1.0/education/users"; // Microsoft Education Graph
//string url = $"https://graph.microsoft.com/v1.0/users"; // Microsoft Graph // Working fine.
////string url = "https://graph.windows.net/LPExamStaging.onmicrosoft.com/users?api-version=1.6";
// Append the access token for the Graph API to the Authorization header of the request by using the Bearer scheme.
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, url);
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", authResult.AccessToken);
HttpResponseMessage response = await http.SendAsync(request);
var json = await response.Content.ReadAsStringAsync();
var jsonResponse = response.ToString();
bool responseCode = response.IsSuccessStatusCode;
//ViewBag.userData = json;
//SaveAPIData(json);
if (responseCode)
{
SaveAPIData(json);
}
}
You need to grant your application EduRoster.Read.All permission and click grant admin consent button.
Login azure portal->click Azure Active Directory->click App registrations(preview)->click your application->click API permissions->add a permission->choose Application permissions
Then click Grant admin consent button.
You can decoded your access token by using https://jwt.io/ to check if you have already got that permission.

No shared secret configured for client for IdentityServer4's reference token

I'm using IdentityServer4 with IdentityServer4.AccessTokenValidation for handling Reference Token.
This is what I have done in Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
// Add identity server 4.
services.AddIdentityServer()
.AddProfileService<IdentityServerProfileService>()
.AddInMemoryClients(LoadInMemoryIdentityServerClients())
.AddInMemoryApiResources(LoadInMemoryApiResources())
.AddInMemoryIdentityResources(LoadInMemoryIdentityResource())
.AddProfileService<IdentityServerProfileService>()
.AddResourceOwnerValidator<ResourceOwnerPasswordValidator>()
.AddDeveloperSigningCredential();
// Add jwt validation.
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddIdentityServerAuthentication(options =>
{
// base-address of your identityserver
options.Authority = "https://localhost:44386";
options.ClaimsIssuer = "https://localhost:44386";
// name of the API resource
options.ApiName = "api1";
options.ApiSecret = "web-api-secret";
options.RequireHttpsMetadata = false;
});
}
protected static IEnumerable<Client> LoadInMemoryIdentityServerClients()
{
var clients = new List<Client>();
var client = new Client();
client.ClientId = "web-api-client";
client.AllowedGrantTypes = GrantTypes.ResourceOwnerPassword;
client.ClientSecrets = new[] {new Secret("web-api-secret".Sha256())};
client.AccessTokenType = AccessTokenType.Reference;
client.AllowedScopes = new[]
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.Email,
IdentityServerConstants.StandardScopes.Address,
"api1"
};
clients.Add(client);
return clients;
}
protected static IEnumerable<IdentityResource> LoadInMemoryIdentityResource()
{
//var profileIdentityResource = new IdentityResource("repository-read", "repository-read", new List<string> { "claim-01", "age" });
return new List<IdentityResource>
{
new IdentityResources.OpenId(),
new IdentityResources.Profile()
//profileIdentityResource
};
}
protected static IEnumerable<ApiResource> LoadInMemoryApiResources()
{
var apiResources = new List<ApiResource>();
var apiResource = new ApiResource("api1", "My API");
apiResource.UserClaims = new[]
{
"age"
};
apiResources.Add(apiResource);
return apiResources;
}
When I make a request with structure shown in the below image:
I received a token.
After using the received token to make a request to protected api resource api/user/search. It gave me 401 status code.
In visual studio output. This is what I saw:
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 POST http://localhost:56219/api/user/search application/json 5
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 10.9132ms 307
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 POST https://localhost:44386/api/user/search application/json 5
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 POST https://localhost:44386/connect/introspect application/x-www-form-urlencoded 143
IdentityServer4.AccessTokenValidation.IdentityServerAuthenticationHandler:Debug: AuthenticationScheme: Bearer was not authenticated.
IdentityServer4.AccessTokenValidation.IdentityServerAuthenticationHandler:Debug: AuthenticationScheme: Bearer was not authenticated.
IdentityServer4.Hosting.EndpointRouter:Debug: Request path /connect/introspect matched to endpoint type Introspection
IdentityServer4.Hosting.EndpointRouter:Debug: Endpoint enabled: Introspection, successfully created handler: IdentityServer4.Endpoints.IntrospectionEndpoint
IdentityServer4.Hosting.IdentityServerMiddleware:Information: Invoking IdentityServer endpoint: IdentityServer4.Endpoints.IntrospectionEndpoint for /connect/introspect
IdentityServer4.Endpoints.IntrospectionEndpoint:Debug: Starting introspection request.
IdentityServer4.Validation.BasicAuthenticationSecretParser:Debug: Start parsing Basic Authentication secret
IdentityServer4.Validation.PostBodySecretParser:Debug: Start parsing for secret in post body
IdentityServer4.Validation.SecretParser:Debug: Parser found secret: PostBodySecretParser
IdentityServer4.Validation.SecretParser:Debug: Secret id found: api1
IdentityServer4.Validation.HashedSharedSecretValidator:Debug: No shared secret configured for client.
IdentityServer4.Validation.SecretValidator:Debug: Secret validators could not validate secret
IdentityServer4.Validation.ApiSecretValidator:Error: API validation failed.
IdentityServer4.Endpoints.IntrospectionEndpoint:Error: API unauthorized to call introspection endpoint. aborting.
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 57.8551ms 401
IdentityModel.AspNetCore.OAuth2Introspection.OAuth2IntrospectionHandler:Error: Error returned from introspection endpoint: Unauthorized
IdentityModel.AspNetCore.OAuth2Introspection.OAuth2IntrospectionHandler:Information: BearerIdentityServerAuthenticationIntrospection was not authenticated. Failure message: Error returned from introspection endpoint: Unauthorized
IdentityServer4.AccessTokenValidation.IdentityServerAuthenticationHandler:Information: Bearer was not authenticated. Failure message: Error returned from introspection endpoint: Unauthorized
IdentityServer4.AccessTokenValidation.IdentityServerAuthenticationHandler:Information: Bearer was not authenticated. Failure message: Error returned from introspection endpoint: Unauthorized
IdentityServer4.AccessTokenValidation.IdentityServerAuthenticationHandler:Information: Bearer was not authenticated. Failure message: Error returned from introspection endpoint: Unauthorized
Microsoft.AspNetCore.Routing.EndpointMiddleware:Information: Executing endpoint 'QrApi.Controllers.UserController.SearchUsersAsync (QrApi)'
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Route matched with {action = "SearchUsersAsync", controller = "User"}. Executing action QrApi.Controllers.UserController.SearchUsersAsync (QrApi)
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService:Information: Authorization failed.
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'.
Microsoft.AspNetCore.Mvc.ChallengeResult:Information: Executing ChallengeResult with authentication schemes ().
IdentityModel.AspNetCore.OAuth2Introspection.OAuth2IntrospectionHandler:Information: AuthenticationScheme: BearerIdentityServerAuthenticationIntrospection was challenged.
IdentityServer4.AccessTokenValidation.IdentityServerAuthenticationHandler:Information: AuthenticationScheme: Bearer was challenged.
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Executed action QrApi.Controllers.UserController.SearchUsersAsync (QrApi) in 10.8603ms
Microsoft.AspNetCore.Routing.EndpointMiddleware:Information: Executed endpoint 'QrApi.Controllers.UserController.SearchUsersAsync (QrApi)'
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 135.7991ms 401
I have found tutorials about reference token, but none of them help me to solve this case.
What am I missing ?
Thank you,
Seems to be my configuration is invalid for API Resource.
This is my original setting for API Resources:
protected static IEnumerable<ApiResource> LoadInMemoryApiResources()
{
var apiResources = new List<ApiResource>();
var apiResource = new ApiResource("api1", "My API");
apiResource.UserClaims = new[]
{
"age"
};
apiResources.Add(apiResource);
return apiResources;
}
After having added the shared secret key which has been defined in client.ClientSecrets = new[] {new Secret("web-api-secret".Sha256())}; to apiResource:
protected static IEnumerable<ApiResource> LoadInMemoryApiResources()
{
//...
var apiResource = new ApiResource("api1", "My API");
api1Resource.ApiSecrets.Add(new Secret("web-api-secret".Sha256()));
//...
}
I could make request to protected resources successfully.
Hope this helps someone who is struggling with IdentityServer4 as I did.
My solution was to add the secret when instantiating the API resource.
protected static IEnumerable<ApiResource> LoadInMemoryApiResources()
{
var apiResources = new List<ApiResource>();
var apiResource = new ApiResource("api1", "My API"){
ApiSecrets = new List<Secret>{
new Secret("web-api-secret".Sha256())
},
Scopes = {
new Scope("openid")
}
};
apiResources.Add(apiResource);
return apiResources;
}
It looks like the issue could be that you don't have an API secret configured. In your config file change the API resource to match the configuration below. I believe to communicate with the introspection endpoint the api secret is required.
return new List<ApiResource>
{
new ApiResource("api1", "My API")
{
ApiSecrets = new List<Secret>
{
new Secret("secret".Sha256())
}
}
};

Resources