/// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        private void HandleImplicitGrant(OAuthAuthorizeEndpointContext context, OauClient client, string redirectUri)
        {
            var oAuthIdentity = new ClaimsIdentity("Bearer");

            context.OwinContext.Authentication.SignIn(oAuthIdentity);
            context.RequestCompleted();
        }
        /// <summary>
        ///  当grant_type=password 触发该事件
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public override async Task GrantResourceOwnerCredentials(
            OAuthGrantResourceOwnerCredentialsContext context)
        {
            logger.Debug("GrantResourceOwnerCredentials");
            string    error  = "invalid_grant";
            OauClient client = Clients.ApiClients.FirstOrDefault(a => a.AppId == context.ClientId);

            if (client == null)
            {
                context.SetError(error, "无效clientId");
                return;
            }
            if (string.IsNullOrEmpty(context.UserName) || string.IsNullOrEmpty(context.Password))
            {
                context.SetError(error, "用户名或密码不能为空");
                return;
            }
            //调用后台的登录服务验证用户名与密码
            if (!CheckUser(context.UserName, context.Password))
            {
                context.SetError(error, "用户名或密码不能为空");
                return;
            }
            var oAuthIdentity = new ClaimsIdentity(context.Options.AuthenticationType);

            oAuthIdentity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
            //获取附加的请求参数
            IDictionary <string, object> parameters = context.OwinContext.Environment;

            if (parameters != null)
            {
                //foreach (var item in parameters)
                //{
                //    //添加附加凭证信息
                //    oAuthIdentity.AddClaim(new Claim(OAuthKeys.Prefix+item.Key,item.Value.ToString()));
                //}
            }
            var oauthProps = new AuthenticationProperties(new Dictionary <string, string>
            {
                {
                    OAuthKeys.AuthPropClientId, context.ClientId
                }
            })
            {
                // Gets or sets the time at which the authentication ticket was issued.
                IssuedUtc = DateTime.UtcNow,
                // Gets or sets the time at which the authentication ticket expires.
                ExpiresUtc = DateTime.UtcNow.AddMinutes(client.RefreshTokenLifeTime)
            };
            var  ticket         = new AuthenticationTicket(oAuthIdentity, oauthProps);
            bool validateResult = context.Validated(ticket);

            if (!validateResult)
            {
                context.SetError(error, "validate 失败");
            }
            await base.GrantResourceOwnerCredentials(context);
        }
        /// <summary>
        /// 验证clientId与clientSecret
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
        {
            logger.Debug("ValidateClientAuthentication");
            string clientId;
            string clientSecret;
            int    code             = 0;
            string error            = "invalid_client";
            string errorDescription = "";

            if (!context.TryGetBasicCredentials(out clientId, out clientSecret))
            {
                context.TryGetFormCredentials(out clientId, out clientSecret);
            }
            if (string.IsNullOrEmpty(clientId) || string.IsNullOrEmpty(clientSecret))
            {
                errorDescription = "参数有误";
            }
            else
            {
                //获取附加的请求参数
                IReadableStringCollection parameters = context.Parameters;
                OauClient client = Clients.ApiClients.FirstOrDefault(a => a.AppId == clientId && a.AppSecret == clientSecret);
                if (client == null)
                {
                    errorDescription = "无效clientId或者无效的clientSecret";
                }
                else
                {
                    code = 1;
                    if (parameters != null)
                    {
                        //在OWIN环境中添加附加的请求参数
                        foreach (var item in parameters)
                        {
                            context.OwinContext.Set(OAuthKeys.Prefix + item.Key, string.Join(",", item.Value));
                        }
                        logger.Debug("ValidateClientAuthentication,context.Parameters:" + JsonConvert.SerializeObject(parameters));
                    }
                }
            }
            if (code == 1)
            {
                //设置客户机id并标记应用程序验证的上下文
                bool validateResult = context.Validated(clientId);
                logger.Debug("ValidateClientAuthentication,validateResult:" + validateResult);
                if (!validateResult)
                {
                    context.SetError(error, "validate 失败");
                }
            }
            else
            {
                //设置错误的响应信息
                context.SetError(error, errorDescription);
            }
            await base.ValidateClientAuthentication(context);
        }
        /// <summary>
        /// 当grant_type=client_credentials触发该事件
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public override async Task GrantClientCredentials(OAuthGrantClientCredentialsContext context)
        {
            logger.Debug("GrantClientCredentials");
            string error = "invalid_grant";

            if (string.IsNullOrEmpty(context.ClientId))
            {
                context.SetError(error, "无效clientId");
            }
            else
            {
                OauClient client = Clients.ApiClients.FirstOrDefault(a => a.AppId == context.ClientId);
                if (client != null)
                {
                    //获取附加的请求参数
                    IDictionary <string, object> parameters = context.OwinContext.Environment;

                    int tokenLifeTime = client.RefreshTokenLifeTime;
                    var oAuthIdentity = new ClaimsIdentity(context.Options.AuthenticationType);
                    if (parameters != null)
                    {
                        //foreach (var item in parameters)
                        //{
                        //    //添加附加凭证信息
                        //   oAuthIdentity.AddClaim(new Claim(OAuthKeys.Prefix+item.Key,item.Value.ToString()));
                        //}
                    }
                    bool validateResult = false;
                    var  oauthProps     = new AuthenticationProperties(new Dictionary <string, string>
                    {
                        {
                            OAuthKeys.AuthPropClientId, context.ClientId
                        }
                    })
                    {
                        // Gets or sets the time at which the authentication ticket was issued.
                        IssuedUtc = DateTime.UtcNow,
                        // Gets or sets the time at which the authentication ticket expires.
                        ExpiresUtc = DateTime.UtcNow.AddMinutes(client.RefreshTokenLifeTime)
                    };
                    //替换此上下文中的票据信息,并将其标记为已验证
                    var ticket = new AuthenticationTicket(oAuthIdentity, oauthProps);
                    validateResult = context.Validated(ticket);
                    if (!validateResult)
                    {
                        context.SetError(error, "validate失败");
                    }
                }
                else
                {
                    context.SetError(error, "无效clientId");
                }
            }
            await base.GrantClientCredentials(context);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="context"></param>
        /// <param name="client"></param>
        /// <param name="redirectUri"></param>
        /// <returns></returns>
        private async Task HandleAuthorizationCodeGrant(OAuthAuthorizeEndpointContext context
                                                        , OauClient client, string redirectUri)
        {
            #region Settin Token
            context.OwinContext.Set(OAuthKeys.ClientId, client.AppId);
            context.OwinContext.Set(OAuthKeys.Prefix + "client_secret", client.AppSecret);

            var oAuthIdentity = new ClaimsIdentity(context.Options.AuthenticationType);
            oAuthIdentity.AddClaim(new Claim(ClaimTypes.Name, Guid.NewGuid().ToString("n")));
            var oauthProps = new AuthenticationProperties(new Dictionary <string, string>
            {
                {
                    OAuthKeys.AuthPropClientId, client.AppId
                }
            })
            {
                // Gets or sets the time at which the authentication ticket was issued.
                IssuedUtc = DateTime.UtcNow,
                // Gets or sets the time at which the authentication ticket expires.
                ExpiresUtc = DateTime.UtcNow.AddMinutes(client.RefreshTokenLifeTime),
                //  Gets or sets the full path or absolute URI to be used as an http redirect response
                RedirectUri = redirectUri
            };
            //替换此上下文中的票据信息,并将其标记为已验证
            var ticket = new AuthenticationTicket(oAuthIdentity, oauthProps);
            var authorizeCodeContext = new AuthenticationTokenCreateContext(
                context.OwinContext,
                context.Options.AuthorizationCodeFormat,
                ticket);

            await context.Options.AuthorizationCodeProvider.CreateAsync(authorizeCodeContext);

            #endregion Setting Token

            string token = authorizeCodeContext.Token ?? string.Empty; //由于获取的token与设置的token不一致
                                                                       //string token = authorizeCodeContext.OwinContext.Get<string>(OAuthKeys.AuthorizeCodeToken) ?? string.Empty;
            var url = redirectUri + "?code=" + Uri.EscapeDataString(token);
            logger.Debug("AuthorizeEndpoint,authorization_code,url:" + url);
            context.Response.Redirect(url);
            context.RequestCompleted();
        }
Example #6
0
        /// <summary>
        /// 生成 refresh_token
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public async Task CreateAsync(AuthenticationTokenCreateContext context)
        {
            logger.Debug("CreateAsync");
            if (context.Ticket.Properties != null)
            {
                logger.Debug("CreateAsync,context.Ticket.Properties:" + JsonConvert.SerializeObject(context.Ticket.Properties));
            }
            var clientId = context.OwinContext.Get <string>(OAuthKeys.ClientId);

            if (!string.IsNullOrEmpty(clientId))
            {
                OauClient client = Clients.ApiClients.FirstOrDefault(a => a.AppId == clientId);
                if (client != null)
                {
                    var refreshTokenModel = GetRefreshToken(context, clientId, client);
                    //调用RefreshToken服务保存Token
                    var insertResult = await HandleCreateToken(refreshTokenModel);

                    if (insertResult > 0)
                    {
                        #region  Setting Token
                        // Gets or sets the time at which the authentication ticket was issued.
                        context.Ticket.Properties.IssuedUtc = DateTime.UtcNow;
                        // Gets or sets the time at which the authentication ticket expires.
                        context.Ticket.Properties.ExpiresUtc          = DateTime.UtcNow.AddMinutes(client.RefreshTokenLifeTime);
                        refreshTokens[refreshTokenModel.RefreshToken] = refreshTokenModel.ProtectedTicket;
                        context.Ticket.Properties.Dictionary.Add(OAuthKeys.RefreshToken, refreshTokenModel.RefreshToken);
                        //设置RefreshToken的key
                        context.SetToken(refreshTokenModel.RefreshToken);

                        if (refreshTokens != null)
                        {
                            logger.Debug("CreateAsync,HandleCreateToken,refreshTokens:" + JsonConvert.SerializeObject(refreshTokens));
                        }
                        #endregion  Setting Token
                    }
                }
            }
        }
        /// <summary>
        /// 生成 refresh_token
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public async Task CreateAsync(AuthenticationTokenCreateContext context)
        {
            var clientId = context.OwinContext.Get <string>(OAuthKeys.ClientId);

            logger.Debug("CreateAsync,clientId:" + clientId);
            if (context.Ticket.Properties != null)
            {
                logger.Debug("CreateAsync,context.Ticket.Properties:" + JsonConvert.SerializeObject(context.Ticket.Properties));
            }
            if (!string.IsNullOrEmpty(clientId))
            {
                OauClient client = Clients.ApiClients.FirstOrDefault(a => a.AppId == clientId);
                if (client != null)
                {
                    //调用RefreshToken服务保存Token
                    var insertResult = await HandleCreateToken();

                    if (insertResult > 0)
                    {
                        #region Setting Token
                        // Gets or sets the time at which the authentication ticket was issued.
                        context.Ticket.Properties.IssuedUtc = DateTime.UtcNow;
                        // Gets or sets the time at which the authentication ticket expires.
                        context.Ticket.Properties.ExpiresUtc = DateTime.UtcNow.AddMinutes(client.RefreshTokenLifeTime);
                        var token = Guid.NewGuid().ToString("n") + Guid.NewGuid().ToString("n");
                        context.SetToken(token);
                        authenticationCodes[token] = context.SerializeTicket();
                        //context.OwinContext.Set(OAuthKeys.AuthorizeCodeToken, token);
                        if (authenticationCodes != null)
                        {
                            logger.Debug("CreateAsync,HandleCreateToken,authenticationCodes:" + JsonConvert.SerializeObject(authenticationCodes));
                        }
                        #endregion Setting Token
                    }
                }
            }
        }
        /// <summary>
        /// 生成 authorization_code(authorization code 授权方式)、生成 access_token (implicit 授权模式)
        /// </summary>
        public override async Task AuthorizeEndpoint(OAuthAuthorizeEndpointContext context)
        {
            string          redirectUri = string.Empty, clientId = string.Empty, clientSecret = string.Empty;
            IFormCollection formColls = await context.Request.ReadFormAsync();

            //form类型的参数
            if (formColls != null && formColls.Count() > 0)
            {
                redirectUri  = formColls["redirect_uri"];
                clientId     = formColls["client_id"];
                clientSecret = formColls["client_secret"];
            }
            else
            {
                //url类型的参数
                redirectUri  = context.Request.Query["redirect_uri"];
                clientId     = context.Request.Query["client_id"];
                clientSecret = context.Request.Query["client_secret"];
            }
            OauClient client = Clients.ApiClients.FirstOrDefault(a => a.AppId == clientId && a.AppSecret == clientSecret);

            if (context.AuthorizeRequest.IsImplicitGrantType)
            {
                logger.Debug("AuthorizeEndpoint,implicit");
                //implicit 授权方式
                HandleImplicitGrant(context, client, redirectUri);
            }
            else if (context.AuthorizeRequest.IsAuthorizationCodeGrantType)
            {
                //authorization code 授权方式
                if (client != null)
                {
                    await HandleAuthorizationCodeGrant(context, client, redirectUri);
                }
            }
        }
Example #9
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="context"></param>
        /// <param name="clientId"></param>
        /// <param name="client"></param>
        /// <returns></returns>
        private OauRefreshToken GetRefreshToken(AuthenticationTokenCreateContext context, string clientId, OauClient client)
        {
            var identity = context.Ticket.Identity;

            if (identity == null)
            {
                return(null);
            }
            int    userId          = 0;
            string userName        = identity.Name;
            string customTokenType = string.Empty;
            //var userExtInfo = context.OwinContext.Get<string>("as:userExtInfo");
            //string deviceId = context.OwinContext.Get<string>("as:deviceId");
            //string customTokenType = context.OwinContext.Get<string>("as:customTokenType");
            //if (string.IsNullOrEmpty(customTokenType))
            //{
            //    customTokenType = identity.AuthenticationType;
            //}
            //if (userId < 1 && identity.Claims != null)
            //{
            //    var tmpUserId = identity.Claims.FirstOrDefault(a => a.Type == ClaimTypes.PrimarySid);
            //    if (tmpUserId != null)
            //    {
            //        userId = Convert.ToInt32(tmpUserId.Value);
            //    }
            //}
            //if (string.IsNullOrEmpty(userExtInfo) && identity.Claims != null)
            //{
            //    var tmpUserData = identity.Claims.FirstOrDefault(a => a.Type == ClaimTypes.UserData);
            //    if (tmpUserData != null)
            //    {
            //        userExtInfo = tmpUserData.Value;
            //    }
            //}
            var refreshTokenId = Guid.NewGuid().ToString("n");
            var refreshToken   = new OauRefreshToken()
            {
                AppId           = clientId,
                ExpiresUtc      = DateTime.UtcNow.AddMinutes(client.RefreshTokenLifeTime),
                IssuedUtc       = DateTime.UtcNow,
                ProtectedTicket = context.SerializeTicket(),
                RefreshToken    = refreshTokenId,
                TokenType       = identity.AuthenticationType,
                UserName        = userName,
                UserID          = userId,
                CustomTokenType = customTokenType,
                AccessToken     = string.Empty
            };

            return(refreshToken);
        }