1、anglarjs端在app.js(即anglar的入口js),注册.factory("messageService",使得每次来自html客户端的请求都能带有一个值,如AKey:


var chars = ['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'];function generateMixed(n) {     var res = "";     for(var i = 0; i < n ; i ++) {         var id = Math.ceil(Math.random()*35);         res += chars[id];     }     return res;}var ClientID=generateMixed(6);
var Akey='ccc';
expressApp.factory('authInterceptor', function($rootScope){
    return {
        request: function(config){
            config.headers = config.headers || {};
            config.headers.authorization = Akey;
            return config;
        },
        responseError: function(response){
            )
            {
                debugger
                location.href="./E403.html"
            }
        }
    };
})
expressApp.config(function ($locationProvider, $routeProvider,$httpProvider) {
    $httpProvider.interceptors.push('authInterceptor');
}

2、html客户端做一个403页面,页面带一个连接,连接跳转到登录页

<li>
     使用具有访问权限的账户重新登录系统,点击:
    <a href="./index.html#/login">此处</a>。
 </li>

3、客户端包含一个登录页login.html,对应的关键js如下:

$http({
    method: 'post', url: baseUrl+'account/login',
    data: {
        LoginName: $scope.LoginName,
        Password:$scope.Password,
        ClientID:ClientID
    }
}).then(function (response) {
        Akey=response.data.LogonUser.SessionKey;
    },
    function (response) {
    }
);

这里面最重要的一句话,就是Akey=response.data.LogonUser.SessionKey; 因为Aky是在app.js里面定义的全局变量,所以登录之前是一个错误值,在服务端限定以后,不能访问任何常规的action,但是只能访问服务端的account/login这个action。

4、下来看看服务端的login这个action

[Route("express/account/login")]
public HttpResponseMessage Login(Users user)
{
    if (string.IsNullOrEmpty(user.LoginName))
        return Request.CreateResponse(HttpStatusCode.Forbidden);
    if (string.IsNullOrEmpty(user.Password))
        return Request.CreateResponse(HttpStatusCode.Forbidden);

    var nowUser = auS.GetUserByUserId(user.LoginName);
    if (nowUser == null)
        return Request.CreateResponse(HttpStatusCode.Forbidden);

    #region 验证密码
    if (!string.Equals(nowUser.Password, user.Password))
    {
        return Request.CreateResponse(HttpStatusCode.Forbidden);
    }
    #endregion

    if (nowUser.IsDelete)
        return Request.CreateResponse(HttpStatusCode.Forbidden);

    var existsDevice = auS.GetClientUser(nowUser.LoginName);

    if (existsDevice == null)
    {
        string passkey = auS.ComputeHash(nowUser.LoginName + nowUser.ClientID + DateTime.UtcNow + Guid.NewGuid());
        existsDevice = new Users()
        {
            LoginName = nowUser.LoginName,
            SessionKey = passkey,
            ClientID = user.ClientID
        };
        auS.AddClientUser(existsDevice);
    }
    else
    {

        auS.UpdateUserDevice(existsDevice);
    }
    existsDevice.Password = "";

    return Request.CreateResponse(HttpStatusCode.OK, new SessionObject() { SessionKey = existsDevice.SessionKey, LogonUser = existsDevice });
}

这里面最关键的一个就是这两句话,当客户端发来一个clientID以后,使用一定的规则合成一个会话ID,存到内存中一个静态列表里面,以实现只要登录一次且不超时,就缓存这个人的登录信息,相当于session一样的效果。

string passkey = auS.ComputeHash(nowUser.LoginName + nowUser.ClientID + DateTime.UtcNow + Guid.NewGuid());
ClientID = user.ClientID

那么在来看看app.js里面的这个ClientID:

','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'];

function generateMixed(n) {
     var res = "";
     ; i < n ; i ++) {
         );
         res += chars[id];
     }
     return res;
}
);

5、来看看AuthenticationService.cs的一些关键代码:这里也可以用字典,甚至可以把列表迁移到redis上面去都可以。

