Oauth 验证用户授权登录 几点总结

  大部分信息来源于网络      在此注明  谢谢  http://www.mamicode.com/info-detail-1156227.html 此片文章 为了防止文档丢失  拷贝文档内容 


基于令牌的认证

    我们知道WEB网站的身份验证一般通过session或者cookie完成的,登录成功后客户端发送的任何请求都带上cookie,服务端根据客户端发送来的cookie来识别用户。

    WEB API使用这样的方法不是很适合,于是就有了基于令牌的认证,使用令牌认证有几个好处:可扩展性、松散耦合、移动终端调用比较简单等等,别人都用上了,你还有理由不用吗?

    下面我们花个20分钟的时间来实现一个简单的WEB API token认证:

 

Step 1: 新建一个空的WEB API项目,项目名称就设置为WebApi

Oauth 验证用户授权登录 几点总结_第1张图片

Oauth 验证用户授权登录 几点总结_第2张图片

 

Step 2: 在Models目录下新建一个 Product 类 :

技术分享
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace WebApi.Models
{
    public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Category { get; set; }
        public decimal Price { get; set; }
    }
}
技术分享

Step 3:在Controllers目录下新建一个 ProductsController 类

技术分享
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Web.Http;

using WebApi.Models;

namespace WebApi.Controllers
{
    [RoutePrefix("api/Products")]
    public class ProductsController : ApiController
    {
        Product[] products = new Product[]  
        {  
            new Product { Id = 1, Name = "Tomato Soup", Category = "Groceries", Price = 1 },  
            new Product { Id = 2, Name = "Yo-yo", Category = "Toys", Price = 3.75M },  
            new Product { Id = 3, Name = "Hammer", Category = "Hardware", Price = 16.99M }  
        };

        public IEnumerable GetAllProducts()
        {
            return products;
        }

        public Product GetProductById(int id)
        {
            var product = products.FirstOrDefault((p) => p.Id == id);
            if (product == null)
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }
            return product;
        }

        public IEnumerable GetProductsByCategory(string category)
        {
            return products.Where(p => string.Equals(p.Category, category,
                    StringComparison.OrdinalIgnoreCase));
        }
    }
}
技术分享

F5运行后就可以使用这个简单的WebApi了,测试api可以使用Postman工具:

Oauth 验证用户授权登录 几点总结_第3张图片

Oauth 验证用户授权登录 几点总结_第4张图片

    获取所有数据  http://localhost:1234/api/products

    获取内码为1的数据  http://localhost:1234/api/products/1

    查询category=的数据  http://localhost:1234/api/products?category=Groceries

 

    可以看到这个产品的API是公开访问的,没有任何验证,这样不是很安全,下一步我将加上token验证。

 

Step 4:安装所需的NuGet包:

打开NuGet包管理器控制台,然后输入如下指令:

Install-Package Microsoft.AspNet.WebApi.Owin -Version 5.1.2
Install-Package Microsoft.Owin.Host.SystemWeb -Version 2.1.0
Install-Package Microsoft.AspNet.Identity.Owin -Version 2.0.1
Install-Package Microsoft.Owin.Cors -Version 2.1.0
Install-Package EntityFramework -Version 6.0.0

Step 5:在项目根目录下添加Owin“Startup”类

技术分享
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;

using Owin;
using Microsoft.Owin;
using Microsoft.Owin.Security.OAuth;

[assembly: OwinStartup(typeof(WebApi.Startup))]
namespace WebApi
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            HttpConfiguration config = new HttpConfiguration();
            ConfigureOAuth(app);

            WebApiConfig.Register(config);
            app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
            app.UseWebApi(config);
        }

        public void ConfigureOAuth(IAppBuilder app)
        {
            OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
            {
                AllowInsecureHttp = true,
                TokenEndpointPath = new PathString("/token"),
                AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
                Provider = new SimpleAuthorizationServerProvider()
            };
            app.UseOAuthAuthorizationServer(OAuthServerOptions);
            app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
        }
    }
}
技术分享

 

Step 6:删除Global.asax 

我们已经设置了Setup类,就不需要Global了,删掉干净;

 

Step 7:在项目根目录下添加验证类 SimpleAuthorizationServerProvider,为了简单用户的验证部分我们省略掉;

技术分享
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

using System.Threading;
using System.Threading.Tasks;
using Microsoft.Owin;
using Microsoft.Owin.Security.OAuth;
using System.Security.Claims;

namespace WebApi
{
    public class SimpleAuthorizationServerProvider : OAuthAuthorizationServerProvider
    {
        public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
        {
            context.Validated();
        }

        public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
        {

            context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });

            /*
             * 对用户名、密码进行数据校验,这里我们省略
            using (AuthRepository _repo = new AuthRepository())
            {
                IdentityUser user = await _repo.FindUser(context.UserName, context.Password);

                if (user == null)
                {
                    context.SetError("invalid_grant", "The user name or password is incorrect.");
                    return;
                }
            }*/

            var identity = new ClaimsIdentity(context.Options.AuthenticationType);
            identity.AddClaim(new Claim("sub", context.UserName));
            identity.AddClaim(new Claim("role", "user"));

            context.Validated(identity);

        }
    }
}
技术分享

 

