Extend MVC Application to REST - asp.net-mvc

I think I may have phrased the question wrong. What I have currently is an MVC Web Application that (by default) uses bearer tokens. This is all well and good but if I want to communicate with any of these APIs outside of the Web Application, I would like to use a REST client. However, I can not find a way to generate a bearer token/call the Login method and get a bearer token back to be used as an authorization header in subsequent requests.
What I hope to have:
POST /Account/Login
Returns: token
POST /Product/Create
Token Header
Body Request
Returns: success or failure
ETC. All without losing the existing functionality of the website.
Thanks for any help!

The /Token endpoint already provides all the functionality you need in order to use [Authorize] on your WebAPI methods. The general process to make this work would be something like the following:
Client establishes a POST request to http://somesite.com/Token. The Content-Type header should contain x-www-form-urlencoded. The payload body should include grant_type=password&username="username"&password="password". The grant_type value indicates that we are presenting a password in exchange for an access token.
The server response will either be a HTTP 403 or an HTTP 200. In the case of HTTP 200, the response body will include access_token, token_type (bearer), and expires_in.
The client optionally stores this access_token for future access, then establishes a new request to the protected server resource, including a header Authorization, which will be Bearer access_token. This format is important, it must start with Bearer and a space, then the access_token value.
Note that this does not take into account issues of Cross Origin Requests (CORS), or HTTPS. Proper security should be enacted whenever a username or password is sent, as in step 1 here.
This is configured by default on any new MVC5 project with Identity. You will find a Startup class similar to the following:
public partial class Startup
{
// Enable the application to use OAuthAuthorization. You can then secure your Web APIs
static Startup()
{
PublicClientId = "web";
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
AuthorizeEndpointPath = new PathString("/Account/Authorize"),
Provider = new ApplicationOAuthProvider(PublicClientId),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
AllowInsecureHttp = true
};
}
The TokenEndpointPath represents your path for token requests, the AuthorizeEndpointPath represents the path used when External Logins (Facebook, Twitter, Google, etc.) are used. See this Microsoft article for more info on the default template.
A much more detailed step by step of this process and complete client application written in Angular.js can be found on a blog by Taiseer Joudeh.

Related

Spring Oauth2 : How to get all clientIds?

Has there anyway to retrieve all clientIds from OAuth2Authentication ?
I can get single clientId from Oauth2Request as
String clientId = auth.getOAuth2Request().getClientId();
but I'd like to know them all.
The client IDs are configured on the authorization server and there is no standard way to get the client IDs on resource server side.
Hence, if you use an external authorization server like Google, Facebook or GitHub you have to look into their APIs.
With your own authorization server, you could get all client IDs, see ClientRegistrationService:
Interface for client registration, handling add, update and remove of ClientDetails from an Authorization Server.
All you need is a ClientDetailsService implementing ClientRegistrationService, for example JdbcClientDetailsService.

Vulnerabilities when using client credentials and OWIN Middleware OAuth

