/// <summary> /// Invoked whenever succesfully authenticates a user /// </summary> public Task Authenticated(QQAuthenticatedContext context) { return(OnAuthenticated(context)); }
/// <summary> /// 授权处理 /// </summary> /// <returns></returns> protected override async Task <AuthenticationTicket> AuthenticateCoreAsync() { AuthenticationProperties properties = null; try { string code = null; string state = null; IReadableStringCollection query = Request.Query; IList <string> values = query.GetValues("code"); if (values != null && values.Count == 1) { code = values[0]; } values = query.GetValues("state"); if (values != null && values.Count == 1) { state = values[0]; } properties = Options.StateDataFormat.Unprotect(state); if (properties == null) { return(null); } // OAuth2 10.12 CSRF if (!ValidateCorrelationId(properties, _logger)) { return(new AuthenticationTicket(null, properties)); } // 获取 accessToken 授权令牌 var oauth2Token = await ObtainAccessTokenAsync(code); string accessToken = oauth2Token["access_token"]; // Refresh token is only available // Otherwise, it is null. var refreshToken = oauth2Token["refresh_token"]; var expire = oauth2Token["expires_in"]; if (string.IsNullOrWhiteSpace(accessToken)) { _logger.WriteWarning("Access token was not found"); return(new AuthenticationTicket(null, properties)); } // 获取用户openid JObject userOpenIdToken = await ObtainUserOpenIdAsync(accessToken); string openId = userOpenIdToken["openid"].Value <string>(); if (string.IsNullOrEmpty(openId)) { _logger.WriteWarning("User openId was not found"); return(new AuthenticationTicket(null, properties)); } // 获取用户个人信息 JObject userInfoToken = await ObtainUserInfoAsync(accessToken, openId); var context = new QQAuthenticatedContext(Context, openId, userInfoToken, accessToken, refreshToken, expire); context.Identity = new ClaimsIdentity(new[] { new Claim(ClaimTypes.NameIdentifier, context.OpenId, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationType), new Claim(ClaimTypes.Name, context.Nickame, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationType), new Claim("urn:qqconnect:id", context.OpenId, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationType), new Claim("urn:qqconnect:name", context.Nickame, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationType), new Claim(Constants.QQClaimType, userInfoToken.ToString(), "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationType), }, Options.AuthenticationType, ClaimsIdentity.DefaultNameClaimType, ClaimsIdentity.DefaultRoleClaimType); context.Properties = properties; // 没有Email //if (!string.IsNullOrWhiteSpace(context.Email)) //{ // context.Identity.AddClaim(new Claim(ClaimTypes.Email, context.Email, "http://www.w3.org/2001/XMLSchema#string", Options.AuthenticationType)); //} await Options.Provider.Authenticated(context); return(new AuthenticationTicket(context.Identity, context.Properties)); } catch (Exception ex) { _logger.WriteError("Authentication failed", ex); return(new AuthenticationTicket(null, properties)); } }
/// <summary> /// /// </summary> /// <returns></returns> protected override async Task <AuthenticationTicket> AuthenticateCoreAsync() { AuthenticationProperties properties = null; try { string code = null; string state = null; IReadableStringCollection query = Request.Query; IList <string> values = query.GetValues("code"); if (values != null && values.Count == 1) { code = values[0]; } values = query.GetValues("state"); if (values != null && values.Count == 1) { state = values[0]; } properties = Options.StateDataFormat.Unprotect(state); if (properties == null) { return(null); } // OAuth2 10.12 CSRF if (!ValidateCorrelationId(properties, _logger)) { return(new AuthenticationTicket(null, properties)); } // Check for error if (Request.Query.Get("error") != null) { return(new AuthenticationTicket(null, properties)); } var requestPrefix = Request.Scheme + "://" + Request.Host; var redirectUri = requestPrefix + Request.PathBase + Options.CallbackPath; // Build up the body for the token request var body = new List <KeyValuePair <string, string> > { new KeyValuePair <string, string>("grant_type", "authorization_code"), new KeyValuePair <string, string>("code", code), new KeyValuePair <string, string>("redirect_uri", redirectUri), new KeyValuePair <string, string>("client_id", Options.AppId), new KeyValuePair <string, string>("client_secret", Options.AppSecret) }; // Request the token var tokenResponse = await _httpClient.PostAsync(Options.TokenEndPoint, new FormUrlEncodedContent(body), Request.CallCancelled); tokenResponse.EnsureSuccessStatusCode(); var text = await tokenResponse.Content.ReadAsStringAsync(); // Deserializes the token response dynamic response = JsonConvert.DeserializeObject <dynamic>(text); if (response == null || response.access_token == null) { _logger.WriteWarning("Access token was not found"); return(new AuthenticationTicket(null, properties)); } var accessToken = (string)response.access_token; var expiresIn = (int)response.expires_in; // Get the QQ user //http://wiki.open.qq.com/wiki/website/get_user_info var userResponse = await _httpClient.GetAsync( Options.UserInfoEndPoint + "?access_token=" + Uri.EscapeDataString(accessToken), Request.CallCancelled); userResponse.EnsureSuccessStatusCode(); text = await userResponse.Content.ReadAsStringAsync(); var user = JObject.Parse(text); var context = new QQAuthenticatedContext(Context, user, accessToken, expiresIn) { Identity = new ClaimsIdentity( Options.AuthenticationType, ClaimsIdentity.DefaultNameClaimType, ClaimsIdentity.DefaultRoleClaimType) }; if (!string.IsNullOrEmpty(context.UserId)) { context.Identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, context.UserId, XmlSchemaString, Options.AuthenticationType)); } if (!string.IsNullOrEmpty(context.UserName)) { context.Identity.AddClaim(new Claim(ClaimsIdentity.DefaultNameClaimType, context.UserName, XmlSchemaString, Options.AuthenticationType)); } context.Properties = properties; await Options.Provider.Authenticated(context); return(new AuthenticationTicket(context.Identity, context.Properties)); } catch (Exception ex) { _logger.WriteError(ex.Message); } return(new AuthenticationTicket(null, properties)); }
protected override async Task <AuthenticationTicket> AuthenticateCoreAsync() { AuthenticationProperties properties = null; try { string code = null; string state = null; IReadableStringCollection query = Request.Query; IList <string> values = query.GetValues("error"); if (values != null && values.Count >= 1) { _logger.WriteVerbose("Remote server returned an error: " + Request.QueryString); } values = query.GetValues("code"); if (values != null && values.Count == 1) { code = values[0]; } values = query.GetValues("state"); if (values != null && values.Count == 1) { state = values[0]; } properties = Options.StateDataFormat.Unprotect(state); if (properties == null) { return(null); } // OAuth2 10.12 CSRF if (!ValidateCorrelationId(properties, _logger)) { return(new AuthenticationTicket(null, properties)); } if (code == null) { // Null if the remote server returns an error. return(new AuthenticationTicket(null, properties)); } string requestPrefix = Request.Scheme + "://" + Request.Host; string redirectUri = requestPrefix + Request.PathBase + Options.CallbackPath; string tokenRequest = "grant_type=authorization_code" + "&code=" + Uri.EscapeDataString(code) + "&redirect_uri=" + Uri.EscapeDataString(redirectUri) + "&client_id=" + Uri.EscapeDataString(Options.AppId) + "&client_secret=" + Uri.EscapeDataString(Options.AppSecret); HttpResponseMessage tokenResponse = await _httpClient.GetAsync(Options.TokenEndpoint + "?" + tokenRequest, Request.CallCancelled); tokenResponse.EnsureSuccessStatusCode(); string text = await tokenResponse.Content.ReadAsStringAsync(); IFormCollection form = WebHelpers.ParseForm(text); string accessToken = form["access_token"]; string expires = form["expires"]; string openidAddress = Options.OpenIdEndpoint + "?access_token=" + Uri.EscapeDataString(accessToken); if (Options.SendAppSecretProof) { openidAddress += "&appsecret_proof=" + GenerateAppSecretProof(accessToken); } HttpResponseMessage openidResponse = await _httpClient.GetAsync(openidAddress, Request.CallCancelled); openidResponse.EnsureSuccessStatusCode(); text = await openidResponse.Content.ReadAsStringAsync(); string openid = GetParmFromContent(text, @"""openid"":""(?<openId>[^""]+)""", "openId"); string graphAddress = Options.UserInformationEndpoint + "?access_token=" + Uri.EscapeDataString(accessToken) + "&oauth_consumer_key=" + Uri.EscapeDataString(Options.AppId) + "&openid=" + Uri.EscapeDataString(openid); HttpResponseMessage graphResponse = await _httpClient.GetAsync(graphAddress, Request.CallCancelled); graphResponse.EnsureSuccessStatusCode(); text = await graphResponse.Content.ReadAsStringAsync(); JObject user = JObject.Parse(text); var context = new QQAuthenticatedContext(Context, user, accessToken, expires); context.Identity = new ClaimsIdentity( Options.AuthenticationType, ClaimsIdentity.DefaultNameClaimType, ClaimsIdentity.DefaultRoleClaimType); if (!string.IsNullOrEmpty(context.Id)) { context.Identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, context.Id, XmlSchemaString, Options.AuthenticationType)); } if (!string.IsNullOrEmpty(context.UserName)) { context.Identity.AddClaim(new Claim(ClaimsIdentity.DefaultNameClaimType, context.UserName, XmlSchemaString, Options.AuthenticationType)); } if (!string.IsNullOrEmpty(context.Email)) { context.Identity.AddClaim(new Claim(ClaimTypes.Email, context.Email, XmlSchemaString, Options.AuthenticationType)); } if (!string.IsNullOrEmpty(context.Name)) { context.Identity.AddClaim(new Claim("urn:QQ:name", context.Name, XmlSchemaString, Options.AuthenticationType)); // Many QQ accounts do not set the UserName field. Fall back to the Name field instead. if (string.IsNullOrEmpty(context.UserName)) { context.Identity.AddClaim(new Claim(ClaimsIdentity.DefaultNameClaimType, context.Name, XmlSchemaString, Options.AuthenticationType)); } } if (!string.IsNullOrEmpty(context.Link)) { context.Identity.AddClaim(new Claim("urn:QQ:link", context.Link, XmlSchemaString, Options.AuthenticationType)); } context.Properties = properties; await Options.Provider.Authenticated(context); return(new AuthenticationTicket(context.Identity, context.Properties)); } catch (Exception ex) { _logger.WriteError("Authentication failed", ex); return(new AuthenticationTicket(null, properties)); } }