I'm still trying to get my head around OWIN, and in particularly why would I want to configure CORS thru OWIN using the CorsMiddleware:
appBuilder.UseCors(…)
Instead of just keep using the HttpConfiguration, like this:
var config = new HttpConfiguration();
config.EnableCors(…);
appBuilder.UseWebApi(config);
Given that the latter is compatible with both EnableCors and DisableCors attributes, which gives you a more fine-grained control (at least I haven't been able to find a way to configure the CorsMiddleware in a per Controller basis).
If the Web API CORS stuff works for you then just use it. The only reason to use the Owin Middleware is if you app framework doesn't support it, or if you have multiple apps hosted together and would rather have you one CORS handler.
Owin middleware allows the writers of the middleware to only have to write it once, not for each framework. As a consumer it doesn't add much value to you.
Related
I'm new to url rewriting process in Marklogic and need help to resolve the below issue.
I have written Xquery implementation to redirect my API endpoints to the respective Xquery modules as /rewriter-ex/rewriter.xqy.
xquery version "1.0-ml";
let $url := xdmp:get-request-url()
return if(fn:matches($url,"/fetchRecord")) then
fn:replace($url,"/fetchRecord","/lib/fetch-record.xqy$1")
else if(fn:matches($url,"/saveRecord")) then
fn:replace($url,"/saveRecord$","/lib/save-record.xqy")
else (xdmp:set-response-code(404, "Not found"),"/no/such/resource")
And the url-rewriter path in the App server configuration is set to /rewriter-ex/rewriter.xqy and rewrite resolves globally parameter is set to true in App server.
I'm able to redirect my API urls to the respective endpoints.But I'm not able to use predefined ML Res-API endpoints like /v1/documents,it is showing 404 error as returned in the rewriter.xqy.
Is there a way I can implement rewriter to support both rest api endpoints as well as custom API endpoints?
If you'd like to create your own RESTful API on top of MarkLogic, with your own custom end-points. Please check out XQuery API for RESTful Services (XQRS).
declare
%rest:path("/fetchRecord/{$record-id}")
%rest:GET
function fetch-record($record-id as xs:string) {
fn:doc($record-id)
};
declare
%rest:path("/saveRecord/{$record-id}")
%rest:PUT("{$doc}")
%xdmp:update
function put-record($record-id as xs:string, $doc as document-node(element())) {
xdmp:document-insert($record-id, $doc)
};
Your RESTXQ Modules can sit on their own separate HTTP App Server (on their own port) and live side by side with another HTTP App Server which has the default MarkLogic REST API on it.
XQRS is totally compatible with the rest of MarkLogic's software, including Data Hub Framework, they can party together.
The REST API doesn't support customization or replacement of the default declarative rewriter configured during initialization of a REST API server. In addition, the REST API doesn't provide an XQuery API interface to the functionality of the REST API endpoints.
Instead, the recommended approach is to extend the REST API through one of the following alternatives:
Providing an endpoint module in the modules database and specifying the actual path of the module in the modules database on a request to the REST API server to invoke the endpoint without rewriting as in http://myhost:8010/the/directory/path/to/my/module.xqy
Such endpoints can be Data Service endpoints. See https://docs.marklogic.com/guide/java/DataServices
Using the /v1/invoke endpoint to invoke a main module. See https://docs.marklogic.com/guide/rest-dev/extensions#id_72813
Using a Resource Service Extension. See https://docs.marklogic.com/guide/rest-dev/extensions#id_41710
Hoping that helps,
Thanks for your answers.I'm planning to use two app servers one for rest calls and other for API calls.These two app servers will point to the same DB.Please let me know if this is a right approach.
I have already working ASP.net Web API (.Net Framework 4.6.1) Application, And already have some "DelegatingHandler"s and "ActionFilterAttribute"s working on it to handle Authentication, and Validation filters.
I need to change Some error Messages like 404 default message :
No HTTP resource was found that matches the request URI 'https://example.com/api/someWrongUrlAction'.
So, I read about OWIN middleware, but I'm afraid of using it, and need to know will it affect any other working functionality or hosting settings? will it affect the already exists "DelegatingHandler" MessageHandlers ? or "ActionFilterAttribute" Filters?
Note: I need to use the OWIN middleware only for that purpose, but
I'll keep hosting in IIS as it is.
To be fair I'm not really sure why do you need an owin here. You could use either IIS tools (it will manage such routes in a best way) or you could use some of fallback approaches provided by MVC framework:
MVC 6 Routing, SPA fallback + 404 Error Page
or
Fallback route for MVC Areas
or
google like 'mvc fallback route' ;-)
Regarding your question. You can host OWIN application in the IIS. You might need to switch your application to support owin pipeline. Do not think you will be able to merge both approaches inside the same application.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I consider my self a rank beginner to OWIN and after reading a lot of documentation I have only gotten more confused with conflicting notions than before I began. I know these are multiple questions, but I feel answering these will clear most fundamental doubts regarding OWIN and how to best use it. Here are my questions:
What can I use OWIN middleware for that I couldn't already do using
message handlers or HTTP modules? Or are they both the same thing
except that the latter two are tightly coupled with IIS?
A lot of the documentation says OWIN allows for decoupling between
the web server and web application ie. removing dependency on IIS
for hosting say Web API applications. But I have yet to see an
example of some web application or web api that used OWIN and was
successfully ported from being hosted on IIS and then some other web
server. So is IIS and self hosting the only way to go for this
decoupling between web server and web app?
When I searched for OWIN middleware examples, I only got Katana and
Helios which are the only two implementations of the OWIN spec.
Katana is almost done with and wont go beyond revision3 and Helios is not yet supported by
Microsoft as per some articles. So what is the future of OWIN in
that case?
The only detailed practical usage I have seen so far is that of
using OWIN for authentication using OAuth 2. Any other such usages
of keeping an OWIN implementation in the middle?
In my startup class's Configuration method I tried to chain simple
middleware code snippets as below and to be able to see the request
being sent in :-
but got errors:
How do I see the request coming in and modify it for the next component in the middleware?
What are the various kinds of middle ware that you have plugged-in
in your projects between the web server and application?
Thanks for answering any or all of these above.
What can I use OWIN middleware for that I couldn't already do using message handlers or HTTP modules? Or are they both the same thing except that the latter two are tightly coupled with IIS?
Decoupling with IIS is part of it. OWIN middleware is a pipeline that allows certain things that are "OWIN aware" to be involved in the request, if they choose. IHttpHandler's handle a single thing - they were not chain-able. I like to compare the pipeline more to Global.asax. I've seen a lot of stuffed Global.asax handlers doing all sorts of things like authentication, authorization, spitting out HTTP headers like P3P policies, X-Frame-Options, etc. Part of the problem with this is developing reusable components from that was difficult and depended on IIS. OWIN attempts to remove those issues.
A lot of the documentation says OWIN allows for decoupling between the web server and web application ie. removing dependency on IIS for hosting say Web API applications. But I have yet to see an example of some web application or web api that used OWIN and was successfully ported from being hosted on IIS and then some other web server. So is IIS and self hosting the only way to go for this decoupling between web server and web app?
That's true for WebAPI 2 and SignalR 2. MVC 5 and older can't really be decoupled from IIS at the moment. MVC 6 will resolve this issue and is a pretty big overhaul. The ASP.NET Website has a tutorial or two on SignalR self hosting on a Console app. You'll see in the tutorial a Startup class, just as if it were running on IIS or IIS Express. The only thing the Console App does differently is it is bootstrapping a server with HttpListener in the Main method.
[comment] With respect to point #2 above, what are the owin components here? Is Katana an owin component or is it the code we write using Katana or both put together?
OWIN is really not much more an an abstraction layer, really a specification, between the web application and the web server. There are different "implementations" of OWIN depending on the server you want to run on - Katana is an OWIN implementation that runs WebAPI 2 and SignalR 2. Kestrel is another example of an OWIN implementation.
When I searched for OWIN middleware examples, I only got Katana and Helios which are the only two implementations of the OWIN spec. Katana is almost done with and wont go beyond revision3 and Helios is not yet supported by Microsoft as per some articles. So what is the future of OWIN in that case?
That's still a bit up-in-the-air, but OWIN is being used to develop the Kestrel web server that allows ASP.NET 5 Core to run on Linux / OS X.
The only detailed practical usage I have seen so far is that of using OWIN for authentication using OAuth 2. Any other such usages of keeping an OWIN implementation in the middle?
SignalR and WebAPI also use OWIN. This is useful so that you can run a SignalR Hub as a Windows Service, same goes for Web API.
Any other such usages of keeping an OWIN implementation in the middle?
Platform Independence. Having OWIN in the middle means I can literally xcopy my MVC 6 Core web application from running on IIS to Kestrel on my Mac, and the OWIN implementation takes care of the rest.
In my startup class's Configuration method I tried to chain simple middleware code snippets as below and to be able to see the request being sent in.
context.Request does not have an indexer in OWIN. Use Get<> instead:
app.Use(async (context, next) =>
{
context.Response.Write("hello world 2: " + context.Request.Get<object>("owin.RequestBody"));
await next();
});
Note that owin.RequestBody is a bit of an implementation detail, the actual return type is internal. I'm not sure what you are attempting to get, if you want a query string, use Query from the request, or Headers if you want an HTTP header.
What are the various kinds of middle ware that you have plugged-in in your projects between the web server and application?
Things for handling security, like a middleware component that handled nonces in Content Security Policy, which I wrote about on my personal blog here. The gist of it was it allows me to add an HTTP header with a nonce:
public void Configuration(IAppBuilder app)
{
app.Use((context, next) =>
{
var rng = new RNGCryptoServiceProvider();
var nonceBytes = new byte[16];
rng.GetBytes(nonceBytes);
var nonce = Convert.ToBase64String(nonceBytes);
context.Set("ScriptNonce", nonce);
context.Response.Headers.Add("Content-Security-Policy",
new[] {string.Format("script-src 'self' 'nonce-{0}'", nonce)});
return next();
});
//Other configuration...
}
From there, in my Razor views I could add the nonce to <script> elements get getting the token from the owin context.
There are lots of other things it can be used for. Other frameworks can easily inject themselves into the request / response process now. The NancyFx framework can use OWIN now.
I want to create a WebAPI service for use in my single page application but I also want it to be available for a mobile application too.
When users are using the SPA they are signed in using forms authentication and have a session cookie but if they're using the mobile application this wont be the case.
Is it possible to expose the same API controller as 2 different endpoints where one is authenticated using mutual SSL, a token or as a last resort basic auth and the other uses the session cookie?
For example take the following controller:
public class TodoController :
{
public IQueryable<TodoModel> GetTodos()
{
...
}
}
Can I add multiple routes that map to the same method?
https://myapp.example.org/api/todo
https://myapp.example.org/mutual-auth/api/todo
I want to configure IIS to use mutual SSL for the mutual auth endpoint and use forms authentication for the other endpoint.
Short answer: yes
This is a very broad question, so I won't go into excessive detail about every aspect. I think you should also take a look at BreezeJS because it makes things building these applications significantly easier.
DESIGN
Do you want to build in pure HTML and JavaScript or incorporate CSHTML? The decision is yours, but if you want to eventually create native-based applications using something such as PhoneGap Build, you'll want to stick to pure HTML and JavaScript so that you can compile the code later.
Do you want to use another JS library such as BreezeJS to make life a little easier when designing your controllers? Out of the box, your Web API controllers will be prefixed with api/{controller}/{id} in WebApiConfig. You may want to add {action} routing if you don't go with something like BreezeJS so that you can have more flexibility with your controllers.
Lastly, let's talk about the Repository Pattern and Unit of Work Pattern. This is a bit of hot-topic, but I find that usually creating a repository allows you a great deal of flexibility and it's great for dependency injection. Adding an additional repository layer to your controllers allows you to differentiate between different users or means of access such as a SPA or mobile application very easily. You can use the exact same controllers, but simply draw from different repositories.
SECURITY
You'll want to touch up a bit on [Authorize], [ValidateHttpAntiForgeryTokenAttribute], [Roles("")], and several other data annotations for starters. This is a huge topic which has a ton of reading material online -- invest in some research. Your controller can have multiple actions which have varying limitations on them, such as preventing CSRF on the SPA, but be less restricted on Mobile by either utilizing varying actions on the controller or drawing from separate repositories.
Can I add multiple routes that map to the same method?
https://myapp.example.org/api/todo
https://myapp.example.org/mutual-auth/api/todo
Yes, absolutely. You'll just have to do some extra work with your routing configuration files. With BreezeJS, you get access to not only /api/ but /~breeze/ which works very similarly.
You can secury your Web API using the way you want. For exemple, you can provide a custom Message Handler or a custom Authorization Filter to provide external authentication via token.
There's a full session from the ASP.NET Team that covers this, you just need to choose which one you will pick up:
Security issues for Web API.
Assuming you are hosting web API in IIS, if you enable the forms authentication, FormsAuthenticationModule establishes the identity. That is, if you look at HttpContext.Current.User or Thread.CurrentPrincipal after a successful authentication, the object of type IPrincipal will have the identity (which is FormsIdentity) and the IsAuthenticated property will be set to true. You can do the same thing for any other credential using a custom DelegatingHandler. All you need to do is to validate the credential (token, user id and password in basic scheme in HTTP authorization header or whatever) and set the HttpContext.Current.User and Thread.CurrentPrincipal to an object of type GenericPrincipal with GenericIdentity. After this, the same action method of a controller which is decorated with Authorize will work for both types of requests.
New to AngularJS, and trying to hit a web service with basic auth using either $http or $resource. I haven't written any services or directives and basically just trying to do a call in my controller. Initially I prepended my url with the user/pw separated by an '#' symbol and I also have a callback that does a console out on the returned payload. Now I'm trying to change the $http.defaults.headers.common['Authorization'], but I feel like I should be using $resources. Any assistance on how to do basic auth with $resource (or $http) would be greatly appreciated. Thanks.
$resources is a higher level abstraction that utilizes $http, so regardless of which one you choose to use, adding the Authorization header is a valid solution. Head over to the angular $http docs for information on how to do that.
If you're doing anything more than hard coding a user/password into your application, you might want to take a look at response interceptors as a way to catch 401s and have your user log in. I've studied this blog post in the past when I was looking for a way to build fluid authentication into my app. I'd definitely recommend it if you're thinking about going down that path.