这种身份验证登录的方式,推荐网站有https证书,这样更安全。url地址里面保持身份状态信息适合服务器集群和做负载均衡的时候每个服务器都可以得到用户的身份信息。
登录页面,从nuge安装SimpleAES,这是个ASE加密解密组件:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace WebApplicationUrlWrite.Controllers
{
public class UserController : Controller
{
public ActionResult LoginView()
{
return View();
}
public ActionResult LoginCheck(string account, string password)
{
if (account.Equals("admin") && password.Equals("admin"))
{
//身份保持120秒存活
string waitStr = account + ";" + DateTime.UtcNow.AddSeconds(120).ToString("yyyy-MM-dd HH:mm:ss.fff");
string jm = SimpleAES.AES256.Encrypt(waitStr, "GMxs8953-");
jm = jm.Replace("+",".");
//Session["user"] = jm;
//return RedirectToAction("index", "home");
return Redirect("/home/index?uck="+ jm);
}
return Content("用户名或密码错误");
}
}
}
url重写,让所有.cshtml生成的url都带上自定义的字符串,页面url需要调用@Url.Action("","")来生产连接:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Principal;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using WebGrease.Css.Ast;
namespace WebApplicationUrlWrite
{
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
//加载重写
routes.Add(new MyRoute());
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
/// <summary>
/// URL重写
/// </summary>
public class MyRoute : RouteBase
{
public override RouteData GetRouteData(HttpContextBase httpContext)
{
return null;//为null表示走默认路由执行
//var virtualPath = httpContext.Request.AppRelativeCurrentExecutionFilePath + httpContext.Request.PathInfo;//获取相对路径
//var data = new RouteData(this, new MvcRouteHandler());//声明一个RouteData,添加相应的路由值
//data.Values.Add("controller", "Category");
//data.Values.Add("action", "ShowCategory");
//data.Values.Add("id", 1);
//return null;//返回这个路由值将调用CategoryController.ShowCategory(category.CategoeyID)方法。匹配终止
}
/// <summary>
/// 这个一般是.cshtml文件中的Url.Action方法会命中此方法
/// </summary>
public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
{
string token = requestContext.HttpContext.Request.QueryString["uck"];
string controller = values["controller"].ToString();
string action = values["action"].ToString();
//处理Html.Action传递多参数
//<a href="@Url.Action("About","home",new{articleId= "asldjfsjd", phone = "13588877234" , address = "武侯大道" ,pageIndex=1,pageSize=10})">关于2</a>
StringBuilder sb = new StringBuilder();
foreach (var item in values.Keys)
{
if (item.Equals("controller") || item.Equals("action"))
{
continue;
}
var _kvalue = values[item];
sb.Append("&" + item + "=" + _kvalue);
}
string url = controller + "/" + action + "?uck=" + token + sb.ToString();
return new VirtualPathData(this, url);
}
}
}
过滤器验证登录:
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace WebApplicationUrlWrite.Models
{
/// <summary>
/// 登录验证,权限验证,action过滤
/// </summary>
public class LoginFilter : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
//判断是否跳过授权过滤器
if (filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true)
|| filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true))
{
return;
}
//var session = filterContext.HttpContext.Session;
bool isAjax = filterContext.HttpContext.Request.IsAjaxRequest();
string token = filterContext.HttpContext.Request.QueryString["uck"];
if (string.IsNullOrWhiteSpace(token))
{
goto TO_LOGIN;
}
token = token.Replace(".", "+");
string jiemi = string.Empty;
try
{
jiemi = SimpleAES.AES256.Decrypt(token, "GMxs8953-");
}
catch (Exception)
{
filterContext.HttpContext.Response.Write("无效的token值");
filterContext.HttpContext.Response.End();
return;
}
string account = jiemi.Split(';')[0];
string expireTime = jiemi.Split(';')[1];
var expireUtc = DateTime.SpecifyKind(DateTime.Parse(expireTime), DateTimeKind.Utc);
double cha = (expireUtc - DateTime.UtcNow).TotalSeconds;
if (cha <= 0)
{
//登录失效
goto TO_LOGIN;
}
else
{
//通过验证,有效用户
return;
}
TO_LOGIN:
if (isAjax)
{
filterContext.HttpContext.Response.StatusCode = 801;
filterContext.Result = new EmptyResult();
filterContext.HttpContext.Response.ContentType = "application/json;charset=UTF-8";
filterContext.HttpContext.Response.Write("{\"Code\":500,\"Msg\":\"登录失效,请重新登录\"}");
filterContext.HttpContext.Response.End();
}
else
{
filterContext.Result = new RedirectResult("/user/LoginView");
}
}
}
}
Home/inde页面使用过滤器:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using WebApplicationUrlWrite.Models;
namespace WebApplicationUrlWrite.Controllers
{
[LoginFilter]
public class HomeController : Controller
{
public ActionResult Index()
{
//Session["user"] = "wuosng_userid";
return View();
}
public ActionResult About()
{
ViewBag.Message = "Your application description page.";
return View();
}
}
}
页面参考,注意使用@Html.ActionLink(),@Html.Action("","")这样才会生成uck到连接末尾:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>@ViewBag.Title - 我的 ASP.NET 应用程序</title>
@*@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")*@
</head>
<body>
<div>@Html.ActionLink("主页", "Index", "Home")</div>
<div>@Html.ActionLink("联系方式", "Contact", "Home")</div>
<div><a href="@Url.Action("About","home",new{articleId= "asldjfsjd", phone = "13588877234" , address = "武侯大道" ,pageIndex=1,pageSize=10})">关于2</a></div>
@RenderBody()
@*@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/bootstrap")
@RenderSection("scripts", required: false)*@
</body>
</html>
效果图,登录成功后,会给url添加uck身份识别验证字符串:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>About - 我的 ASP.NET 应用程序</title>
</head>
<body>
<div><a href="/Home/Index?uck=rg/WFbQRxnpHO5OBAzWpTCasfn4uU9MWNMt9dv5OJTZh6HdzoBOZp1sP5/t1bB5jsrOxSEzzhK8/knLDv9UHqQ==">主页</a></div>
<div><a href="/Home/Contact?uck=rg/WFbQRxnpHO5OBAzWpTCasfn4uU9MWNMt9dv5OJTZh6HdzoBOZp1sP5/t1bB5jsrOxSEzzhK8/knLDv9UHqQ==">联系方式</a></div>
<div><a href="/home/About?uck=rg/WFbQRxnpHO5OBAzWpTCasfn4uU9MWNMt9dv5OJTZh6HdzoBOZp1sP5/t1bB5jsrOxSEzzhK8/knLDv9UHqQ==&articleId=asldjfsjd&phone=13588877234&address=武侯大道&pageIndex=1&pageSize=10">关于2</a></div>
<h2>About.</h2>
<h3>Your application description page.</h3>
<p>Use this area to provide additional information.</p>
</body>
</html>