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