Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET 5 OAuth bearer token authentication

I’m trying to implement OAuth bearer token authentication in ASP.NET 5 and am struggling to find an example of how to do this because the OWIN stuff has changed in ASP.NET 5.

For example IApplicationBuilder.UseOAuthAuthorizationServer() and IApplicationBuilder. UseOAuthBearerAuthentication() either don’t exist anymore or I’m missing a reference?

Any pointers would be greatly appreciated.

like image 596
Carl Rippon Avatar asked Mar 31 '15 04:03

Carl Rippon


People also ask

How do I send a POST request with Bearer Token authorization header C #/ net code?

POST JSON With Bearer Token Authorization Header [C#/. NET Code] To send a POST JSON request with a Bearer Token authorization header, you need to make an HTTP POST request, provide your Bearer Token with an Authorization: Bearer {token} HTTP header and give the JSON data in the body of the POST message.

How do I send a Bearer Token in header?

To send a request with the Bearer Token authorization header, you need to make an HTTP request and provide your Bearer Token with the "Authorization: Bearer {token}" header. A Bearer Token is a cryptic string typically generated by the server in response to a login request.

What is Bearer Token authentication C#?

Bearer authentication (also called token authentication) is one of the HTTP authentication schemes that grant access to the bearer of this token. Bearer token authentication is done by sending a security token with every HTTP request we make to the server.


3 Answers

I did it work, but with setting up Thinktecture's identity server v 3 as my token provider but I think if you have another token provider it will be the same flow....

(update : I added a github repo with the code : here)

here is my startup class: (Identityserver v3 also runs on Vnext with some little tweaking). notice I have the server and the web api in same web app. it's also ok if you have two different web project but here it's for the sake of demo...

public class Startup
{
    // For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();
    }

    public void Configure(IApplicationBuilder app)
    {
        app.Map("/core", core =>
        {
            var factory = InMemoryFactory.Create(
                                    users: Users.Get(),
                                    clients: Clients.Get(),
                                    scopes: Scopes.Get());

            var idsrvOptions = new IdentityServerOptions
            {
                IssuerUri = "https://idsrv3.com",
                SiteName = "test vnext Identity server",
                Factory = factory,
                SigningCertificate = Certificate.Get(),
                RequireSsl = false,

                CorsPolicy = CorsPolicy.AllowAll,

                AuthenticationOptions = new AuthenticationOptions
                {
                }
            };

            core.UseIdentityServer(idsrvOptions);
        });

        app.Map("/api", api =>
        {

            api.UseOAuthBearerAuthentication(options => {
                options.Authority = Constants.AuthorizationUrl;
                options.MetadataAddress = Constants.AuthorizationUrl + "/.well-known/openid-configuration";
                options.TokenValidationParameters.ValidAudience = "https://idsrv3.com/resources"; 
            });

            api.UseMvc();

        });

    }
}

from here you can see that my IdentityServerV3 is mapped to '/core' and in the same web app project (it could be another one), I have an web api that uses MVC. below is the controller:

  [Authorize]
[Route("[controller]")]
public class Test : Controller
{
    [HttpGet]
    public JsonResult Get()
    {
        return Json(new
        {
            message = "You See this then it's ok auth is  :" + User.Identity.IsAuthenticated,
        });
    }
}

I have configure a Client in my identity server :

  new Client
            {
                 //Resource Owner Flow Client (our web UI)
                ClientName = "WebUI",
                Enabled = true,

                ClientId = "IdentityWebUI",
                ClientSecrets = new List<ClientSecret>
                {
                    new ClientSecret("secret".Sha256())
                },

                Flow = Flows.ResourceOwner,
                AccessTokenType = AccessTokenType.Jwt,
                AccessTokenLifetime = 3600

            }

and here is the User (used InMemory user):

 return new List<InMemoryUser>
        {
            new InMemoryUser
            {
                Username = "testUser",
                Password = "testPwd",
                Subject = "I am the Subject"
            }

        };

In fidler I issue the following POST to get a bearer token:

    POST : http://localhost:4357/core/connect/token

    User-Agent: Fiddler
    Host: localhost:4357
    Content-Length: 67
    Content-Type: application/x-www-form-urlencoded
    Authorization: Basic SWRlbnRpdHlXZWJVSTpzZWNyZXQ=

    grant_type=password&username=testUser&password=testPwd&scope=openid

in the response you will get an Access_token

