JayData Web API Error $metadata - jaydata

I get the following error from JayData.
Object {requestUri: "/api/program/getprograms/$metadata", statusCode: 404, statusText: "Not Found", responseText: "<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Stric…↵ </fieldset> ↵</div> ↵</div> ↵</body> ↵</html> ↵"}
This is how I am calling the service. Any idea what I am doing wrong?
$data.service("/api/program/getprograms", function (contextFactory) {
var remotecontext = contextFactory();
remotecontext.Program.filter("it.Program.ProgramID == '1'");
context.Programs.forEach(function (program) {
console.log(program);
});
});
I also tried:
var remotedb = new AppContext({ provider: 'webApi', databaseName: 'RemoteDB', dataSource: '/api/program/getprograms' });

$data.service() and $data.initService() was created to generate dynamic client-side data model on the fly. This is the alternative to generate static data model with JaySvcUtil.exe.
This won't work with WebAPI endpoints and webApi provider since there is no metadata service in WebAPI. The $metadata service is available only in OData endpoints, for WebAPI, you have to build you client-side data model manually.

Related

protect asp.net web api 2 project with identity server 4

I have an asp.net web api 2 project with .Net framework 4.8 and a centralized Identity Server 4 project. I want to validate jwt/access token generated from IS4 in my web api 2 project. I can understand its a duplicate question but somehow I am unable to find any suitable help and I am not sure what's missing. I have used IdentityServer3.AccessTokenValidation for token validation in web api project.
Startup.cs
using IdentityServer3.AccessTokenValidation;
using Microsoft.Owin;
using Owin;
[assembly: OwinStartup(typeof(WebApplicationApiNew.Startup))]
namespace WebApplicationApiNew
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
{
Authority = "https://localhost:44373",
RequiredScopes = new[] { "api1" },
});
}
}
}
Calling this API with a valid JWT bearer token still gives 401:
[Authorize]
[HttpPost]
public String GetName1()
{
if (User.Identity.IsAuthenticated)
{
var identity = User.Identity as ClaimsIdentity;
if (identity != null)
{
IEnumerable<Claim> claims = identity.Claims;
}
return "Valid";
}
else
{
return "Invalid";
}
}
Error details:
2021-07-24 20:41:25.4133|DEBUG|Microsoft.Owin.Security.OAuth.OAuthBearerAuthenticationMiddleware|Authentication failed
Microsoft.IdentityModel.Tokens.SecurityTokenInvalidAudienceException: IDX10214: Audience validation failed. Audiences: '[PII is hidden. For more details, see https://aka.ms/IdentityModel/PII.]'. Did not match: validationParameters.ValidAudience: '[PII is hidden. For more details, see https://aka.ms/IdentityModel/PII.]' or validationParameters.ValidAudiences: '[PII is hidden. For more details, see https://aka.ms/IdentityModel/PII.]'.
at Microsoft.IdentityModel.Tokens.Validators.ValidateAudience(IEnumerable`1 audiences, SecurityToken securityToken, TokenValidationParameters validationParameters)
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateAudience(IEnumerable`1 audiences, JwtSecurityToken jwtToken, TokenValidationParameters validationParameters)
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateTokenPayload(JwtSecurityToken jwtToken, TokenValidationParameters validationParameters)
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateToken(String token, TokenValidationParameters validationParameters, SecurityToken& validatedToken)
at Microsoft.Owin.Security.Jwt.JwtFormat.Unprotect(String protectedText)
at Microsoft.Owin.Security.OAuth.OAuthBearerAuthenticationHandler.<AuthenticateCoreAsync>d__3.MoveNext()
The error shows:
IDX10214: Audience validation failed
If your JWT token contains an "aud" claim, the authentication middleware
is attempting to validate the audience claim, but there is no audience specified in your options. Can you try one of the following:
Set an audience in the options:
Audience = "[your audience]"
Disable audience validation in the options:
TokenValidationParameters.ValidateAudience = false;
Refer to the identity server documentation for more details:
https://docs.identityserver.io/en/latest/topics/apis.html
I found solution to my problem. IS3 requires aud claim (with /resources in url) to be present in jwt/access token in order to validate the token. But on the other side IS4 has stopped emitting the aud claim by default. So we need to explicitly set IS4 server to emit aud claim to support legacy/old access token validation with IdentityServer3.AccessTokenValidation.
services.AddIdentityServer(options =>
{
...
options.EmitStaticAudienceClaim = true; // <- for older access token validation
})
.AddDeveloperSigningCredential()
.AddInMemoryPersistedGrants()
.AddInMemoryIdentityResources(Config.GetIdentityResources())
...