public string ComputeHash(string input)
{
    byte[] data = Md5.ComputeHash(Encoding.Unicode.GetBytes(input));
    var sBuilder = new StringBuilder();
    foreach (byte t in data)
        sBuilder.Append(t.ToString("X"));
    return sBuilder.ToString();
}
 /// <summary>
/// 使用唯一标识获得登录用户
/// </summary>
/// <param name="Akey"></param>
/// <returns></returns>
public Users GetClientUserByAkey(string Akey)
{
    //headers.Authorization.Scheme
    var ul = ClientUser.Where(_ =>
    {
        return _.SessionKey == Akey;
    });
    )
    {
        var u = ul.FirstOrDefault();
        if (u.ExpiredTime < DateTime.Now)
        {
            return u;
        }
        else
        {
            ClientUser.Remove(u);
        }
    }
    return null;
}

public Users GetUserByUserId(string loginName)
{

  //Accessor是我写的一个ORM的访问器
  var ul = Accessor.GetList<Users>(new { LoginName = loginName });
  return ul.FirstOrDefault();
}

 

首先BaseController继承自ApiController,而且用于登录的那个Controller也就是AccountController必须继承自 ApiController

AccountController : ApiController

BaseController: ApiController

再来看看BaseController的关键代码,这样我们写业务Controller(非登录AccountController)的时候,比如ProductController,让ProductController:BaseController即可

public Express.Entity.Users currentUser = null;
public override Task<HttpResponseMessage> ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken)
{
    if (controllerContext.Request.Headers.Authorization != null
        && !string.IsNullOrWhiteSpace(controllerContext.Request.Headers.Authorization.Scheme))
    {
        currentUser = new AuthenticationService().GetClientUserByAkey(controllerContext.Request.Headers.Authorization.Scheme);
        if (currentUser == null)
        {
            var response = new HttpResponseMessage(HttpStatusCode.Forbidden);
            var tsc = new TaskCompletionSource<HttpResponseMessage>();
            tsc.SetResult(response);
            return tsc.Task;
        }
    }
    else
    {
        var response = new HttpResponseMessage(HttpStatusCode.Forbidden);
        var tsc = new TaskCompletionSource<HttpResponseMessage>();
        tsc.SetResult(response);
        return tsc.Task;
    }
    return base.ExecuteAsync(controllerContext, cancellationToken);
}

好了,下一篇讲述,如果实现粒度到action级别的权限控制。

