2012-06-01 2 views
1

Мы хотим сделать STS, который передает аутентификацию Google.Как сделать STS с использованием Gmail OAuth

После шагов, указанных в https://developers.google.com/accounts/docs/OAuth2Login?hl=es-ES мы имеем следующий код в Login.aspx генерируется шаблон веб-сайта ГНС ​​в VS2010:

protected void Page_Load(object sender, EventArgs e) 
{ 
    if (Request.QueryString["code"] != null) 
    { 
     //I'm coming from google, already authenticated 
     FormsAuthentication.SetAuthCookie(GetUserName(Request.QueryString["code"]), false); 
     Response.Redirect("default.aspx"); 
    } 
    else 
    { 
     //I want to authenticate 
     Response.Redirect(
      "https://accounts.google.com/o/oauth2/auth?" + 
      "response_type=code&" + 
      "client_id=988046895016.apps.googleusercontent.com&" + 
      "redirect_uri=" + HttpUtility.UrlEncode("https://localhost/GmailSTS/login.aspx") + "&" + 
      "scope=" + HttpUtility.UrlEncode("https://www.googleapis.com/auth/userinfo.email") 
      ); 
    } 
} 

Но я получаю ошибку beacuse ва не указано в QueryString , отладка образцов и сгенерированный шаблон я увидел, что в, wtrealm, wctx и ДАП являются параметрами, необходимыми, чтобы я использовал параметр состояния, чтобы они туда и обратно и получить их обратно:

protected void Page_Load(object sender, EventArgs e) 
{ 
    if (Request.QueryString["code"] != null) 
    { 
     //I'm coming from google, already authenticated 
     FormsAuthentication.SetAuthCookie("johannsw", false); 
     String lQueryStrings = HttpUtility.UrlDecode(Request.QueryString["state"]); 
     lQueryStrings.Replace('?', '&'); 
     Response.Redirect("default.aspx" + "?" + lQueryStrings); 

    } 
    else 
    { 
     //I want to authenticate 
     String lState = String.Empty; 
     foreach (var key in Request.QueryString.AllKeys) 
     { 
      if (String.Equals("wa", key) || 
       String.Equals("wtrealm", key) || 
       String.Equals("wctx", key) || 
       String.Equals("wct", key)) 
       lState += key + "=" + Request.QueryString[key] + "&"; 
     } 
     lState = lState.Remove(lState.Length - 1); 

     Response.Redirect(
      "https://accounts.google.com/o/oauth2/auth?" + 
      "response_type=code&" + 
      "client_id=988046895016.apps.googleusercontent.com&" + 
      "redirect_uri=" + HttpUtility.UrlEncode("https://localhost/GmailSTS/login.aspx") + "&" + 
      "scope=" + HttpUtility.UrlEncode("https://www.googleapis.com/auth/userinfo.email") + "&" + 
      "state=" + HttpUtility.UrlEncode(lState) 
      ); 
    } 
} 

но теперь я получаю сообщение об ошибке говорящее «Использование POST-протокола HTTP-протокола d для доступа к пути '/ WebSite1 /' не допускается. "

Любые подсказки? Спасибо!

ответ

1

Ну, наконец, я сделал это. Вот как я решил это только в случае, если это помогает кто-то еще:

Login.aspx.cs

