I'm building an ASP.NET WebApi SPA using OWIN middleware and need an explanation of what the AuthorizeEndpointPath property does in OAuthAuthorizationServerOptions.
The documentation states
The request path where client applications will redirect the user-agent in order to obtain user consent to issue a token. Must begin with a leading slash, like "/Authorize".
When I try to access a protected WebApi without a Bearer token, my application never redirects to the path specified (as I would expect), but simply returns a 401.
What is Token Based Authentication in Web API? Token-based authentication is a process where the client application first sends a request to Authentication server with a valid credentials. The Authentication server sends an Access token to the client as a response.
To access the web API method, we have to pass the user credentials in the request header. If we do not pass the user credentials in the request header, then the server returns 401 (unauthorized) status code indicating the server supports Basic Authentication.
By default the token is not stored by the server. Only your client has it and is sending it through the authorization header to the server. If you used the default template provided by Visual Studio, in the Startup ConfigureAuth method the following IAppBuilder extension is called: app.
The different endpoint paths are for use with different OAuth flows for token granting.
TokenEndpointPath
= used to get tokens, in the client credentials grant flow, the resource owner password credentials grant flow, and at the end of an authorization code grant flowAuthorizeEndpointPath
= used for delegated auth in the authorization code grant flow and implicit grant flowCalling either of these endpoints will result in the execution of various methods in your implementation of OAuthAuthorizationServerProvider
- which ones are executed depends on which endpoint you called, and which parameters you sent with the request. You have to call one of them explicitly from your client - you'll never get redirected to either of them.
Before discussing the flows and endpoints further lets first define three things:
We're letting the client authenticate directly - we're not asking a user to input a username and password anywhere. This might be because the client doesn't have users, or we don't care who the user is when we call the web service.
Example request:
POST https://yourwebapi.com/token HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Host: yourwebapi.com
grant_type=client_credentials&
client_id=mega_app&
client_secret=1234hsdflkjh123
Will call GrantClientCredentials
(having validated the client id in ValidateClientAuthentication
) for you to set up some claims about the client.
This is when the user enters their details directly into the client, and the client sends these details directly to the authorization server. So the client sees the user's credentials.
You'd call it in your client with a request something like this:
POST https://yourwebapi.com/token HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Host: yourwebapi.com
grant_type=password&
username=bart&
password=b4rt
The client makes a request to the endpoint you have specified in TokenEndpointPath
, with grant_type of password, this will result in a call to the GrantResourceOwnerCredentials
method in your implementation of OAuthAuthorizationServerProvider
.
Assuming the user credentials are valid, access is granted, you create an identity that will have some claims specific to that user, and a token is returned that the client can subsequent send to the authorization server to pull this identity out again on later requests.
For authorization code grant flow and implicit grant flow we're interested in who the user is, but we don't want the user entering credentials directly into the client. In this case, the client calls through to the authorization server and it's the authorization server that gets the user to authenticate in some way, on behalf of the client. In this case the client has to send through its client id and a redirect_url and some other bits.
GET HTTP/1.1
Host: https://yourwebapi.com/api/Account/ExternalLogin?
client_id=mega_app&
scope=user+repo&
state=1234kjhsfdlkh123497&
response_type=code&
redirect_uri=https%3a%2f%2fyourwebapi.com%2fcallme
The response_type
parameter determines whether we're using implicit or authorization code flow. In AuthorizationEndpointResponse
based on this we can return either the token or the code. If we return a code, then the client has to make a call to the TokenEndpointPath
with that code to be given a token.
Have a look at this MSDN page for more info, and also Chapter 16 of Designing Evolvable Web APIs with ASP.NET.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With