• OAuth在WebApi


    OAuth在WebApi中的使用,前后台分离的调用方式

    前段时间由于公司架构服务层向WebApi转换,就研究了OAuth在WebApi中的使用,这中间遇到了很多坑,在此记录一下OAuth的正确使用方式。

     

    1、  OAuth是做什么的?

     

      在网上浏览时,大家都见过这样的功能:网站A提供了第三方登录服务,比如使用新浪微博、QQ账户登录。用户使用第三方账户登陆后,第三方返回Token给网站A,当网站A调用第三方服务请求登录用户信息时需传递该Token给第三方,第三方才允许该服务请求。之后的每次请求无需再次认证,直接使用该Token即可。这就是OAuth的典型应用。

     

    2、  简单使用介绍 (具体使用OAuth的方法请参考:在ASP.NET中基于Owin OAuth使用Client Credentials Grant授权发放Token)

     

      2.1、用户登录的过程即是获取Token的过程,前端用户登录示例代码如下:

     

     登录代码

    $.ajax({
    type: "POST",
    url: api_address + "token", //api_address为WebApi服务地址,由于OAuth的使用中设置了属性TokenEndpointPath = new PathString("/token"),所以请求到“token”链接时即可自动进入认证流程。
    data: { grant_type: "password", username: username, password: password, ran: Math.random() },//传递用户名、密码、认证方式
    dataType: "json",
    success: function (result) {
    if (result.access_token && result.access_token.length > 0) {
    //result.access_token即是有效的服务调用凭证,可以把该值存入到Cookie中,以备下次使用。
    callback(1, "登录成功。");
    }
    else {
    callback(0, "未知错误!");
    }
    },
    error: function (XMLHttpRequest, textStatus, errorThrown) {
    callback(0, XMLHttpRequest.responseJSON.error);
    }
    });

    登录代码

     

      2.2、当认证方式为password时,已下方法为认证流程中的一步。(认证通过才会返回Token)

     

     认证代码

    public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
    var username= context.UserName;
    var password=context.Password;
    if(用户名与密码不合法)
    {
    context.setError(“用户名或密码错误!”);//认证不通过
    }
    else
    {
    var oAuthIdentity = new ClaimsIdentity(context.Options.AuthenticationType);
    oAuthIdentity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
    //可以加入用户信息及其他必要信息到Token中,以便在api服务中使用(使用中HttpContext.Current.User.Identity即为oAuthIdentity对象,WebApi的Controller中可直接使用User.Identity)。
    oAuthIdentity.AddClaim(new Claim("UserID", user.UserID.ToString()));
    var ticket = new AuthenticationTicket(oAuthIdentity, new AuthenticationProperties());
    context.Validated(ticket);//认证通过
    }
    return base.GrantResourceOwnerCredentials(context);
    }

    认证代码

    认证代码

     

    3、 已经获取了Token,如何使用?

     

      网上的大部分示例都是使用HttpClient调用的方式,而前后端的完全分离作为一种发展趋势,我们需要Jquery的调用方式。

     

     调用Api

    $.ajax({
    type: “method”,//get,post,put,delete
    url:api_address + “api/Test”,//如果调用webapi中的TestController
    data: {data},
    dataType: "json",
    headers: {
    "Authorization": "Bearer " + “token” //把登录获取的Token加入到http请求头中
    },
    success: function (result) {
    callback(result);
    },
    error: function (XMLHttpRequest, textStatus, errorThrown) {
    //。。。。。。
    }
    });

    调用Api

     

    4、Api的访问权限该如何做?

     

      认证中我们把用户登录成功作为认证通过的标志,但不同角色的用户具有不同的访问权限(个人认为认证中应使用最小权限验证,如示例中的登录成功),如何控制有些Controller不能被低权限用户访问。

     

     一个典型的ApiController

    [Authorize]
    public class TestController: ApiController
    {
    // GET api/<controller>
    public HttpResponseMessage Get(int appid)
    {
    return null;
    }
    }

    一个典型的ApiController

     

      [Authorize]表示访问该Controller的请求必须经过认证(请求头中具有Token信息),这里我们可以自定义一个特性去验证用户权限,并替换特性AuthorizeAttribute。(这里仅提供思路,具体做法请自己摸索,不保证以下代码的正确性)

     

     示例自定义特性(拦截器)

    public class CustomeAuthorizeAttribute:System.Web.Http.AuthorizeAttribute
    {
    protected override bool IsAuthorized(System.Web.Http.Controllers.HttpActionContext actionContext)
    {
    if(base.IsAuthorized(actionContext))
    {
    //这里对用户的权限进行验证,actionContext可以获得请求的是哪一个Controller
    var user = HttpContext.Current.User.Identity;//Token中带有的用户信息
    if (可以访问)
    {
    return true;
    }
    return false;
    }
    return false;
    }
    }

    示例自定义特性(拦截器)

     

     

     

     

     

  • 相关阅读:
    java_day20_Servlet
    前端_day08_定位
    前端_day07_浮动和清除浮动
    前端_day06_CSS选择器
    前端_day05_HTML常见标签
    数据库_day06_多表查询,子查询,事务,sql注入
    java_day19_MVC和配置文件
    chrome更新flash player失败
    jar打包命令使用
    win7开启远程桌面服务
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/5018040.html
Copyright © 2020-2023  润新知