I've implemented OAuth2 client_credentials flow in our MVC app. Our MVC app is actually the Resource in this scenario. I had much difficulty in securing a sample for this specific use case, since this flow is primarily used for API access, but I did it nonetheless.
I'd like to share some of the implementation details with you to ask for any information regarding vulnerabilities that I may be unaware of. I am in no way a security expert, which is what brought me here.
In .NET Framework 4.5.2 I used the Microsoft.Owin libraries v3.0.1. I know there are newer ways to set up this sort of thing, (.NET Core and IdentityServer4 for example), but as I said I was having difficulty finding a viable sample for this specific use case, so I did the best I could.
I implemented a Provider:
public class ApplicationOAuthProvider : OAuthAuthorizationServerProvider
{
private ClientService clientService;
public ApplicationOAuthProvider()
{
this.clientService = new ClientService();
}
public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
string clientId;
string clientSecret;
context.TryGetFormCredentials(out clientId, out clientSecret);
if (clientId == "XXXX" && clientSecret == "XXXXX")
{
context.Validated(clientId);
}
return base.ValidateClientAuthentication(context);
}
public override Task GrantClientCredentials(OAuthGrantClientCredentialsContext context)
{
var client = clientService.GetClient(context.ClientId);
var oAuthIdentity = new ClaimsIdentity(context.Options.AuthenticationType);
oAuthIdentity.AddClaim(new Claim(ClaimTypes.Name, client.ClientName));
var ticket = new AuthenticationTicket(oAuthIdentity, new AuthenticationProperties());
context.Validated(ticket);
//context.OwinContext.Response.Headers.Add("Access-Control-All‌​ow-Origin", new[] { "*" });
return base.GrantClientCredentials(context);
}
with the following startup code:
public partial class Startup
{
public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }
static Startup()
{
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
Provider = new ApplicationOAuthProvider(),
AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(60),
//AllowInsecureHttp = true,
AuthenticationMode = AuthenticationMode.Active,
};
}
public void ConfigureAuth(IAppBuilder app)
{
app.UseCors(CorsOptions.AllowAll)
.UseOAuthBearerTokens(OAuthOptions);
//app.UseOAuthBearerTokens(OAuthOptions);
}
}
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
ConfigureAuth(app);
}
}
and then created a Client app that is also a website and eventually gained access to the Resource (MVC app). The Resource has no users, therefore no login screen. The Resource (now) has a token endpoint. The Client app makes a request to the token endpoint with their credentials and, (after being authenticated), then uses that token in subsequent requests to the Resource.
I've found 2 different ways of using this token to gain access.
Include the access token in the request header. OR
Include the access token as a form parameter
My questions are concerning vulnerabilities to this scenario:
Assuming all communications between the client app and the server are happening over secure channels (https) and the client app is able to maintain the credentials in a secure fashion, what are the chances that an access token could be obtained or intercepted? Or, are there methods included in this flow (or perhaps another OAuth flow) that also include client verification? I realize that the client is already being authenticated via client_id/client_secret, but when I ask about verification, I'm asking about the origin of the request (assuming of course, that the method of verification does not include checking something that can be spoofed by a malicious user).
Is there an additional step of verification that I should be including that I may have missed - because there's alot of information out there and I did my best to scour, but I can't claim that I have a solid understanding of everything I've read so far.
If there is an additional verification step that I have missed, how does that fit into this (client_credentials) flow?
Thanks,
Carrie
I've found 2 different ways of using this token to gain access.
Include the access token in the request header. OR
Include the access token as a form parameter
This means that your access token is of type Bearer token (therefore, you can also use a third way to send the access token: using GET method with a query parameter).
what are the chances that an access token could be obtained or intercepted?
Or, are there methods included in this flow (or perhaps another OAuth flow)
that also include client verification?
You have a Bearer token, thus the RFC-6750 applies. The Threat Mitigation section answers your questions:
first, your access token may be disclosed if the version of TLS between your client app and the authorization server (to get the token), and between the client app and the resource server (to give the token), have a security flaw (excerpt: This requires that the communication interaction between the client and the authorization server, as well as the interaction between the client and the resource server, utilize confidentiality and integrity protection. Since TLS is mandatory to implement and to use with this specification, it is the preferred approach for preventing token disclosure via the communication channel.)
secondly, another way for your access token to be disclosed is when using a TLS accelerator. As said in the same section of the RFC: In some deployments, including those utilizing load balancers, the TLS connection to the resource server terminates prior to the actual server that provides the resource. This could leave the token unprotected between the front-end server where the TLS connection terminates and the back-end server that provides the resource.
There are other ways to get the access token disclosed.
The solution is not to implement another OAuth flow but to apply the recommandations in section 5.3 of the RFC. As a summary, the main recommandations are:
always use TLS,
validate TLS certificate chains,
use token encryption in addition to the usage of TLS protection: for instance, encrypt the token with a shared secret between the client app and the resource server,
don't store bearer tokens in cookies,
issue short-lived bearer tokens,
issue scoped bearer tokens (use audience restriction).
This is not in the RFC but I would add this recommandation: use mutual authentication. This means that the client app must have a X.509 certificate that must be verified by the resource server. This is possible in the specific Oauth2 flow you have chosen, because the client app is known by the resource server (with some alternative flows, it can not be done).

Web API 2 and HttpClient

I have a web api and MVC project,
The web api is deployed at api.domain.com
The MVC app is deployed at domain.com
I recently secured certain methods on the API, it requires authentication (grant type: password).
I want to have the token passed around in the code behind of the MVC app and not javascript, to keep it secure and away from someone sniffing angular js traffic.
I did some research and I should use the HttpClient class. If this is the case how does this client handle refresh tokens? Right now the token expires after 8 hours, I know a refresh token is also issued but does the HttpClient automatically handle this or do I have to write my own logic to check if a request was denied due to an expired token.
Thank you!
I did some research and I should use the HttpClient class. If this is
the case how does this client handle refresh tokens?
The HttpClient class is, as its name suggest, an HTTP protocol client. It knows strictly nothing about OAuth 2.0 and in this respect nothing about refresh tokens. So you should write this logic yourself. Basically the flow you should follow is something along those lines:
Send an HTTP request t othe target endpoint using the HttpClient and including your existing OAuth Bearer token in the Authorization header field.
If the request succeeds then you are good to go. If the request fails with 401, then you should use your refresh token in order to renew your access token and then repeat step 1 with your new access token.
I think using a HttpMessageHandler can help you.
The way this is wired up to an HttpClient is by using the HttpClient constructor that takes a HttpMessagHandler:
1: // Create client and insert an OAuth message handler in the message path that
2: // inserts an OAuth authentication header in the request
3: HttpClient client = new HttpClient(new OAuthMessageHandler(new HttpClientHandler()));
The HttpClientHandler is the default “network” handler provided by HttpClient that actually sends the request and received the response from the network.
Refer this for complete detail: https://blogs.msdn.microsoft.com/henrikn/2012/02/16/extending-httpclient-with-oauth-to-access-twitter/