{"access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6ImEzck1VZ01Gdjl0UGNsTGE2eUYzekFrZnF1RSIsImtpZCI6ImEzck1VZ01Gdjl0UGNsTGE2eUYzekFrZnF1RSJ9.eyJjbGllbnRfaWQiOiJJZGVudGl0eVdlYlVJIiwic2NvcGUiOiJvcGVuaWQiLCJzdWIiOiJJIGFtIHRoZSBTdWJqZWN0IiwiYW1yIjoicGFzc3dvcmQiLCJhdXRoX3RpbWUiOjE0MjgzOTQ3MzAsImlkcCI6Imlkc3J2IiwiaXNzIjoiaHR0cHM6Ly9pZHNydjMuY29tIiwiYXVkIjoiaHR0cHM6Ly9pZHNydjMuY29tL3Jlc291cmNlcyIsImV4cCI6MTQyODM5ODMzMCwibmJmIjoxNDI4Mzk0NzMwfQ.cbB4YrRXaaRDNw8BjeI4Q1DvXN28xmJScMJBGWCM_zSLcH1i63cQVTmR8X86rGP5VrR0Ly4-EmWZ8911Vh4jc4Ua0Kgz2n7RbmQ6VqQX5Z_lM3F8EIgD81kpUn0v3hhSFW06aJ2Lo1XOZG_re84xGgqre-H4dC0XZR6IQMEAQ9Q5dOXBh8V1NxyLSh0PzyrRRmOnEndoaY4uaIFtbp9j7KnXxQ3ZdGmaYAO96xuhHfO1DbgRdw6fYyf4nnC795yhnwDh1QZGxPsFaysJSA_3-cjmw-29m-Ga0hD1ALfVE7R57iNLxkB6dyEuz1UFJhJyibRDW9sNspo2gQFZZGxMKQ","expires_in":3600,"token_type":"Bearer"}

then I use that access_token to call my web api

here is the fiddler (in composer pane)

    GET http://localhost:4357/api/Test

    User-Agent: Fiddler
    Host: localhost:4357
    Content-Length: 0
    Content-Type: application/x-www-form-urlencoded
    Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6ImEzck1VZ01Gdjl0UGNsTGE2eUYzekFrZnF1RSIsImtpZCI6ImEzck1VZ01Gdjl0UGNsTGE2eUYzekFrZnF1RSJ9.eyJjbGllbnRfaWQiOiJJZGVudGl0eVdlYlVJIiwic2NvcGUiOiJvcGVuaWQiLCJzdWIiOiJJIGFtIHRoZSBTdWJqZWN0IiwiYW1yIjoicGFzc3dvcmQiLCJhdXRoX3RpbWUiOjE0MjgzOTQ3MzAsImlkcCI6Imlkc3J2IiwiaXNzIjoiaHR0cHM6Ly9pZHNydjMuY29tIiwiYXVkIjoiaHR0cHM6Ly9pZHNydjMuY29tL3Jlc291cmNlcyIsImV4cCI6MTQyODM5ODMzMCwibmJmIjoxNDI4Mzk0NzMwfQ.cbB4YrRXaaRDNw8BjeI4Q1DvXN28xmJScMJBGWCM_zSLcH1i63cQVTmR8X86rGP5VrR0Ly4-EmWZ8911Vh4jc4Ua0Kgz2n7RbmQ6VqQX5Z_lM3F8EIgD81kpUn0v3hhSFW06aJ2Lo1XOZG_re84xGgqre-H4dC0XZR6IQMEAQ9Q5dOXBh8V1NxyLSh0PzyrRRmOnEndoaY4uaIFtbp9j7KnXxQ3ZdGmaYAO96xuhHfO1DbgRdw6fYyf4nnC795yhnwDh1QZGxPsFaysJSA_3-cjmw-29m-Ga0hD1ALfVE7R57iNLxkB6dyEuz1UFJhJyibRDW9sNspo2gQFZZGxMKQ

Then I get the response still in fidler:

you can have more info by following this link below, but it's not related to vnext. I will create a post on this as I need an angularJS app to authenticate and use an implicit flow instead of resource owner flow... with visual studio 2015 preview

like image 76
Cedric Dumont Avatar answered Oct 10 '22 12:10

Cedric Dumont


I am not sure where UseOAuthAuthorizationServer is, but for UseOAuthBearerAuthentication, try adding the Microsoft.AspNet.Security.OAuthBearer NuGet Package and then in your startup Configure Method add:

app.UseOAuthBearerAuthentication(options =>
            {
                options.Audience = {your audience};
                options.Authority = {your authority}}); //or whatever options you need
like image 36
NPNelson Avatar answered Oct 10 '22 11:10

NPNelson


The real kicker here is the token generation. I've managed to build one using the default Microsoft.AspNet.Security.OAuthBearer package, but it wasn't easy.

// Injected from the constructor; this is why we configured the options above rather 
// than simply passing them to the UseOAuthBearerAuthentication()
private readonly OAuthBearerAuthenticationOptions bearerOptions;

// In your /Token action...
var handler = bearerOptions.SecurityTokenValidators.OfType<System.IdentityModel.Tokens.JwtSecurityTokenHandler>()
    .First();
// The identity here is the ClaimsIdentity you want to authenticate the user as.
// You can get this using the SignInManager if you're using Identity.
var securityToken = handler.CreateToken(
    issuer: bearerOptions.TokenValidationParameters.ValidIssuer, 
    audience: bearerOptions.TokenValidationParameters.ValidAudience, 
    subject: identity);
var token = handler.WriteToken(securityToken);
// The var token is your bearer token

My full solution is detailed here: Token Based Authentication in ASP.Net 5 (vNext).

like image 31
Matt DeKrey Avatar answered Oct 10 '22 12:10

Matt DeKrey