protected void Page_Load(object sender, EventArgs e) 
{ 
    if (Request.QueryString["code"] != null && Request.QueryString["error"] != "access_denied") 
    { 
     // If I got code and no error then 
     // ask for access_code so I can get user email 

     //Here I ask for the access_code. 
     WebRequest requestLogIn = null; 
     Stream stream = null; 
     WebResponse response = null; 
     StreamReader reader = null; 

     string sendData = "code=" + Request.QueryString["code"] + "&"; 
     sendData += "client_id=" + ObtenerClientID() + "&"; 
     sendData += "client_secret=" + ObtenerClientSecret() + "&"; 
     sendData += "redirect_uri=" + System.Configuration.ConfigurationManager.AppSettings["urlLogin"] + "&"; //TODO: ver si es necesario 
     sendData += "grant_type=authorization_code"; 

     requestLogIn = WebRequest.Create("https://accounts.google.com/o/oauth2/token"); 

     requestLogIn.Method = "POST"; 
     requestLogIn.ContentType = "application/x-www-form-urlencoded"; 

     byte[] arrayToSend = Encoding.UTF8.GetBytes(sendData); 
     requestLogIn.ContentLength = arrayToSend.Length; 

     stream = requestLogIn.GetRequestStream(); 
     stream.Write(arrayToSend, 0, arrayToSend.Length); 
     stream.Close(); 

     response = requestLogIn.GetResponse(); 

     if (((HttpWebResponse)response).StatusCode == HttpStatusCode.OK) 
     { 
      stream = response.GetResponseStream(); 
      reader = new StreamReader(stream); 
      string responseValue = reader.ReadToEnd(); 
      reader.Close(); 

      var lJSONResponse = new JavaScriptSerializer().Deserialize<JSONResponseToken>(responseValue); 

      //Now that I have the access_code ask for the user email so I can match him in my base and load claims. 

      WebRequest myRequest = WebRequest.Create("https://www.googleapis.com/oauth2/v2/userinfo"); 
      myRequest.Method = "GET"; 

      myRequest.Headers.Add("Authorization", "Bearer " + lJSONResponse.Access_Token); 

      response = myRequest.GetResponse(); 
      if (((HttpWebResponse)response).StatusCode == HttpStatusCode.OK) 
      { 
       stream = response.GetResponseStream(); 
       reader = new StreamReader(stream); 
       responseValue = reader.ReadToEnd(); 

       var lUserMail = new JavaScriptSerializer().Deserialize<JSONResponseUserMail>(responseValue); 

       // User is authenticated 
       FormsAuthentication.SetAuthCookie(lUserMail.Email, false); 

       // default.aspx will load claims 
       Response.Redirect("default.aspx?" + Request.QueryString.ToString()); 
      } 
     } 


    } 
    else 
    { 
     //redirect to google for login. 

     //Save original url in a cookie for later use. 
     Guid lGuid = Guid.NewGuid(); 
     CreateContextCookie(lGuid.ToString(), this.Request.Url.AbsoluteUri); 

     Response.Redirect(
      "https://accounts.google.com/o/oauth2/auth?" + 
      "response_type=code&" + 
      "client_id=" + ObtenerClientID() + "&" + 
      //I want to return here again 
      "redirect_uri=" + HttpUtility.UrlEncode(System.Configuration.ConfigurationManager.AppSettings["urlLogin"]) + "&" + 
      //Add scope so I can get user mail. 
      "scope=" + HttpUtility.UrlEncode("https://www.googleapis.com/auth/userinfo.email") + "&" + 
      //Reference to the cookie so I can get the original url again 
      "state=" + HttpUtility.UrlEncode(lGuid.ToString()) 
      ); 
    } 
} 

Default.aspx.cs:

защищен недействительным Page_PreRender (объект отправителя, EventArgs е) {

String lCode = Request.QueryString["code"]; 
    String lSTate = Request.QueryString["state"]; 
    var ctxCookie = this.Request.Cookies[lSTate]; 

    var requestMessage = (SignInRequestMessage)WSFederationMessage.CreateFromUri(new Uri(ctxCookie.Value)); 
    //Erase cookie 
    var contextCookie = new HttpCookie(lSTate) 
    { 
     Expires = DateTime.UtcNow.AddDays(-1) 
    }; 

    //process login request 
    SecurityTokenService sts = 
     new CustomSecurityTokenService(CustomSecurityTokenServiceConfiguration.Current); 
    SignInResponseMessage responseMessage = 
     FederatedPassiveSecurityTokenServiceOperations.ProcessSignInRequest(requestMessage, this.User, sts); 
    FederatedPassiveSecurityTokenServiceOperations.ProcessSignInResponse(responseMessage, this.Response); 

    this.Response.Cookies.Add(contextCookie); 
} 
Смежные вопросы