Is it possible to expose multiple endpoints using

2019-07-21 07:05发布

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.

3条回答
可以哭但决不认输i
2楼-- · 2019-07-21 07:18

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.

查看更多
Fickle 薄情
3楼-- · 2019-07-21 07:22

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.

查看更多
够拽才男人
4楼-- · 2019-07-21 07:23

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.

查看更多
登录 后发表回答