locked
Queries related to access and refresh tokens RRS feed

  • Question

  • User517361227 posted

    Hi,

    I am trying to use the token based authorization in my web api application, for this I have been able to generate the access token with my custom provider.
    Before I can go longer with this bearer token authorization I have some queries related to tokens which I need to clear.

    1. how to read/decrypt access token in web api - Is it possible to read or decrypt custom data or user id/email from access token at controller level?
    2. how to generate refresh token along with the access token?
    3. how to invalidate/delete previously generated access tokens for same user or how to avoid generating new access token if there is already valid token for an user?
    4. how to accept JSON request to generate access token to /token endpoint - for now I have to send x-www-form-urlencoded form which I want to convert to JSON
    (Ideally I want to be able to call my Login action method in Account controller with JSON request and get same tokens and other information.)
    5. how to update expiry date of access token on every API request if token is still valid and send same information to client application about update of expiry date
    6. how to generate access token from refresh token?
    7. what to do after refresh token is expired?
    8. where these tokens are saved, is this more resource consuming process than storing own custom string in DB against each user and check at every API request from DB?

    I am using below code to generate access token for now.

    Providers -> OAuthProvider.cs

    using Microsoft.Owin.Security;
    using Microsoft.Owin.Security.OAuth;
    using OAuth.Services;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Security.Claims;
    using System.Threading.Tasks;
    using System.Web;
    
    namespace OAuth.Providers
    {
        public class OAuthProvider : OAuthAuthorizationServerProvider
        {
            #region[GrantResourceOwnerCredentials]
            public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
            {
                return Task.Factory.StartNew(() =>
                {
                    var userName = context.UserName;
                    var password = context.Password;
                    var userService = new UserService();
                    var user = userService.ValidateUser(userName, password);
                    if (user != null)
                    {
                        var claims = new List<Claim>()
                        {
                            new Claim(ClaimTypes.Sid, Convert.ToString(user.Id)),
                            new Claim(ClaimTypes.Name, user.Name),
                            new Claim(ClaimTypes.Email, user.Email)
                        };
                        ClaimsIdentity oAuthIdentity = new ClaimsIdentity(claims,
                                    Startup.OAuthOptions.AuthenticationType);
    
                        var properties = CreateProperties(user.Email, user.Id.ToString());
                        
                        var ticket = new AuthenticationTicket(oAuthIdentity, properties);
                        context.Validated(ticket);
                    }
                    else
                    {
                        context.SetError("invalid_grant", "The user name or password is incorrect");
                    }
                });
            }
            #endregion
    
            #region[ValidateClientAuthentication]
            public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
            {
                if (context.ClientId == null)
                    context.Validated();
    
                return Task.FromResult<object>(null);
            }
            #endregion
    
            #region[TokenEndpoint]
            public override Task TokenEndpoint(OAuthTokenEndpointContext context)
            {
                foreach (KeyValuePair<string, string> property in context.Properties.Dictionary)
                {
                    context.AdditionalResponseParameters.Add(property.Key, property.Value);
                }
    
                return Task.FromResult<object>(null);
            }
            #endregion
    
            #region[CreateProperties]
            public static AuthenticationProperties CreateProperties(string userEmail, string userId)
            {
                IDictionary<string, string> data = new Dictionary<string, string>
                {
                    { "userEmail", userEmail },
                    { "userId", userId }
                };
                return new AuthenticationProperties(data);
            }
            #endregion
        }
    }

    App_Start -> Startup.cs

    using Microsoft.Owin;
    using Microsoft.Owin.Security.OAuth;
    using OAuth.Providers;
    using Owin;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    
    namespace OAuth
    {
        public partial class Startup
        {
            public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }
    
            static Startup()
            {
                OAuthOptions = new OAuthAuthorizationServerOptions
                {
                    TokenEndpointPath = new PathString("/token"),
                    Provider = new OAuthProvider(),
                    //AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
                    AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(1),
                    AllowInsecureHttp = true
                };
            }
            public void ConfigureAuth(IAppBuilder app)
            {
                app.UseOAuthBearerTokens(OAuthOptions);
            }
        }
    }


    Please help me clear the above queries.

    Hope to receive answer to all questions.


    Thanks
    Vinod

    Wednesday, March 7, 2018 5:05 PM

All replies

  • User283571144 posted

    Hi vinod_praviram,

    1. how to read/decrypt access token in web api - Is it possible to read or decrypt custom data or user id/email from access token at controller level?

    As far as I know, we could use Startup.OAuthOptions.AccessTokenFormat.Unprotect method to decrypt  the token.

    Details, you could refer to below codes sample:

            [Authorize]
            public IEnumerable<string> Get()
            {
               var re =  HttpContext.Current.Request.Headers["authorization"];
                ResolveToken(re.ToString().Replace("bearer  ", ""));
                 return new string[] { "value1", "value2" };
            }
    
            public void  ResolveToken(string Token)
            {
                //First Token decryption
                AuthenticationTicket ticket = Startup.OAuthOptions.AccessTokenFormat.Unprotect(Token);
                if (ticket != null && (ticket.Properties != null && ticket.Properties.ExpiresUtc.HasValue))
                {
                    ClaimsIdentity identity = ticket.Identity;
                    string chaimname = identity.Name;
                }
        
            }

    Result:

    Besides, in our forum we suggest one thread talking about one question.

    I suggest you could ask the different question with separate theard. 

    It will be more easily for other folks who faces the same issue.

    Best Regards,

    Brando

    Thursday, March 8, 2018 7:26 AM
  • User517361227 posted

    Hi Brando,

    Thanks for replying and as those all questions were related to same thing so I posted at once.

    Will check the unprotect method soon.

    Thanks
    Vinod

    Thursday, March 8, 2018 4:18 PM
  • User283571144 posted

    Hi vinod_praviram,

    As I says, you have asked too many question in one thread, each question should have each reply and sample code.

    I suggest you could ask the different question with separate thread.

    Thank you.

    Best Regards,

    Brando

    Monday, March 12, 2018 1:19 AM
  • User517361227 posted

    Hi Brando,

    I know that, that's why I posted separate query :)

    Monday, March 12, 2018 4:25 PM