11

I have two applications

  1. Client application build on ASP.NET MVC
  2. Authentication server build on Web API + OWIN

Have planned authentication as follow

  1. For user login client app will make a request to authication server with logged in credential.
  2. Authication server will generate a token and will send back to client application.
  3. Client application will store that token in local storage.
  4. for each subsequent request client app will attached token kept in local storage in request header.

NOW, ON SERVER SIDE OF CLEINT APP I NEED TO VALIDATE THAT TOKEN COMES WITH EACH REQUEST IS NOT TEMPERED.

  1. Please suggest me how to validate token in each request as i don't know the key the OWIN has used to generate the token.
  2. Is is right to write code to validate token on client app or it should be on authication server.
  3. I am planning to shift all user management code like register user, change password to authentication server so than we can re-use it for different client app- is it right design practice?

So far i have wrote below code to just to create a POC.

=========================OWIN configuration========

    [assembly: OwinStartup(typeof(WebApi.App_Start.Startup))]
    namespace WebApi.App_Start
    {
        public class Startup
        {
            public void Configuration(IAppBuilder app)
            {
                HttpConfiguration config = new HttpConfiguration();

                ConfigureOAuth(app);

                WebApiConfig.Register(config);
                app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
                app.UseWebApi(config);
            }

            public void ConfigureOAuth(IAppBuilder app)
            {
                OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
                {
                    AllowInsecureHttp = false,
                    TokenEndpointPath = new PathString("/token"),
                    AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
                    Provider = new SimpleAuthorizationServerProvider(),

         };

         // Token Generation

                app.UseOAuthAuthorizationServer(OAuthServerOptions);
                app.UseOAuthBearerAuthentication(new 
 OAuthBearerAuthenticationOptions());

            }
        }
    }

==============================oAuth Provided========================

 public class SimpleAuthorizationServerProvider: OAuthAuthorizationServerProvider
    {
        public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
        {
            context.Validated(); 
        }

        public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
        {


            context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });

            using (AuthRepository _repo = new AuthRepository())
            {
                IdentityUser user =  _repo.FindUser(context.UserName, context.Password);

                if (user == null)
                {
                    context.SetError("invalid_grant", "The user name or password is incorrect.");
                    return;
                }
            }

            var identity = new ClaimsIdentity(context.Options.AuthenticationType);
            identity.AddClaim(new Claim("sub", context.UserName));
            identity.AddClaim(new Claim("role", "user"));

            context.Validated(identity);

        }
    }

Please help,

Thanks,

@Paul

paul sim
  • 463
  • 2
  • 10
  • 23
  • Don’t use localstorage for authentication tokens it’s not secure. Better off using a cookie. https://www.owasp.org/index.php/HTML5_Security_Cheat_Sheet#Local_Storage – Robbert Draaisma Jul 28 '18 at 21:58

4 Answers4

3

Please suggest me how to validate token in each request as i don't know the key the OWIN has used to generate the token.

Your current setup, were you have added the app.UseOAuthBearerAuthentication() to the owin pipeline, will authenticate the user from the bearer token which is passed on each request for you. The current user can then be found via HttpContext.Current.User.

Use the Authorize attribute to then decide which users are authorized on certain endpoints. Here's an example where users with the role "user" are allowed to access

[Authorize(Roles="user")]
public class ValuesController : ApiController
{
}

Is is right to write code to validate token on client app or it should be on authication server.

NO, you don't validate the token in client, if your user credentials are wrong you wont get a token at all. That's all you need to know. And also, why should you want to validate the token in the client?

I am planning to shift all user management code like register user, change password to authentication server so than we can re-use it for different client app- is it right design practice?

Reusing a token provider is common. Why invent the wheel for every application? Build one great, or use a third party, and reuse it across your applications.

Marcus Höglund
  • 16,172
  • 11
  • 47
  • 69
  • Thanks for your reply @Marcus. – paul sim Aug 02 '18 at 08:09
  • Yes app.UseOAuthBearerAuthentication() is added. I have seen if I try to access any restricted resources from same authorization server(http://localhost:58386/) with invalid token, server internally validate the token and not allow to access that method. But my client app is in different domain(http://localhost:57543/). I want to use same authorization server(http://localhost:58386/) to authenticate and authorized all [Authorized] method defined in my client app(http://localhost:57543/) – paul sim Aug 02 '18 at 08:09
  • I could not find the configurations that are required to do in client app to tell client app to use authorization server(web api app) for authentication and authorization. Please help. – paul sim Aug 02 '18 at 15:37
  • @paulsim You need to enable the client app to decode and read the token thats been generated from the authorization api. Both apps needs to use the same Machine key. Here's a great blog which describes this step by step http://bitoftech.net/2014/09/24/decouple-owin-authorization-server-resource-server-oauth-2-0-web-api/. Np, If this answer was to any help, please upvote/accept. – Marcus Höglund Aug 02 '18 at 19:59
2

Use JSON Web Tokens (JWT) and claims identities, not random tokens that require keeping track of the issued tokens.

A JWT is like a passport issued by a trusted authority. The passport is signed/stamped, and you can verify that it was issued by this trusted authority and that it has not been tampered with. That means, the integrity of the access-right claim present in the token can be verified without keeping state anywhere. The only communication that needs to happen between the trusting application and the authority is an initial (secure) download of the authority's public key (used for signing the tokens).

It's also advisable that you use a standard claims schema, like OpenID Connect ( http://openid.net/specs/openid-connect-core-1_0.html#StandardClaims )

A good book on the topic, which helped me a lot getting an understanding of all these concepts, can be found here: A Guide to Claims-Based Identity and Access Control.

Efrain
  • 3,248
  • 4
  • 34
  • 61
0

One way to verify a token has not been tampered is to sign it using an asymmetric key pair, Identity Server uses this approach as seen here.

In your case if you are rolling your own authentication you will need to implement this yourself, and check on every request probably in a custom middleware that the token is valid.

MarkovskI
  • 1,489
  • 2
  • 21
  • 25
0

If you create, sendback, save in localStorage and every thing about JWT Token as correct, you have to know that many ways are in .Net that you can to controlling per request.

Server side controlling:

  1. If you are using Web API Core, in core you can create Middleware that runs as pipline in run time, and you can give context and check token that requested, for more infomation check: This.

  2. If you use of Asp.net MVC, you can use ActionFilter in MVC(Asp.Net-Core have more advance ActionFilter too), that each requests goes through on and you can check every thisng abount request, for more information check: This.

ClientSide Conftolling:

  1. After that you give Token after log in from server side, you have to save data in localstorage that your browser check per request that data, they advantage are the Expireation and every like this issue in token save in localstorage and you and browser can use of this for more information check: This.

GoodLuck.

AmirReza-Farahlagha
  • 1,204
  • 14
  • 26