Step 7:让CORS起作用

在ASP.NET Web API中启用OAuth的Access Token验证非常简单,只需在相应的Controller或Action加上[Authorize]标记

修改ProductsController类

技术分享
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Web.Http;

using WebApi.Models;

namespace WebApi.Controllers
{

    public class ProductsController : ApiController
    {
        Product[] products = new Product[]  
        {  
            new Product { Id = 1, Name = "Tomato Soup", Category = "Groceries", Price = 1 },  
            new Product { Id = 2, Name = "Yo-yo", Category = "Toys", Price = 3.75M },  
            new Product { Id = 3, Name = "Hammer", Category = "Hardware", Price = 16.99M }  
        };

        [Authorize]
        [Route("")]
        public IEnumerable GetAllProducts()
        {
            return products;
        }

        [Authorize]
        public Product GetProductById(int id)
        {
            var product = products.FirstOrDefault((p) => p.Id == id);
            if (product == null)
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }
            return product;
        }

        [AllowAnonymous]
        public IEnumerable GetProductsByCategory(string category)
        {
            return products.Where(p => string.Equals(p.Category, category,
                    StringComparison.OrdinalIgnoreCase));
        }
    }
}
技术分享

 

现在我们再次直接GET http://localhost:23477/api/products/ 会返回401错误,请求被拒绝

Oauth 验证用户授权登录 几点总结_第5张图片

 

获取token, POST   http://localhost:23477/token

参数BODY x-www-form-urlencoded 格式:

grant_type=password

username=admin 

password=123456

Oauth 验证用户授权登录 几点总结_第6张图片

返回200状态,内容为:

技术分享
{
  "access_token": "eLjAu3Alm2YWjJKXmX_fLY07P6vbIzxasFECkDap3KIE0Ydp7IGhTgrzWLtPdgrK46rfAB-OmJSG5C8Bh-PkfG3XrGS0uDea2KBXyoWSR11evTGJiVIyXny3Ih2DkH04qH2T_Ar4kIjcAngPtUnsEVex26tV4QHIrjCq5SlkOdfdAa9Pnl98QVwYH47yO-zlc55bwMgpR2J4fQLyNzWVHNZpH3DbOcHQ3Yenemr6XhM",
  "token_type": "bearer",
  "expires_in": 86399
}
技术分享

只要在http请求头中加上Authorization:bearer Token就可以成功访问API就成功了:

GET   http://localhost:23477/api/products/

Authorization : bearer eLjAu3Alm2YWjJKXmX_fLY07P6vbIzxasFECkDap3KIE0Ydp7IGhTgrzWLtPdgrK46rfAB-OmJSG5C8Bh-PkfG3XrGS0uDea2KBXyoWSR11evTGJiVIyXny3Ih2DkH04qH2T_Ar4kIjcAngPtUnsEVex26tV4QHIrjCq5SlkOdfdAa9Pnl98QVwYH47yO-zlc55bwMgpR2J4fQLyNzWVHNZpH3DbOcHQ3Yenemr6XhM

Oauth 验证用户授权登录 几点总结_第7张图片

 

这样我们就完成了简单的WEB API的token验证~

不过这个程序有个问题,如果GetProductById也加上验证那么根据ID获取product的接口 http://localhost:23477/api/products/1 会报错

需要修改成 http://localhost:23477/api/products?id=1 

不知道是哪里出的问题

Oauth 验证用户授权登录 几点总结_第8张图片

Oauth 验证用户授权登录 几点总结_第9张图片


下面 这段追CSDN别人问题的描述解决的 请求调用的问题 

 在请求里  我用的 火狐的 debug 进行请求 一直出现


{
    "error": "unsupported_grant_type"
}

传说中的这个错误 没用过 始终不知道原因 

    翻各种 文章 找到了 先获取 token   怎么获取呢  那么涉及到 必须在内容中传输用户名 密码 和 类型 

   grant_type=password&username=uname&password=pwd  在内容里面加上这一段  进行post 请求 且只能进行post 请求



加上这个进行请求之后 就可以获取到access 的token  

   不知道上面那些参数的你连问题在哪你都不知道    请大家注意 知识是为了分享 为了传播给更多的技术爱好者看

   那么我们得到了 token 怎么使用呢  

  我们在请求头 加上   



Authorization : bearer eLjAu3Alm2YWjJKXmX_fLY07P6vbIzxasFECkDap3KIE0Ydp7IGhTgrzWLtPdgrK46rfAB-OmJSG5C8Bh-

Authorization  名称 

 bearer+空格+token 内容  

然后在去请求你的api接口 就可以顺利的取到数据 

 所有我们的请求只需要前期加上验证  输入用户名和密码  就是你请求token 的地方 带上你的用户名和密码 在后台进行验证

那么我们就可以确认用户是否可以获取 token 的验证   


在这里可以打开你的用户列表 查询数据库的用户列表 或者一些固定的授权的用户进行授权 

  那么我们就可以对用户进行 授权了 如果没有获取到授权的用户 是无法拿到token的 那么 无法进行请求 

      有什么不会 请留言 

                    知无不言言无不尽        知识是哪来共享的



你可能感兴趣的:(NET)