分享

WebApi2+OAuth2 角色权限验证

 Jcstone 2019-05-26

1、创建项目


2、在管理解决方案的Nuget程序包搜索并添加以下程序包(见packages.config)

 <?xml version="1.0" encoding="utf-8"?>

<packages>

  <package id="Microsoft.AspNet.Cors" version="5.2.7" targetFramework="net452" />

  <package id="Microsoft.AspNet.Mvc" version="5.2.7" targetFramework="net452" />

  <package id="Microsoft.AspNet.Razor" version="3.2.7" targetFramework="net452" />

  <package id="Microsoft.AspNet.WebApi" version="5.0.0" targetFramework="net452" />

  <package id="Microsoft.AspNet.WebApi.Client" version="5.2.7" targetFramework="net452" />

  <package id="Microsoft.AspNet.WebApi.Client.zh-Hans" version="5.2.7" targetFramework="net452" />

  <package id="Microsoft.AspNet.WebApi.Core" version="5.2.7" targetFramework="net452" />

  <package id="Microsoft.AspNet.WebApi.Core.zh-Hans" version="5.2.7" targetFramework="net452" />

  <package id="Microsoft.AspNet.WebApi.Cors" version="5.2.7" targetFramework="net452" />

  <package id="Microsoft.AspNet.WebApi.HelpPage" version="5.2.7" targetFramework="net452" />

  <package id="Microsoft.AspNet.WebApi.Owin" version="5.2.7" targetFramework="net452" />

  <package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.7" targetFramework="net452" />

  <package id="Microsoft.AspNet.WebApi.WebHost.zh-Hans" version="5.2.7" targetFramework="net452" />

  <package id="Microsoft.AspNet.WebPages" version="3.2.7" targetFramework="net452" />

  <package id="Microsoft.Owin" version="4.0.1" targetFramework="net452" />

  <package id="Microsoft.Owin.Cors" version="4.0.1" targetFramework="net452" />

  <package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net452" />

  <package id="Newtonsoft.Json" version="6.0.8" targetFramework="net452" />

  <package id="Owin" version="1.0" targetFramework="net452" />

</packages>

3、创建user类

  public class User    {

        public string Name { get; set; }

        public string Password { get; set; }

        public string Role { get; set; }

    }

4、创建SimpleAuthorizationServerProvider.cs和SimpleRefreshTokenProvider.cs类

using Microsoft.Owin.Security.OAuth;

using System;

using System.Collections.Generic;

using System.Linq;

using System.Security.Claims;

using System.Threading.Tasks;

using System.Web;

namespace mywebapiOauth.OAuth

{

   public class SimpleAuthorizationServerProvider : OAuthAuthorizationServerProvider

    {

        List<User> users = new List<User>() { 

            new User(){ Name="admin",Password="admin",Role="Administrator" },

            new User(){ Name="zhangsan",Password="zhangsan",Role="Admin" },

            new User(){ Name="lisi",Password="admin",Role="user" }

        };

        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[] { "*" });

            User user = users.Where(p => p.Name == context.UserName && p.Password == context.Password).FirstOrDefault ();

            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.Role ));

            identity.AddClaim(new Claim(ClaimTypes.Role, user.Role));

            context.Validated(identity);

        }

    }

public class SimpleRefreshTokenProvider : AuthenticationTokenProvider

    {

        private static ConcurrentDictionary<string, string> _refreshTokens = new ConcurrentDictionary<string, string>();

        /// <summary>

        /// 生成 refresh_token

        /// </summary>

        public override void Create(AuthenticationTokenCreateContext context)

        {

            context.Ticket.Properties.IssuedUtc = DateTime.UtcNow;

            context.Ticket.Properties.ExpiresUtc = DateTime.UtcNow.AddDays(60);

            context.SetToken(Guid.NewGuid().ToString("n"));

            _refreshTokens[context.Token] = context.SerializeTicket();

        }

        /// <summary>

        /// 由 refresh_token 解析成 access_token

        /// </summary>

        public override void Receive(AuthenticationTokenReceiveContext context)

        {

            string value;

            if (_refreshTokens.TryRemove(context.Token, out value))

            {

                context.DeserializeTicket(value);

            }

        }

    }

}

5、创建Startup.cs

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;

using mywebapiOauth.OAuth;

[assembly: OwinStartup(typeof(mywebapiOauth.Startup))]

namespace mywebapiOauth

{

    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 option = new OAuthAuthorizationServerOptions()

            {

                AllowInsecureHttp = true,

                TokenEndpointPath = new PathString("/token"), //获取 access_token 授权服务请求地址

                AccessTokenExpireTimeSpan = TimeSpan.FromDays(1), //access_token 过期时间

                Provider = new SimpleAuthorizationServerProvider(), //access_token 相关授权服务

                RefreshTokenProvider = new SimpleRefreshTokenProvider() //refresh_token 授权服务

            };

            app.UseOAuthAuthorizationServer(option);

            app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());

        }

    }

}


6、在Models文件夹创建Product.cs

 public class Product

    {

        public int Id { get; set; }

        public string Name { get; set; }

        public string Category { get; set; }

        public decimal Price { get; set; }

    }

7、新建WebAPI2 控制器 ProductsController

using mywebapiOauth.Models;

using System;

using System.Collections.Generic;

using System.Linq;

using System.Net;

using System.Net.Http;

using System.Web.Http;

namespace mywebapiOauth.Controllers

{

    [Authorize]

    [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<Product> GetAllProducts()

        {

            return products;

        }

         [Authorize(Roles="Admin")]

        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<Product> GetProductsByCategory(string category)

        {

            return products.Where(p => string.Equals(p.Category, category,

                    StringComparison.OrdinalIgnoreCase));

        }

    }

}


8、Postman调试——获取token


9、Postman调试——刷新token

为避免token过期再输入密码,使用refresh token即可


10、获取 id=1的product,权限   [Authorize(Roles="Admin")]



    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多