Bearer Tokens in C++Builder/FMX REST Functionality?

I have a server application running in node.js/Mongoose/MongoDB with a REST interface.
My client application is built in Embarcadero C++Builder/Firemonkey(FMX) and so far all is good with interacting with the node server using the embarcadero REST features (TRESTClient/TRESTRequest/TRESTResponse).
I recently added authentication to my server using JSON Web tokens and the user registration/login is working successfully, giving me back a bearer token using the following code:
const token = jwt.sign({sub: user.id}, process.env.JWT_SECRET, {expiresIn: '30d' })
Accessing data is implemented via express-jwt by sending a REST request with the bearer token. Postman makes it easy to send a request for data using a Bearer token (https://learning.postman.com/docs/sending-requests/authorization/#bearer-token), however I cannot find out how to do this seemingly simple task using Embarcadero's REST features.
I have tried using the Embarcadero REST OAUTH/OAUTH2/SIMPLE/BASIC authentication methods with the bearer token in the Access-Token and Request-Token fields and nothing seems to work.
How can this be done? I am sure this is something simple I am missing but there is next to no documentation I can find.
I figured out an answer for anyone else who is having trouble using authentication in C++Builder with REST:
Design-time method:
--> Setup TRESTClient, TRESTRequest, TRESTResponse
--> In TRESTRequest Params, create a new param with fields:
Name: Authorization, Value: Bearer XXXXXXXX (JWT String), Options: poDoNotEncode (this is the important part
Creating the REST client for authorization at runtime:
// initialize REST client
TRESTClient* pRESTClient = new TRESTClient(BASE_URL);
pRESTClient->ContentType = "application/json";
// connect REST request for querying server
TRESTRequest* pRESTRequest = new TRESTRequest(NULL);
pRESTRequest->Client = pRESTClient;
// connect REST response for receiving JSON from server
TRESTResponse* pRESTResponse = new TRESTResponse(NULL);
pRESTRequest->Response = pRESTResponse;
pRESTResponse->ContentType = "text/html";
// do authenticated query
pRESTRequest->Method = rmGET;
pRESTRequest->Resource = ROUTE_ITEMS;
pRESTRequest->ResourceSuffix = SUBROUTE_ITEMSUFFIX;
pRESTRequest->Params->Clear();
TRESTRequestParameter* param = pRESTRequest->Params->AddItem();
param->Name = "Authorization";
param->ContentType = ctNone;
param->Kind = pkHTTPHEADER;
param->Options << poDoNotEncode;
char temp[512];
sprintf(temp, "Bearer %s", JWT_TOKEN);
param->Value = (const char*)temp;
pRESTRequest->Execute();
The server response is then added to the TRESTResponse->Content field as JSON.
As a note, it is important to have the server configured with express-JWT (https://www.npmjs.com/package/express-jwt) for this to work properly with the following code managing the server (node.js):
app.use(jwt({
secret: process.env.JWT_SECRET,
credentialsRequired: false,
getToken: function fromHeaderOrQuerystring (req) {
if (req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Bearer') {
return req.headers.authorization.split(' ')[1];
} else if (req.query && req.query.token) {
return req.query.token;
}
return null;
}
}));

How to integrate Spring MVC and Nuxt JS?

I have learnt Nuxt JS and Spring MVC. I want to know, how to make a single page web application integrating or configuring Spring MVC and Nuxt JS. I didn't find any well documented material over internet. Basically, I want to handle all CRUD operations asynchronously. Database is MySQL. If possible, can someone help me how to do this? Thank you in advance!
I hope this will answer you, if I understand your question correctly.
Assuming, you have written the data access operations using Spring, Nuxt Js runs on port 3000, Tomcat on port 8080.
Let's say this is our RestController which fetches users data from database (using repository, service layer). Note the use of CrossOrigin - enabling cross origin request for restful web service which includes headers for Cross-Origin Resource Sharing (CORS) in the response. Here, we only allow localhost:3000 to send cross-origin requests. You can also go for Global CORS configuration.
#RestController
#RequestMapping("api")
#CrossOrigin(origins = "http://localhost:3000")
public class MainRestController {
private final IRestService restService;
#Autowired
public MainRestController(IRestService restService) {
this.restService = restService;
}
#GetMapping(value = "users", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Iterable<String>> getUsers() {
try {
return new ResponseEntity<>(restService.getAllUsers(), HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
}
}
As you are using Nuxt js, this is our vue component which tries to access our REST end point which we created above. We are using axios to get our response here.
<template>
<div class="container">
<ul>
<li v-for="user of users">
{{user}}
</li>
</ul>
</div>
</template>
<script>
export default {
async asyncData({ $axios }) {
const users = await $axios.$get('http://localhost:8080/api/users');
return { users }
}
}
</script>
Your nuxt.config.js should contain this: the axios and proxy module should be installed.
modules: [
'#nuxtjs/axios',
'#nuxtjs/proxy'
],
axios: {
proxy: true,
},
env: {
baseUrl: process.env.BASE_URL || 'http://localhost:3000'
},
proxy: {
'/api/': {
target: 'http://localhost:8080/',
pathRewrite: { "^/api": "" },
changeOrigin: true,
}
},

Credential Validation from database in Oracle JET

I have created a sample application in Oracle JET which would route to the homepage upon login.
I want to validate the user credentials(username and password) with the table in the database using RESTful web services and only upon successful validation I want the application to be routed to the homepage.
Since I am new to Oracle JET and have less knowledge about integrating and validating user input with the data in the database, it would be a great if someone could help me with this. Thank you.
You can use ajax method to call restful web services.
Here is an sample that can help you.
self.username = ko.observable("");
self.password = ko.observable("");
self.login = function(data, event)
{
$.ajax({
url: "https://restservicesforlogin?username="+self.username()+"&userpwd="+self.password()+"",
type: 'GET',
headers: {
your headers Details
},
success: function(data)
{
if(self.ERROR_CODE()=='S')
{
oj.Router.rootInstance.go('homePage');
}
if(self.ERROR_CODE()=='E')
{
alert("Invalid username/password");
self.isLoggedIn(false);
}
},
error: function(jqXHR, exception)
{
alert("Internal Server Error") ;
}
})
}

Bad request when trying to post to wcf rest 4 service

I am playing with the wcf 4.0 rest template and trying to get it to work with jquery.
I have created a new rest template project and added a webform into the same project just to get things simple.
I have slightly modfied the Create Method to look like this
[WebInvoke(UriTemplate = "", Method = "POST")]
public string Create(SampleItem instance)
{
// TODO: Add the new instance of SampleItem to the collection
return (instance.Id == 1) ? "1 was returned" : "something else was returned";
}
Then from my webform I am using this.
<script type="text/javascript">
$(document).ready(function () {
$.ajax({
type: 'POST',
url: "/service1/",
data: { "Id": 1,"StringValue": "String content"
},
success: function (data) {
$('.result').html(data);
},
error: function (error) {
$('.result').html(error)
},
dataType: "json",
contentType: "application/json; charset=utf-8"
});
});
</script>
<div class="result"></div>
However fiddler is returning a 400 error telling me there is a request error. Have I done something wrong?
400 can also mean something in your service went wrong. Did you try to attach a debugger to the Rest-service?
Tried to create a .Net-console application (create the request using HttpClient) and communicate with your service?
I ran into same error, after half hour of testing I saw just some error occured in the REST-service.