How can I implement the authorization through token and roles, in WEB API C #, SOAP architecture, through the use of repositories with stored procedures and dependency injection?
public override void OnAuthorization(HttpActionContext actionContext)
{
if (actionContext.Request.Headers.Authorization == null)
{
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
}
else
{
string autenticationToken = actionContext.Request.Headers.Authorization.Parameter;
string decodeautenticationToken = Encoding.UTF8.GetString(Convert.FromBase64String(autenticationToken));
string[] userNamePassworArray = decodeautenticationToken.Split(':');
string username = userNamePassworArray[0];
string password = userNamePassworArray[1];
LoginModel model = new LoginModel();
//validate user credentials and obtain user roles (return List Roles)
model.Roleslist = _serviceUsuario.ObtenerRoles(username, password);
if (model.Roleslist !=null)
{
//this line takes a list of roles and divides them with a comma.
string ListRoles = string.Join(",", model.Roleslist.Select(x => x.Roles));
//bacic authentication
Thread.CurrentPrincipal = new GenericPrincipal(new GenericIdentity(username), null);
I tried it in the following way, but it does not work
//ClaimsIdentity oAuthIdentity = await model.Roleslist.GenerateUserIdentityAsync(userManager, OAuthDefaults.AuthenticationType);
//ClaimsIdentity cookiesIdentity = await model.Roleslist.GenerateUserIdentityAsync(userManager, CookieAuthenticationDefaults.AuthenticationType);
//it does not work
var authTicket = new FormsAuthenticationTicket(1, username, DateTime.Now, DateTime.Now.AddMinutes(30), false, ListRoles);
string encryptedTicket = FormsAuthentication.Encrypt(authTicket);
var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
HttpContext.Current.Request.Cookies.Add(authCookie);
// HResult = 0x80004002 Message = You can not convert an object of type 'System.Security.Claims.ClaimsIdentity' to the type 'System.Web.Security.FormsIdentity'.
FormsIdentity id = (FormsIdentity)HttpContext.Current.User.Identity;
FormsAuthenticationTicket ticket = id.Ticket;
string userData = ticket.UserData;
string[] roles = userData.Split(',');
HttpContext.Current.User = new GenericPrincipal(HttpContext.Current.User.Identity, roles);
}
else
{
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized, "El nombre de usuario o la contraseña no son correctos.");
}
}
}
I tried it in the following way, but it does not work
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();
LoginModel model = new LoginModel();
//validate user credentials //valida las credenciales de usuario
//model.usuario = _serviceUsuario.Login(context.UserName, context.Password);//bool
//validate user credentials and obtain user roles //validar las credenciales de usuario y obtener roles de usuario
model.Roleslist = _serviceUsuario.ObtenerRoles(context.UserName, context.Password);//List
//ApplicationUser user = await userManager.FindAsync(context.UserName, context.Password);
if (model.Roleslist == null)
{
context.SetError("invalid_grant", "El nombre de usuario o la contraseña no son correctos.");
return;
}
I managed to implement the authentication with Token without Entity Framework that is with the validation based on a stored procedure and roles. The code is the following:
public class CredentialsAuthorizationServerProvider : OAuthAuthorizationServerProvider
{
// ...
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
LoginModel model = new LoginModel();
//validate user credentials and obtain user roles (return List Roles)
//validar las credenciales de usuario y obtener roles de usuario
var user = model.User = _serviceUsuario.ObtenerUsuario(context.UserName, context.Password);
if (user == null)
{
context.SetError("invalid_grant", "El nombre de usuario o la contraseña no son correctos.cod 01");
return;
}
var stringRoles = user.Roles.Replace(" ", "");
string[] roles = stringRoles.Split(',');
var identity = new ClaimsIdentity(context.Options.AuthenticationType);
foreach (var Rol in roles)
{
identity.AddClaim(new Claim(ClaimTypes.Role, Rol));
}
identity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
AuthenticationProperties properties = CreateProperties(context.UserName);
var ticket = new AuthenticationTicket(identity, properties);
context.Validated(ticket);
}
}
Configure la aplicación para el flujo basado en OAuth
PublicClientId = "self";
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
//Provider = new ApplicationOAuthProvider(PublicClientId),
Provider = new CredentialsAuthorizationServerProvider(PublicClientId),
AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromHours(1),
// En el modo de producción establezca AllowInsecureHttp = false
AllowInsecureHttp = true
};
// Permitir que la aplicación use tokens portadores para autenticar usuarios
//app.UseOAuthBearerTokens(OAuthOptions);
app.UseOAuthAuthorizationServer(OAuthOptions);
Startup
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
var config = new HttpConfiguration();
WebApiConfig.Register(config);
ConfigureAuth(app);
var authOptions = new OAuthBearerAuthenticationOptions()
{
AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Active
};
app.UseOAuthBearerAuthentication(authOptions);
app.UseWebApi(config);
}
}
User contributions licensed under CC BY-SA 3.0