I am looking for any article or forum thread, where I could find information how to make oauth 2.0 authentication. Especially I have MVC 3 application and WCF Restfull API. And I have to call API methods from web app with using oauth 2.0 protocol authentication. But I could not find any information about it. After googling I see only results how to develop clients for facebook, linkedin, google etc.. Any help would be helpful. Thank you.
You could have a look at DotNetOpenAuth. It has a client library which you can easily install from NuGet here.
Using DotNetOpenAuth all the OAuth plumbing is handled behind the scenes.
DotNetOpenAuth:
When you install the NuGet Package: https://www.nuget.org/packages/DotNetOpenAuth.Ultimate/4.3.3.13295
You can setup an OAuth client like this:
var authorizationServerDescription = new AuthorizationServerDescription
{
ProtocolVersion = ProtocolVersion.V20,
TokenEndpoint = new Uri("https://yourUrl/token"),
AuthorizationEndpoint = new Uri("https://yourUrl/authorize")
};
var client = new WebServerClient(authorizationServerDescription, "ClientIdentifier", "ClientSecret");
Then you can request a IAuthorizationState like this:
// Resource Owner Password Flow
client.ExchangeUserCredentialForToken("userName", "password");
// Client Credential Flow
client.GetClientAccessToken();
The IAuthorizationState contains the AccessToken you can use to Authorize against your Api. If a RefreshToken is provided you can also refresh your authorization using:
client.RefreshAuthorization(AuthorizationState);
ThinkTecture:
Alternatively you could use Thinktecture.IdentityModel. If you chose to use Thinktectures IdentityModel be sure to check out this post: Introducing OAuth2 Code Flow and Refresh Token Support in Thinktecture IdentityServer. Which not only explains how to set up an OAuth Token Server using Thinktecture, but how to use the client as well including a code sample. Ofcourse you can use this client to validate against another OAuth 2.0 server as long as the parameters are implemented according to the OAuth specifications.
OAuth 2.0 Playground
If you want to have a better look at the OAuth 2.0 flow, be sure to check out Google's OAuth 2.0 Playground. I think that a lot of people don't know that it is possible to test your own server with it. Just push the 'settings' icon in the top right and set:
OAuth endpoints: Custom
And you're good to go.
Related
I have 2 .NET solutions: a webapp, an API.
When user browses the webapp he needs to be authenticated and thus facing this:
return builder.AddOpenIdConnect("contonso", options =>
{
options.Authority = configuration["Contonso:Oidc:Authority"];
options.ClientId = configuration["Contonso:Oidc:ClientId"];
options.ClientSecret = configuration["Contonso:Oidc:ClientSecret"];
options.ResponseType = OpenIdConnectResponseType.Code;
options.ProtocolValidator.RequireState = true;
options.UsePkce = false;
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
}
Which works finely as I get all infos : code, token, id_token once user authenticated.
I copied code above into my API and changed clientId/clientSecret to point to my resource server.
From my webapp I call the API adding an Authorization : Bearer token (received previously).
However in API solution, I get redirected each time to the login page, whatever I pass in my authorization header.
Do I need to change something in my API code in order to make the token "transit" to the resource server and just validate token received?
Cheers,
APIs behave differently to web back ends. The API should never redirect the client and should just validate JWT access tokens instead:
Return a 200 error when the JWT is valid
Return a 401 error when it is not
You use different .Net middleware in the API, by calling AddJwtBearer. Here is a Curity code example that does this.
The main thing is to implement the standards based behaviour, which will then work with any programming language and Authorization Server.
API CODE
There are two main approaches to API JWT validation, and you are using the first type:
Use a JWT framework (such as ASP.Net Core)
Use a JWT library
When you are new to securing APIs using OAuth, it can be useful to understand what code looks like for the library approach, as in this class of mine, which shows the steps an API should use:
Download the token signing public key from the Authorization Server
Give the public key to a library, which will then cryptographically validate the JWT
Also check the issuer, audience and algorithm are as expected
.Net Core will do this for you automatically though, so use the Curity code example approach, since you will write less code.
As always RTFM was the good way. I needed to call the introspection endpoint to validate my token. Explained here also : https://connect2id.com/products/server/docs/api/token-introspection
I then used a Nuget package doing that and it works fine.
Anyways thanks for your help and lightning Gary :)
I am using JSON Web Token (Bearer) as my default Authentication. I'm then using (Cookies) as my Authentication for Google.
I am using the default Google Authentication in Asp.Net Core API to get the AccessToken. I then pass that AccessToken to my Angular application in the Url, using a redirect. This is similar to how the ASP.Net MVC 5 Web API works. From there, I'm making a call back to my Asp.Net Core API to try and get the remaining claims. I'm making the call using the AccessToken.
Does anyone know how to access the external claims using the Google AccessToken? I know how to do this in the Asp.Net MVC 5 Web API, but Asp.Net Core is much different.
I can see external claims here. This happens during the OAuth process after the User Authenticates with Google. This is in my ExternalLoginCallback method.
var result = await HttpContext.AuthenticateAsync(CookieAuthenticationDefaults.AuthenticationScheme);
Here is some information that seems to be useful, but it doesn't specifically address third party Auth.
https://learn.microsoft.com/en-us/aspnet/core/migration/claimsprincipal-current?view=aspnetcore-2.2
If I call the API using the AccecssToken, in the header, and use HttpContext.AuthenticateAsync like so....
var result = await HttpContext.AuthenticateAsync(JwtBearerDefaults.AuthenticationScheme);
I get this.
{System.Exception: No SecurityTokenValidator available for token: ya29.Glt5B_thgPhe8-FcR
Thanks in advance! Any help is much appreciated.
Here is what I ended up doing. Since I'm able to get the claims from the Cookie in my ExternalLoginCallback method, I went ahead and created a new JSON Web Token (JWT), added the extracted claims to it and then passed that over to my Angular application. Now, when I make the call back to my API, I'm able to read that Token and extract the claims using this line of code in my GetUserInfo method.
HttpContext.AuthenticateAsync(JwtBearerDefaults.AuthenticationScheme);
Bottom line, since I could not read the Google AccessToken like I could in my ASP.Net MVC 5 Web API, I just went ahead and created a new JWT Token, added in the claims and used that.
By the way, I'm having to do all of this because I can not call my ExternalLogin method directly from Angular because of a known Cors policy issue.
I'm getting lost in OAuth and OpenIDConnect and aspnet core middleware. Any help on this would be appreciated.
I have multiple UIs (web, native apps) that use the same set of web services, and I'd like to ensure only authenticated users can access the web services. My organization uses Google accounts, so I'd like to use Google authentication restricted to the organization domain.
The web site is properly requiring authentication, following this sample. What I need now is to have the web site (AngularJS 4) invoke my back end web services with an auth token that I can verify with Google.
The back end services are written with aspnet core. I've tried using these approaches: Google middleware and Google OpenIDConnect but these still 1) assume there is a UI that can prompt an unauthorized user to log in, and 2) appear to be cookie-based, and I won't have cookies for the web service calls.
I don't want to prompt the user to log in, since the "user" in this case is a software client. Either they're authenticated or not already. I just need to get the authentication token, validate it, and carry on.
This appears to be the same question, which hasn't been answered yet, either.
Any suggestions are appreciated. Also, suggestions or tips on having native apps do the same!
Got it working. As mentioned, I was getting lost, and the OpenIDConnect, though referenced in several areas as a solution, was a red herring for the web services. Here's what is working for me now, with as complete steps as I can provide (some cleanup required):
Add authentication to the UI following these directions
Obtain the JWT token as shown in the first segment here
On each web service call, include the JWT token in the headers:
Name: Authentication
Value: Bearer {token value}
Install the JwtBearer NuGet package
In the ConfigureServices method of Startup in the web service, after you AddMvc():
services.AddAuthorization(options =>
{ // this policy needed only if you want to restrict to accounts within your domain. otherwise, don't use options. or use whatever options work for you.
options.AddPolicy("hd",
policy => policy.RequireAssertion(context =>
context.User.HasClaim(c =>
c.Type == "hd" &&
("https://accounts.google.com".Equals(c.Issuer) ||
"accounts.google.com".Equals(c.Issuer, StringComparison.CurrentCultureIgnoreCase)) &&
c.Value == "yourdomain.com"
)));
});
In the Configure method, before you UseMvc():
JwtBearerOptions jwtOptions = new JwtBearerOptions();
jwtOptions.Audience = "{the OAuth 2.0 client ID credential from google api developer console}";
jwtOptions.Authority = "https://accounts.google.com";
jwtOptions.TokenValidationParameters = new TokenValidationParameters();
jwtOptions.TokenValidationParameters.ValidIssuers = new List<string>()
{
"https://accounts.google.com",
"accounts.google.com"
};
app.UseJwtBearerAuthentication(jwtOptions);
Perhaps there is a more appropriate way to do this...if there is, I'm interested in trying it out. For now, this is working.
I will try to help.
First you need to look at OpenID Connect (which is built on top of OAuth 2.0) remembering that OAuth 2.0 NOT an Authentication protocol.
1) assume there is a UI
No UI is required for login assuming you are using Google services. You only need to check for the existence of and validate the Access Token, Identity Token (and perhaps the refresh token). If there is no Token, assume the user is NOT Authenticated and redirect them to the Authentication Server with a Authorization Request.
If there is a valid Access Token and Refresh Token, then you can assume the user is Authenticated.
You can also inspect the Access Token for proper "Scopes" to determine if they are Authorized for your specific application.
If you are using Google for Authorization Server, you can validate the the hd parameter within Identity Token has the desired Domain.
BTW: No cookies involved.
Hope that helps.
I am new in asp.net core and want to implement authentication and authorization in WEB API 2 project. I am little bit confuse to use basic authentication, bearer token, JWT token or any other. please suggest more preferable
Thanks
Basic auth is as the name suggests, very basic and not very secure, it uses base64 encoding of the username and password so you must use HTTPS if you use it, but best is not to use it at all.
A bearer token is a type of token which effectively gives access to a resource to the "bearer" of the token. Both basic and bearer are used in an HTTP Authorization header.
You can have different formats of bearer tokens, one of which is JWT - JWT is the industry standard so I recommend you use it, and therefore you'll be using bearer tokens.
This article is a good starting point to look into all this in the context of asp.net core. See also this video series and this article goes into more detail about JWT validation.
Edit
To answer your questions in the comments:
OAuth is a standard for users to delegate permissions to apps or websites to access their resources, for example when you allow some web app to post on your behalf to your Facebook feed. Various tokens are used in this process and they're very often JWT. OAuth2 adds authentication via OpenID Connect.
OWIN on the other hand is a standard for web servers which decouples IIS and ASP.NET with the aim of allowing ASP.NET to run on other web servers which implement OWIN and other frameworks generally to run on OWIN compatible servers if those frameworks are OWIN compatible.
Auth0 is an identity platform which can do OAuth and allows you to use JWTs, generally it handles your identity and SSO. IdentityServer is another identity platform with some similar features.
I'd still recommend starting with the articles I linked at the top, don't worry too much about OWIN, and read more about OAuth to determine if you really need it. If you do, I'd recommend IdentityServer.
ASP.NET Core 2.0 and above Web API authentication and authorization
Bearer type JWT Token based authentication
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
Please implement as following below post
https://fullstackmark.com/post/13/jwt-authentication-with-aspnet-core-2-web-api-angular-5-net-core-identity-and-facebook-login
I have a web api application which implements the Resource Owner Password flow from OAuth specification. Everything works correctly.
Actually I configure everything in my WebApiConfig class by using an Authentication filter like this
// Configure Web API to use only bearer token authentication.
config.SuppressDefaultHostAuthentication();
config.Filters.Add( new HostAuthenticationFilter( OAuthDefaults.AuthenticationType ) );
As some of my customer asked for a different method of authentication I am evaluating to add a couple of features to my services but stil did not have clear how those features can work together.
In particular I cam across a link which explain in very easy words how to implement a HMAC authentication in web api.
Can I implement this authentication method and let the client to choose which one he want to use? Do they can cohesist together?
Yes, your web api service can send back multiple schemes in the WWW-Authenticate challenge. In your case it can send back 'bearer' and 'hmac' for example.
See also this question for more info on using multiple schemes.
BTW, it's not your web api service that supports Resource Owner Password flow. The client uses this flow to get a token from the authorization server that it can use in a bearer scheme with your service (resource server). HTH.