加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-web-api – web api – asp.net身份令牌即使对于后续请

发布时间:2020-12-16 03:17:01 所属栏目:asp.Net 来源:网络整理
导读:我在web api中使用asp.net身份进行基于令牌的身份验证. 对于刷新令牌,我已经基于以下链接实现了 http://bitoftech.net/2014/07/16/enable-oauth-refresh-tokens-angularjs-app-using-asp-net-web-api-2-owin/ 我添加了以下两个类,并在启动配置中提到. 从ui我
我在web api中使用asp.net身份进行基于令牌的身份验证.

对于刷新令牌,我已经基于以下链接实现了

> http://bitoftech.net/2014/07/16/enable-oauth-refresh-tokens-angularjs-app-using-asp-net-web-api-2-owin/

我添加了以下两个类,并在启动配置中提到.

从ui我通过api单独使用用户名和密码调用

http://domain/token

当我调用上面的api时,请求直接转到ValidateClientAuthentication方法.

但在这种方法逻辑中,我们需要发送客户端ID和客户端密钥.

在用户登录特定用户之前,我们如何知道这两个?

我认为工作流程应该是这样的,我们需要检查数据库的用户名和密码,并应生成访问令牌和刷新令牌.

但是我在哪里做这个逻辑.

样本中提到的这个系统的工作流程是什么?

在此系统之前,我将在我的应用程序中调用Common / login api,并在成功验证后,

我将调用代码使用户登录

var userIdentity=await user.GenerateUserIdentityAsync(UserManager);

AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent },userIdentity);

在上面的代码之后,我将从用户身份生成访问令牌.

我已经多次尝试过以下实现并厌倦了流程.

帮助我关于这里提到的逻辑和流程.

SimpleAuthorizationServerProvider

namespace AngularJSAuthentication.API.Providers
    {
        public class SimpleAuthorizationServerProvider : OAuthAuthorizationServerProvider
        {
            public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
            {

                string clientId = string.Empty;
            string clientSecret = string.Empty;
            Client client = null;

            if (!context.TryGetBasicCredentials(out clientId,out clientSecret))
            {
                context.TryGetFormCredentials(out clientId,out clientSecret);
            }

            if (context.ClientId == null)
            {
                //Remove the comments from the below line context.SetError,and invalidate context 
                //if you want to force sending clientId/secrects once obtain access tokens. 
                context.Validated();
                //context.SetError("invalid_clientId","ClientId should be sent.");
                return Task.FromResult<object>(null);
            }

            using (AuthRepository _repo = new AuthRepository())
            {
                client = _repo.FindClient(context.ClientId);
            }

            if (client == null)
            {
                context.SetError("invalid_clientId",string.Format("Client '{0}' is not registered in the system.",context.ClientId));
                return Task.FromResult<object>(null);
            }

            if (client.ApplicationType == Models.ApplicationTypes.NativeConfidential)
            {
                if (string.IsNullOrWhiteSpace(clientSecret))
                {
                    context.SetError("invalid_clientId","Client secret should be sent.");
                    return Task.FromResult<object>(null);
                }
                else
                {
                    if (client.Secret != Helper.GetHash(clientSecret))
                    {
                        context.SetError("invalid_clientId","Client secret is invalid.");
                        return Task.FromResult<object>(null);
                    }
                }
            }

            if (!client.Active)
            {
                context.SetError("invalid_clientId","Client is inactive.");
                return Task.FromResult<object>(null);
            }

            context.OwinContext.Set<string>("as:clientAllowedOrigin",client.AllowedOrigin);
            context.OwinContext.Set<string>("as:clientRefreshTokenLifeTime",client.RefreshTokenLifeTime.ToString());

            context.Validated();
            return Task.FromResult<object>(null);
        }

        public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
        {

            var allowedOrigin = context.OwinContext.Get<string>("as:clientAllowedOrigin");

            if (allowedOrigin == null) allowedOrigin = "*";

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

            using (AuthRepository _repo = new AuthRepository())
            {
                IdentityUser user = await _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(ClaimTypes.Name,context.UserName));
            identity.AddClaim(new Claim(ClaimTypes.Role,"user"));
            identity.AddClaim(new Claim("sub",context.UserName));

            var props = new AuthenticationProperties(new Dictionary<string,string>
                {
                    { 
                        "as:client_id",(context.ClientId == null) ? string.Empty : context.ClientId
                    },{ 
                        "userName",context.UserName
                    }
                });

            var ticket = new AuthenticationTicket(identity,props);
            context.Validated(ticket);

        }

        public override Task GrantRefreshToken(OAuthGrantRefreshTokenContext context)
        {
            var originalClient = context.Ticket.Properties.Dictionary["as:client_id"];
            var currentClient = context.ClientId;

            if (originalClient != currentClient)
            {
                context.SetError("invalid_clientId","Refresh token is issued to a different clientId.");
                return Task.FromResult<object>(null);
            }

            // Change auth ticket for refresh token requests
            var newIdentity = new ClaimsIdentity(context.Ticket.Identity);

            var newClaim = newIdentity.Claims.Where(c => c.Type == "newClaim").FirstOrDefault();
            if (newClaim != null)
            {
                newIdentity.RemoveClaim(newClaim);
            }
            newIdentity.AddClaim(new Claim("newClaim","newValue"));

            var newTicket = new AuthenticationTicket(newIdentity,context.Ticket.Properties);
            context.Validated(newTicket);

            return Task.FromResult<object>(null);
        }

        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);
        }

    }
}