check if user session has expired asp web api

I am experimenting in developing Single Page Application using Asp Mvc 4 / Web Api and angularjs.
I am using the mvc controller actions to return views and web api actions to return json.
As the web api part is restfull and it has no state, I am wondering how to check if a user session has expired. For example: a user is clicking on a button and this leads to request to the web api action to get some json data. But when the request hits the server I want to check if the user session has expired.
As I said I am rather new to this combination of technologies and I am wondering how can this be achieved. Any example will be greatly appreciated. Thanks in advance.
Web API introduced an Attribute [Authorize] to provide security. This can be set globally (global.asx)
public static void Register(HttpConfiguration config)
{
config.Filters.Add(new AuthorizeAttribute());
}
Or per controller:
[Authorize]
public class ValuesController : ApiController{
...
If your user is authenticated(session has not expired) the service will work normally if not an http 401 unauthorized is returned.
This is how I did it in my project: First instantiate a session on client sidei.e in your MVC Application if the user logs in , once the session is created,with each request you should add a unique identifyable token or session id in the header of your WebApi request which you are going to send, If the user sends a request without logging in there would be no token present in the header of the request.
If in your service you get an authentication token which you can verify, that means the request is authenticated and hence session was still in place otherwise the user sent the request without a session in place and hence no token present in the header of the request.
You could add headers with your request like this :
HttpClient httpClient = new HttpClient();
// Add a new Request Message
HttpRequestMessage requestMessage = new HttpRequestMessage(...);
// Add your custom headers
requestMessage.Headers.Add("authToken", "SessionId");
or
requestMessage.Headers.Add("authToken", "encryptedUsername:encryptedPassword");
And then in your WebApi Service read those headers, if you can uniquely identify or verify the authToken then that means the session was in place else unauthenticated request , generate an error response.
I dont know if this is the best practise or not but I did it this way. I actually store the encrypted username & password in my session and attach it with every request and in my WebApi I extract these header values and recheck them with my database and then further process the request. I know many people would not be too much happy about storing passwords in the session but I think its not that bad, they are in encrypted form atleast. Rest is upto you , you could store a sessionId instead or a unique identifier or a flag that may indicate that the session was actually in place and request is authenticated.

How to build secured api using ServiceStack as resource server with OAuth2.0?

I have build a OAuth2.0 Authorization server using dotnetopenauth that will manage authentication, authorization, and assign accessToken to the caller. The caller will use the access token to access the api (webservices) at resource server.
If follow the sample provided by dotnetopenauth in Resource Server, api that builded using WCF can be authenticated by OAuthAuthorizationManager
If using ServiceStack to build my api in Resource Server, how to build the authentication process that verify the incoming api request based on assigned OAuth2.0 access token? The functionality should similar to OAuthAuthorizationManager in the dotnetopenid sample and not based on login session.
Just some update
I didn't use the AuthenticateAttribute or RequiredRoleAttribute from ServiceStack.ServiceInterface.
I create 2 custom RequestFilterAttribute to replace the functions provided by AuthenticateAttribute and RequiredRoleAttribute.
In each custom RequestFilterAttribute's Execute method, I'm using method in dotnetopenauth to verify the access token.
//httpReq==req from Execute(IHttpRequest req, IHttpResponse res, object requestDto)
The code for the access token verification as following, reference the relevant documentation from both servicestack and dotnetopenauth for more info. ResourceServer is class from dotnetopenauth
HttpRequestBase reqBase = new HttpRequestWrapper((System.Web.HttpRequest)httpReq.OriginalRequest);
var resourceServer = new ResourceServer(new StandardAccessTokenAnalyzer(AuthorizationServerPublicKey, ResourceServerPrivateKey));
IPrincipal ip = null;
resourceServer.VerifyAccess(reqBase, out ip);
If the ip is null then not authenticated, if not null, the incoming request is valid and can use the ip to check the role e.g. ip.IsInRole(requiredRole)
I'm not sure this is the correct way to do the checking or not, but it's works for me. Any better solution are welcome.

Resources