domingo, 3 de abril de 2011

Simple login con janrain

Gracias a la comunidad alt net hipano, me enteré de janrain, que entre otras cosas, provee un servicio que sirve para autenticar usando cuentas de distintos proveedores (google, facebook, twitter, etc).

Hace poco me tocó agregar un login simple a una aplicación, por lo que decidí probarlo. Es muy fácil. Luego de crear una cuenta y una aplicación, hay que obtener el widget de login. El sitio es muy claro y te va guiando paso a paso.

Paso 1: completar la url de token. Luego que el usuario se loguea, el browser del usuario hace un post a esta url pasando un token. Lo bueno es que la url puede ser localhost, por lo que se puede usar el servicio en un ambiente de desarrollo que no sea visible desde internet.

Paso 2: explica que hacer con ese token. Básicamente, nuestra app tiene que llamar a un servicio de janrain por http, que devuelve un xml o json con los datos del usuario.

Paso 3: elegir los providers. Se trata de elegir si me quiero autenticar con google, facebook, twitter, etc.

Lo simple de todo es es cómo se puede integrar a una aplicación asp mvc. Vamos por pasos.

Primero una interface muy simple para poder autenticar:
public interface ITokenAuthentication {
string Login(string token);
}
Aca se puede ver la interface y su implementación:

Luego, le decimos al web config que vamos a usar form authentication:
<authentication mode="Forms">
<forms loginUrl="~/Home/Index" />
</authentication>

Creamos un controller de autenticación (es al que janrain hace el redirect después que el usuario se loguea):

[HttpPost]
public ActionResult Token(string token) {
string username = tokenAuthentication.Login(token);
FormsService.SignIn(username, true);
return RedirectToAction("Index", "Presupuestador");
}

public ActionResult LogOff() {
FormsService.SignOut();
return RedirectToAction("Index", "Home");
}

Y una vista, donde tenemos que poner antes del body:
<script type="text/javascript">
var rpxJsHost = (("https:" == document.location.protocol) ? "https://" : "http://static.");
document.write(unescape("%3Cscript src='" + rpxJsHost + "rpxnow.com/js/lib/rpx.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
RPXNOW.overlay = true;
RPXNOW.language_preference = 'es';
</script>

La vista podría contener algo como esto:
<% if (Request.IsAuthenticated) { %>
Bienvenido <b><%= Html.Encode(Page.User.Identity.Name) %></b>!
[ <%= Html.ActionLink("Salir", "LogOff", "Account") %> ]
<% } else { %>
<a class="rpxnow" onclick="return false;" href="https://myJanrainApp.rpxnow.com/openid/v2/signin?token_url=<%= Server.UrlEncode(Request.Url.Scheme + "://" + Request.Url.Authority + Url.Action("Token", "Account")) %>">Ingresar</a>
<% } %>

Finalmente, usando un filtro, le decimos al controller X que queremos restringir al acceso para ciertos usuarios:

[Authorize(Users = "myUserName, myFriendUserName")]
public class MyController : Controller

y creo eso es todo.
saludos!