anglarjs1.6.3+owin 实现验证之一:统一拒绝非登录访问。的更多相关文章

  1. 将最小的OWIN身份验证添加到现有的ASP.NET MVC应用程序

    https://weblog.west-wind.com/posts/2015/Apr/29/Adding-minimal-OWIN-Identity-Authentication-to-an-Exi ...

  2. Asp.Net WebApi 使用OWIN架构后,出现 “没有 OWIN 身份验证管理器与此请求相关联(No OWIN authentication manager is associated with the request)” 异常的解决办法

    在Asp.Net WebApi 项目中使用OWIN模块之后,如果没有在OWIN的Startup类中配置认证方式,调用WebApi的相关Controller和Action就会出现如下异常: 出现错误. ...

  3. MVC的验证(模型注解和非侵入式脚本的结合使用) .Net中初探Redis .net通过代码发送邮件 Log4net (Log for .net) 使用GDI技术创建ASP.NET验证码 Razor模板引擎 (RazorEngine) .Net程序员应该掌握的正则表达式

    MVC的验证(模型注解和非侵入式脚本的结合使用)   @HtmlHrlper方式创建的标签,会自动生成一些属性,其中一些属性就是关于验证 如图示例: 模型注解 通过模型注解后,MVC的验证,包括前台客 ...

  4. aspnet core 全局模型验证,统一api响应

    上手就来 新建一个模型验证过滤器,其中ApiResp是自定义的统一响应类. public class VldFilter:IActionFilter { /// <summary> /// ...

  5. 两系统用asp.net forms 身份验证方式实现跨域登录信息共享

    1.两个系统的 web.config 都配置为 forms 验证方式( system.web —> authentication 节点) 2.在两个系统的Web.config里配置相同的 sys ...

  6. ASP.NET MVC 4.0中选择Windows 验证默认出错拒绝访问的原因和解决方案

    在VS 2012或者2013 中,根据模板创建一个ASP.NET MVC 4.0的应用程序,选择下面的模板 然后选择Intranet Application 不对源代码做任何修改,直接按下F5调试,会 ...

  7. 【IP限制】验证是否限制了境外IP访问权限

    为啥要限制境外IP访问咱们的网站或者服务呢?怕泄漏了"机密"(好像都是我们在山寨别人,哪儿TM有机密,那叫"鸡贼") 好像国外的网站也没有限制咱大陆客去访问,反 ...

  8. Struts(二十四):短路验证&重写实现转换验证失败时短路&非字段验证

    短路验证: 若对一个字段使用多个验证器,默认情况下会执行所有的验证.若希望前面的验证器没有通过,后面的验证器就不再执行,可以使用短路验证. 1.如下拦截器,如果输入字符串,提交表单后,默认是会出现三个 ...

  9. 实现Redhat Linux 6和Windows通过Windows Server AD统一认证并共享访问Oracle ZS存储系统

    Windows Server 2012 AD设置 1.  建立新的组织单位OU 为用户提前建立好OU,是为了AD用户管理简单清晰. 2.  建立新的用户和用户组 建立新的用户的时候,要同时将用户归属到 ...

随机推荐

  1. SSM 开发 Tars

    目录结构 tars生成的文件当成 controller 来调用 service ,service 调用 mapper POM 注意如果 mybatis是3.4.1 spring 是4.1.14的话, ...

  2. (后端)Java跨域过滤器

    private FilterConfig config = null; @Override public void init(FilterConfig config) throws ServletEx ...

  3. [Kali_Debian] 清除无用的库文件(清理系统,洁癖专用)-布布扣-bubuko.com - Google Chrome

    [Kali_Debian] 清除无用的库文件(清理系统,洁癖专用) 时间:2014-11-07 16:25:36      阅读:1486      评论:0      收藏:0      [点我收藏 ...

  4. [20180604]在内存修改数据(bbed).txt

    [20180604]在内存修改数据(bbed).txt --//以前曾经做过在内存修改数据,通过oradebug poke命令修改内存信息,相关链接:--//http://blog.itpub.net ...

  5. QSetting的值不能保存。

    最近在使用QSetting的时候,setting的值死活保存不下来,后来添加了如何设置后,settting的可以获取到. QCoreApplication::setOrganizationName(& ...

  6. "error lnk1158 无法运行rc.exe”解决方案

    最近使用VS2012编译时,出现" error lnk1158 无法运行rc.exe”的问题,无法编译生成.exe文件,连最基本的HelloWorld控制台程序都无法运行,重置了VS的默认设 ...

  7. 实时监听input输入的变化(兼容主流浏览器)【转】

    遇到如此需求,首先想到的是change事件,但用过change的都知道只有在input失去焦点时才会触发,并不能满足实时监测的需求,比如监测用户输入字符数. 在经过查阅一番资料后,欣慰的发现firef ...

  8. 寒假集训——搜索 D - Cubes for Masha

    #include <stdio.h> #include <stdlib.h> #include <iostream> #include <string.h&g ...

  9. mysql列的处理

    MySQL 添加列,修改列,删除列 示例:ALTER TABLE tb_financial MODIFY CREATE_TIME DATETIME(3) DEFAULT NULL COMMENT '录 ...

  10. Destroying Array CF 722C

    题目大意就是给长度为 n 一个数列,有 n 每次删除,每一次删除第 i 个位置上的数,求每一次删除后剩余不连续数列的最大区间和. 输入样例 4 1 3 2 5 3 4 1 2 输出样例 5 4 3 0 ...