I'm creating a test project with our IDP server. We have created a simple Web API sample project which return the claims of the users on its get method. We have also created the token by using OAuth Flow GrantResourceOwnerCredentials or Flow 3 in specs. Few things i didn't quite understand, need some help to get some more understanding :-
How does the Web API knows that token is coming from authorized
client and how does it get validated.
Where in Web Api code, we can override and check the OAuth incoming token and its validation. In production environment, we will have separate HA server for IDP and Web API, so do we need to specify some certificate in web config?
Can we have all the Auth mechanism available to the Web Api? like basic , OAuth etc.
How does the Web API knows that token is coming from authorized client and how does it get validated.
Normally access token is passed through HTTP Headers like Authorization. You can use handlers in web api on specific routes and check this token with your logic
Where in Web Api code, we can override and check the OAuth incoming
token and its validation. In production environment, we will have
separate HA server for IDP and Web API, so do we need to specify some
certificate in web config?
As said above. Best place is handler
public class AuthenticationHandler : DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
//...
}
}
and don't forget to configure to use your authentication handler for some specific routes
public static void Register(HttpConfiguration config)
{
// ...
config.MessageHandlers.Add(new AuthenticationHandler());
// ...
}
You need certificate only if your logic needs this certificate to validate your token. The best way is to store and read it to/from windows certificate storage and configure in web.config only thumbprint of certificate you need, so no user names, or plain text password in web.config.
Can we have all the Auth mechanism available to the Web Api? like
basic , OAuth etc.
Yes, you can use basic authentcation together with OAuth, just use something to differentiate, like different HTTP Headers suitable for autorization, but it's not clear for me, why you need to support e.g. basic together with oauth, maybe it will have more sense to use only easier one - basic.
Most of information you need is gathered here http://www.asp.net/web-api/overview/security
Related
I am using Visual Studio 2015 Enterprise Update 1 and ASP.NET 5 rc1-final to build an endpoint that both issues and consumes JWT tokens as described in detail here. In this approach we have a single project that 'does it all' - the project uses OIDC to issue tokens, JWT bearer authentication to validate them and then guards access to various controllers using the Authorize attribute - all in the same project.
Now we would like to refactor this solution by creating an OIDC authorization & authentication endpoint that only issues and validates tokens. Then we want 'n' additional endpoints that rely on that OIDC endpoint as a central authority for authenticating tokens. This will allow us to stand up additional endpoints on our growing service backbone without having to code the authorization & authentication into every endpoint.
While I understand how to configure OIDC to issue tokens from one endpoint, it's not entirely clear how I would point my other endpoint to the OIDC endpoint for token authentication. Presently JWT authentication and OIDC are simultaneously configured in the middleware 'Configure' method so I'm guessing perhaps on all the subordinate sites I would have a small piece of code in calling app.UseJwtBearerAuthentication simply pointing the JWT middleware to the OIDC endpoint? If this is the case there's still a bit of magic taking place with the app.UseJwtBearerAuthentication that uses OIDC to allow IdentityModel to use HTTP, so I'm not clear if I would need this on the subordinate servers also.
Any advice on how to establish a single OIDC authorization & authentication endpoint and then have 'n' subordinate endpoints point to that endpoint for authentication of JWT tokens would be very much appreciated.
Separating the resource server role (i.e the API) from the authorization server role is definitely possible with ASOS.
When opting for JWT tokens (instead of the default encrypted tokens), you need to ensure the audience is correctly added to the authentication ticket by calling ticket.SetResources, so the JWT access token gets the appropriate aud claim, containing the identifier associated with your resource server (i.e API):
public override Task GrantResourceOwnerCredentials(GrantResourceOwnerCredentialsContext context) {
var identity = new ClaimsIdentity(context.Options.AuthenticationScheme);
identity.AddClaim(ClaimTypes.NameIdentifier, "[unique identifier]");
var ticket = new AuthenticationTicket(
new ClaimsPrincipal(identity),
new AuthenticationProperties(),
context.Options.AuthenticationScheme);
// Call SetResources with the list of resource servers
// the access token should be issued for.
ticket.SetResources("resource_server_1");
// Call SetScopes with the list of scopes you want to grant.
ticket.SetScopes("profile", "offline_access");
context.Validate(ticket);
return Task.FromResult(0);
}
In your API app, you just have to set the options.Audience property with the identifier used in the authorization server, and it should work:
app.UseJwtBearerAuthentication(new JwtBearerOptions {
AutomaticAuthenticate = true,
AutomaticChallenge = true,
Audience = "resource_server_1",
Authority = "http://localhost:61854"
});
I would have a small piece of code in calling app.UseJwtBearerAuthentication simply pointing the JWT middleware to the OIDC endpoint? If this is the case there's still a bit of magic taking place with the app.UseJwtBearerAuthentication that uses OIDC to allow IdentityModel to use HTTP, so I'm not clear if I would need this on the subordinate servers also.
The JWT bearer middleware automatically retrieves the cryptographic key used to sign the access token from the authorization server mentioned in the options.Authority property, by making an HTTP call to the configuration metadata endpoint: you don't have to configure anything, even if the API project is separated from the authorization server app.
I am successfully using bearer token authentication for asp.net web API as is demonstrated in the default single page application template. But now I want to use the same web API from a different site (a different url).
When I make a request to web API AuthorizeEndpoint(by default /api/Account/ExternalLogin) from different site, I get error: invalid_request. I guess the problem is in the redirect_uri value, since changing that to value of site running on same domain as web api resolves the problem.
ValidateClientRedirectUri method in application OAuthAuthorizationServerProvider doesn't get fired. So based on my search in Katana source the error origin is in OAuthAuthorizationServerHandler.InvokeAuthorizeEndpointAsync.
Does anyone else have the same problems or am I doing something wrong?
The Katana OAuth middleware is not designed to be cross application - it is mainly for "embedding" an OAuth authorization server into the business resource.
If you want a proper (free) authorization server - have a look here:
https://github.com/thinktecture/Thinktecture.AuthorizationServer/wiki
The bearer token appears to be a hash into an claims hash, which is local to your application.
We are using a jwt token with a separate validate handler. Works cross application.
Still looking for a better way but for now it works.
I have an internal use web site that will be exposed over the Internet for ease of use on mobile devices. The web site is MVC 5 and will communicate with a Web API on a different server. The user will enter their Windows account information on the login page which will be authenticated against our Active Directory service. Once authenticated I would like to create an authentication token for use for subsequent calls to the MVC site as well as calls to the various other Web APIs.
At first we were just going to use Basic authentication since all channels of communication are over SSL however we have one Web API that will not have access to our AD but will have access to a central database that may contain token information.
Any examples or documentation about how to secure enterprise Web APIs would be fantastic. I can't find much information about this topic.
A way to do this would be to create a custom ActionFilterAttribute and override the OnActionExecuting method.
public class AuthenticateAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
//grab token from httprequest in the actionContext
//and authenticate it against the token in the database
if(/*token is NOT authenticated*/)
{
//set unauthorised response
var response = actionContext.ControllerContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
//and set the httpresponse in the actionContext to the unauthorised response
actionContext.Response = response;
//then return
return;
}
}
}
You can then apply this attribute to any actions or methods in your api you wish to authenticate.
We ended up using thinktecture's IdentityServer.
https://github.com/thinktecture/Thinktecture.IdentityServer.v3
v3 Beta 1 was just released. Looks promising.
Support for OpenID Connect and OAuth2.0.
They have several client samples that you can download from a different repository.
https://github.com/thinktecture/Thinktecture.IdentityServer.v3.Samples/tree/master/source/Clients
I'm having hard time in deciding an approach while implementing Authentication/Authorization scenario for my Web API (Service) - MVC (client) architecture project. Even though i have implemented Custom token based authentication in Web API project, I'm finding it hard where exactly i should implement the authorization (In Client or in API itself).
Architecture Overview :
Projects Solution -
|
| __ ASP.NET Web API based REST service (Independently hosted on IIS at M/C 1)
|
| __ ASP.NET MVC based Client (independently hosted on IIS at M/C 2 Consuming REST service)
|
| __ Smart phone client Application (Consuming the REST service)
Already implemented authentication :
Token based authentication in Web API (using Message Handler) - Which generates SHA1 encripted token for authenticated user which needs to be a part of every http request header for authentication.
(Token = User Name + User IP)
SSL protected HTTP request. (Again, Using Message Handler)
Current problems :
At what layer the authorization should be implemented?
How does user role should be persisted at client? Using Cookies? or Adding role information to Token itself ( Which might add overhead for API to decrypt the information and extra DB calls to retrieve permissions associated with that role)
How the Authentication Token should be persisted with Client session?
Since, my application is SPA MVC application, What is the best way to include the Authentication token as a part of every AJAX call i make to API?
I hope, I'm not doing things wrong while taking the whole authentication/authorization concept in to consideration. Thus, I'll appreciate any alternate approach/suggestion.
First of all I think it's never a good idea to invent your own authentication mechanism.
To answer your current problems:
1 Generally spoken you always want to secure your Api using authentication since it's the place where you access your data. Your client (MVC App/Smartphone) should authorize itself to get access to your Api.
2 & 3
Since you are using a REST Api I would suggest to keep your Api stateless, with other words, don't keep any session information. Just include the role data you need in your Token. You could use for example an JSON Web Token.
4
I would always use the authorization header to send authorization data. In your DelegatingHandler (Note the difference MessageHandler MVC, DelegatingHander HTTP) you can simpy retrieve the header.
protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
var authorizationHeader = request.Headers.Authorization;
// Your authorization logic.
return base.SendAsync(request, cancellationToken);
}
For more info on how to include the authorization header in an ajax call please see: How to use Basic Auth with jQuery and AJAX?
Extra info:
If I were you I would also take a look at Thinktecture's Identity Server: https://github.com/thinktecture/Thinktecture.IdentityServer.v2
And maybe this answer about REST Service Authentication will help you as well:
REST service authentication
Why create an entire token system (unless you're using some kind of federated security) you have forms authentication and cookies, once the cookie is set and returned the browser will send the cookie with any AJAX requests made by your SPA.
I'm new in WCF and I want to know how can I protect a WCF Rest service.
I have an asp.net website, only registered users can access it, the application uses a service hosted on the same IIS server, my question is, how can I restrict the use of this service, for that only registered users may use it, knowing that the service can be used by many clients (Android, iPhone, ...). what type of authentication I can use? to test the service I created a winform and I use an HttpWebRequest.
PS: I cant use https.
Thanks
Simplest way is to use asp.net compatibility mode. The WCF service call will result in the same preprocessing used for ASP.NET pages, including checking the ASP.NET auth and session cookies. You will also be able to check HttpContext, including httpcontext.current.user.identity.isauthenticated. If the user is not authenticated, throw an exception or return an error code. Here is some more information: http://msdn.microsoft.com/en-us/library/aa702682.aspx.
So if you are already using forms auth for your application, and the service should be called after a user has logged in to your application, you are set.
You can also create an authentication service. The service will allow the client to send a username / password, and will use ASP.NET authentication to authenticate the user. It will send back an auth cookie, and then you can check future service calls as above. See http://msdn.microsoft.com/en-us/library/bb386582.aspx.
I believe the authentication service can called using json. See How to Call .NET AuthenticationService from json client without ASP.NET.