SimpleRefreshTokenProvider

namespace AngularJSAuthentication.API.Providers
{
    public class SimpleRefreshTokenProvider : IAuthenticationTokenProvider
    {

        public async Task CreateAsync(AuthenticationTokenCreateContext context)
        {
            var clientid = context.Ticket.Properties.Dictionary["as:client_id"];

            if (string.IsNullOrEmpty(clientid))
            {
                return;
            }

            var refreshTokenId = Guid.NewGuid().ToString("n");

            using (AuthRepository _repo = new AuthRepository())
            {
                var refreshTokenLifeTime = context.OwinContext.Get<string>("as:clientRefreshTokenLifeTime"); 

                var token = new RefreshToken() 
                { 
                    Id = Helper.GetHash(refreshTokenId),ClientId = clientid,Subject = context.Ticket.Identity.Name,IssuedUtc = DateTime.UtcNow,ExpiresUtc = DateTime.UtcNow.AddMinutes(Convert.ToDouble(refreshTokenLifeTime)) 
                };

                context.Ticket.Properties.IssuedUtc = token.IssuedUtc;
                context.Ticket.Properties.ExpiresUtc = token.ExpiresUtc;

                token.ProtectedTicket = context.SerializeTicket();

                var result = await _repo.AddRefreshToken(token);

                if (result)
                {
                    context.SetToken(refreshTokenId);
                }

            }
        }

        public async Task ReceiveAsync(AuthenticationTokenReceiveContext context)
        {

            var allowedOrigin = context.OwinContext.Get<string>("as:clientAllowedOrigin");
            context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin",new[] { allowedOrigin });

            string hashedTokenId = Helper.GetHash(context.Token);

            using (AuthRepository _repo = new AuthRepository())
            {
                var refreshToken = await _repo.FindRefreshToken(hashedTokenId);

                if (refreshToken != null )
                {
                    //Get protectedTicket from refreshToken class
                    context.DeserializeTicket(refreshToken.ProtectedTicket);
                    var result = await _repo.RemoveRefreshToken(hashedTokenId);
                }
            }
        }

        public void Create(AuthenticationTokenCreateContext context)
        {
            throw new NotImplementedException();
        }

        public void Receive(AuthenticationTokenReceiveContext context)
        {
            throw new NotImplementedException();
        }
    }
}

解决方法

如何使用刷新令牌并将它们存储在数据库中,如以下两个示例:

> http://bitoftech.net/2014/07/16/enable-oauth-refresh-tokens-angularjs-app-using-asp-net-web-api-2-owin/
> http://leastprivilege.com/2013/11/15/adding-refresh-tokens-to-a-web-api-v2-authorization-server/

如第一个链接中广泛描述的那样,您可以创建自己的令牌提供程序实现来处理令牌刷新:

public class SimpleRefreshTokenProvider : IAuthenticationTokenProvider
{

    public async Task CreateAsync(AuthenticationTokenCreateContext context)
    {
        var clientid = context.Ticket.Properties.Dictionary["as:client_id"];

        if (string.IsNullOrEmpty(clientid))
        {
            return;
        }

        var refreshTokenId = Guid.NewGuid().ToString("n");

        using (AuthRepository _repo = new AuthRepository())
        {
            var refreshTokenLifeTime = context.OwinContext.Get<string>("as:clientRefreshTokenLifeTime"); 

            var token = new RefreshToken() 
            { 
                Id = Helper.GetHash(refreshTokenId),ExpiresUtc = DateTime.UtcNow.AddMinutes(Convert.ToDouble(refreshTokenLifeTime)) 
            };

            context.Ticket.Properties.IssuedUtc = token.IssuedUtc;
            context.Ticket.Properties.ExpiresUtc = token.ExpiresUtc;

            token.ProtectedTicket = context.SerializeTicket();

            var result = await _repo.AddRefreshToken(token);

            if (result)
            {
                context.SetToken(refreshTokenId);
            }

        }
    }
 }

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读