文档章节

WebApi实现验证授权Token,WebApi生成文档等

深圳大道
 深圳大道
发布于 2016/12/29 15:33
字数 1861
阅读 106
收藏 0
using System;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Security;

namespace OtherApi.Auth
{

    public class AuthFilterOutside : AuthorizeAttribute
    {
        //重写基类的验证方式,加入我们自定义的Ticket验证
        public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
        {
            //url获取token
            var content = actionContext.Request.Properties["MS_HttpContext"] as HttpContextBase;
            var token = content.Request.Headers["Token"];
            if (!string.IsNullOrEmpty(token))
            {
                //解密用户ticket,并校验用户名密码是否匹配
                if (ValidateTicket(token))
                {
                    base.IsAuthorized(actionContext);
                }
                else
                {
                    HandleUnauthorizedRequest(actionContext);
                }
            }
            //如果取不到身份验证信息,并且不允许匿名访问,则返回未验证401
            else
            {
                var attributes = actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().OfType<AllowAnonymousAttribute>();
                bool isAnonymous = attributes.Any(a => a is AllowAnonymousAttribute);
                if (isAnonymous) base.OnAuthorization(actionContext);
                else HandleUnauthorizedRequest(actionContext);
            }
        }

        //校验票据(数据库数据匹配)
        private bool ValidateTicket(string encryptToken)
        {
            bool flag = false;
            try
            {
                //获取数据库Token
                Dec.Models.TicketAuth model = Dec.BLL.TicketAuth.GetTicketAuthByToken(encryptToken);
                if (model.Token == encryptToken) //存在
                {
                    //未超时
                    flag = (DateTime.Now <= model.ExpireDate) ? true : false;
                }
            }
            catch (Exception ex) { }
            return flag;
        }
    }
}

using System;
using System.Web;
using System.Web.Http;
using System.Web.Security;
using System.Net.Http;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Text;
using OtherApi.Auth;  //引用验证

namespace SpiderApi.Controllers
{
    /// <summary>
    /// 用户授权接口
    /// </summary>
    public class AccountController : ApiController
    {
        #region 用户登录授权
        /// <summary>
        /// 用户登录授权
        /// </summary>
        /// <param name="username">用户名</param>
        /// <param name="password">密码</param>
        /// <returns></returns>
        [Route("api/account/login")]
        [HttpGet]
        public HttpResponseMessage Login(string username, string password)
        {
            //定义
            ResponseResult obj = new ResponseResult();
            var model = GetLoginModel(username, password);
            if (model != null)
            {
                int userId = model.UserId;
                string Token = UntilHelper.Md5Encode(UntilHelper.GetExtGuidID(), 32);
                var dtNow = DateTime.Now;

                #region 将身份信息保存票据表中,验证当前请求是否是有效请求
                //判断此用户是否存在票据信息
                if (Dec.BLL.TicketAuth.GetTicketAuthByUserId(userId) != null)
                {
                    //清空重置
                    Dec.BLL.TicketAuth.DeleteByUserId(userId);
                }
                Dec.Models.TicketAuth ticket = new Dec.Models.TicketAuth();
                ticket.UserID = userId;
                ticket.Token = Token;
                ticket.CreateDate = dtNow;
                ticket.ExpireDate = dtNow.AddMinutes(30); //30分钟过期
                Dec.BLL.TicketAuth.Add(ticket);
                #endregion

                //返回信息            
                obj.status = true;
                obj.message = "用户登录成功";
                JObject jo = new JObject();
                jo.Add("userid", userId);
                jo.Add("loginname", model.LoginName);
                jo.Add("nickname", model.NickName);
                jo.Add("usertype", model.UserType); //(int)UserTypeEnum.Seller
                jo.Add("token", Token);
                obj.info = jo;
            }
            else
            {
                obj.status = false;
                obj.message = "用户登录失败";
            }
            var resultObj = JsonConvert.SerializeObject(obj, Formatting.Indented);
            HttpResponseMessage result = new HttpResponseMessage { Content = new StringContent(resultObj, Encoding.GetEncoding("UTF-8"), "application/json") };
            return result;
        }
        #endregion

        #region 用户退出登录,清空Token
        /// <summary>
        /// 用户退出登录,清空Token
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <returns></returns>
        [Route("api/account/loginout")]
        [HttpGet]
        public HttpResponseMessage LoginOut(int userId)
        {
            //定义
            ResponseResult obj = new ResponseResult();
            try
            {
                //清空数据库该用户票据数据
                Dec.BLL.TicketAuth.DeleteByUserId(userId);
            }
            catch (Exception ex) { }
            //返回信息            
            obj.status = true;
            obj.message = "成功退出";
            var resultObj = JsonConvert.SerializeObject(obj);
            HttpResponseMessage result = new HttpResponseMessage { Content = new StringContent(resultObj, Encoding.GetEncoding("UTF-8"), "application/json") };
            return result;
        }
        #endregion

        #region 查询Token是否有效
        /// <summary>
        /// 查询Token是否有效
        /// </summary>
        /// <param name="token">token</param>
        /// <returns></returns>
        [Route("api/account/validatetoken")]
        [HttpGet]
        public HttpResponseMessage ValidateToken(string token)
        {
            //定义
            ResponseResult obj = new ResponseResult();
            bool flag = ValidateTicket(token);
            if (flag)
            {
                //返回信息            
                obj.status = true;
                obj.message = "token有效";
            }
            else
            {
                obj.status = false;
                obj.message = "token无效";
            }
            var resultObj = JsonConvert.SerializeObject(obj);
            HttpResponseMessage result = new HttpResponseMessage { Content = new StringContent(resultObj, Encoding.GetEncoding("UTF-8"), "application/json") };
            return result;
        }
        #endregion

        #region 获取用户账户余额
        /// <summary>
        /// 获取用户账户余额
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <returns></returns>
        [Route("api/account/amount")]
        [HttpGet]
        [AuthFilterOutside] //添加验证
        public HttpResponseMessage GetAmount(int userId)
        {
            //定义
            ResponseResult obj = new ResponseResult();
            //获取数据库数据
            Dec.Models.UserInfo model = Dec.BLL.UserInfo.GetUserInfoByUserId(userId);
            if (model != null)
            {
                //返回信息            
                obj.status = true;
                obj.message = "获取用户账户余额成功";
                JObject jo = new JObject();
                jo.Add("userid", model.UserId);
                jo.Add("amount", model.Amount);
                obj.info = jo;
            }
            else
            {
                obj.status = false;
                obj.message = "获取用户账户余额失败";
            }

            var resultObj = JsonConvert.SerializeObject(obj);
            HttpResponseMessage result = new HttpResponseMessage { Content = new StringContent(resultObj, Encoding.GetEncoding("UTF-8"), "application/json") };
            return result;
        }
        #endregion

        /// <summary>
        /// 用户充值接口
        /// </summary>
        /// <param name="userid">用户ID</param>
        /// <param name="amount">充值金额</param>
        /// <returns></returns>
        [Route("api/account/recharge")]
        [HttpGet]
        [AuthFilterInside]
        public HttpResponseMessage Recharge(string userid, double amount)
        {
            //定义
            ResponseResult obj = new ResponseResult();
            //获取数据库数据

            //返回信息            
            obj.status = true;
            obj.message = "操作成功,请等待第三方支付平台返回通知核实是否到账";
            JObject jo = new JObject();
            jo.Add("userid", "123456789");
            jo.Add("amount", 125.80);
            obj.info = jo;

            var resultObj = JsonConvert.SerializeObject(obj);
            HttpResponseMessage result = new HttpResponseMessage { Content = new StringContent(resultObj, Encoding.GetEncoding("UTF-8"), "application/json") };
            return result;
        }

         #region 验证票据是否有效
        /// <summary>
        /// 验证票据是否有效
        /// </summary>
        /// <param name="encryptToken">token</param>
        /// <returns></returns>
        private bool ValidateTicket(string encryptToken)
        {
            bool flag = false;
            try
            {
                //获取数据库Token
                Dec.Models.TicketAuth model = Dec.BLL.TicketAuth.GetTicketAuthByToken(encryptToken);
                if (model.Token == encryptToken) //存在
                {
                    //未超时
                    flag = (DateTime.Now <= model.ExpireDate) ? true : false;
                }
            }
            catch (Exception ex) { }
            return flag;
        }
        #endregion

        #region 用户登录
        /// <summary>
        /// 用户登录
        /// </summary>
        /// <param name="userName">用户名</param>
        /// <param name="userPwd">密码</param>
        /// <returns></returns>
        private Dec.Models.UserInfo GetLoginModel(string userName, string userPwd)
        {
            Dec.Models.UserInfo model = new Dec.Models.UserInfo();
            try
            {
                if (!string.IsNullOrWhiteSpace(userName) && !string.IsNullOrWhiteSpace(userPwd))
                {
                    //数据库比对
                    model = Dec.BLL.UserInfo.GetUserInfoByUserNamePwd(userName, UntilHelper.Md5Encode(userPwd, 32));
                }
            }
            catch (Exception ex) { }
            return model;
        }
        #endregion
    }
}
//////////////////////////////////////////////////////////////////
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Routing;

namespace SpiderApi
{
    public class WebApiApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            //WebApi文档
            AreaRegistration.RegisterAllAreas();
            GlobalConfiguration.Configure(WebApiConfig.Register);
        }

        protected void Application_PostAuthorizeRequest()
        {
            //Enable Session
            HttpContext.Current.SetSessionStateBehavior(System.Web.SessionState.SessionStateBehavior.Required);
        }
    }
}
// Uncomment the following to provide samples for PageResult<T>. Must also add the Microsoft.AspNet.WebApi.OData
// package to your project. 先安装Help Page包  HelpPage=>App_start=>HelpPageConfig.cs
////#define Handle_PageResultOfT

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Net.Http.Headers;
using System.Reflection;
using System.Web;
using System.Web.Http;
using SpiderApi.Models;
#if Handle_PageResultOfT
using System.Web.Http.OData;
#endif

namespace SpiderApi.Areas.HelpPage
{
    /// <summary>
    /// Use this class to customize the Help Page.
    /// For example you can set a custom <see cref="System.Web.Http.Description.IDocumentationProvider"/> to supply the documentation
    /// or you can provide the samples for the requests/responses.
    /// </summary>
    public static class HelpPageConfig
    {
        [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters",
            MessageId = "SpiderApi.Areas.HelpPage.TextSample.#ctor(System.String)",
            Justification = "End users may choose to merge this string with existing localized resources.")]
        [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly",
            MessageId = "bsonspec",
            Justification = "Part of a URI.")]
        public static void Register(HttpConfiguration config)
        {
            //// Uncomment the following to use the documentation from XML documentation file.
            //开启解析
            config.SetDocumentationProvider(new XmlDocumentationProvider(HttpContext.Current.Server.MapPath("~/Bin/SpiderApi.XML")));

            //// Uncomment the following to use "sample string" as the sample for all actions that have string as the body parameter or return type.
            //// Also, the string arrays will be used for IEnumerable<string>. The sample objects will be serialized into different media type 
            //// formats by the available formatters.
            //config.SetSampleObjects(new Dictionary<Type, object>
            //{
            //    {typeof(string), "sample string"},
            //    {typeof(IEnumerable<string>), new string[]{"sample 1", "sample 2"}}
            //});
            //添加映射
            config.SetSampleResponse(Sample.BatchSendMessageResponse(), new MediaTypeHeaderValue("text/json"), "MessageQueue", "BatchSendMessage");
            config.SetSampleResponse(Sample.BatchReceiveMessageResponse(), new MediaTypeHeaderValue("text/json"), "MessageQueue", "BatchReceiveMessage");
            config.SetSampleResponse(Sample.DeleteMessageResponse(), new MediaTypeHeaderValue("text/json"), "MessageQueue", "DeleteMessage");
            config.SetSampleResponse(Sample.BatchDeleteMessageResponse(), new MediaTypeHeaderValue("text/json"), "MessageQueue", "BatchDeleteMessage");
            config.SetSampleResponse(Sample.ChangeMessageVisibilityResponse(), new MediaTypeHeaderValue("text/json"), "MessageQueue", "ChangeMessageVisibility");

            // Extend the following to provide factories for types not handled automatically (those lacking parameterless
            // constructors) or for which you prefer to use non-default property values. Line below provides a fallback
            // since automatic handling will fail and GeneratePageResult handles only a single type.
#if Handle_PageResultOfT
            config.GetHelpPageSampleGenerator().SampleObjectFactories.Add(GeneratePageResult);
#endif

            // Extend the following to use a preset object directly as the sample for all actions that support a media
            // type, regardless of the body parameter or return type. The lines below avoid display of binary content.
            // The BsonMediaTypeFormatter (if available) is not used to serialize the TextSample object.
            config.SetSampleForMediaType(
                new TextSample("Binary JSON content. See http://bsonspec.org for details."),
                new MediaTypeHeaderValue("application/bson"));

            //// Uncomment the following to use "[0]=foo&[1]=bar" directly as the sample for all actions that support form URL encoded format
            //// and have IEnumerable<string> as the body parameter or return type.
            //config.SetSampleForType("[0]=foo&[1]=bar", new MediaTypeHeaderValue("application/x-www-form-urlencoded"), typeof(IEnumerable<string>));

            //// Uncomment the following to use "1234" directly as the request sample for media type "text/plain" on the controller named "Values"
            //// and action named "Put".
            //config.SetSampleRequest("1234", new MediaTypeHeaderValue("text/plain"), "Values", "Put");

            //// Uncomment the following to use the image on "../images/aspNetHome.png" directly as the response sample for media type "image/png"
            //// on the controller named "Values" and action named "Get" with parameter "id".
            //config.SetSampleResponse(new ImageSample("../images/aspNetHome.png"), new MediaTypeHeaderValue("image/png"), "Values", "Get", "id");

            //// Uncomment the following to correct the sample request when the action expects an HttpRequestMessage with ObjectContent<string>.
            //// The sample will be generated as if the controller named "Values" and action named "Get" were having string as the body parameter.
            //config.SetActualRequestType(typeof(string), "Values", "Get");

            //// Uncomment the following to correct the sample response when the action returns an HttpResponseMessage with ObjectContent<string>.
            //// The sample will be generated as if the controller named "Values" and action named "Post" were returning a string.
            //config.SetActualResponseType(typeof(string), "Values", "Post");
        }

#if Handle_PageResultOfT
        private static object GeneratePageResult(HelpPageSampleGenerator sampleGenerator, Type type)
        {
            if (type.IsGenericType)
            {
                Type openGenericType = type.GetGenericTypeDefinition();
                if (openGenericType == typeof(PageResult<>))
                {
                    // Get the T in PageResult<T>
                    Type[] typeParameters = type.GetGenericArguments();
                    Debug.Assert(typeParameters.Length == 1);

                    // Create an enumeration to pass as the first parameter to the PageResult<T> constuctor
                    Type itemsType = typeof(List<>).MakeGenericType(typeParameters);
                    object items = sampleGenerator.GetSampleObject(itemsType);

                    // Fill in the other information needed to invoke the PageResult<T> constuctor
                    Type[] parameterTypes = new Type[] { itemsType, typeof(Uri), typeof(long?), };
                    object[] parameters = new object[] { items, null, (long)ObjectGenerator.DefaultCollectionSize, };

                    // Call PageResult(IEnumerable<T> items, Uri nextPageLink, long? count) constructor
                    ConstructorInfo constructor = type.GetConstructor(parameterTypes);
                    return constructor.Invoke(parameters);
                }
            }

            return null;
        }
#endif
    }
}
/*
API接口测试工具 - WebApiTestClient使用--Nuget引入组件 
--A Simple Test Client for ASP.NET Web API
*/
/*
1、修改Api.cshtml文件
通过上述步骤,就能将组件WebAPITestClient引入进来。下面我们只需要做一件事:打开文件 (根据 Areas\HelpPage\Views\Help) Api.cshtml 并添加以下内容:

@Html.DisplayForModel("TestClientDialogs")
@Html.DisplayForModel("TestClientReferences")
添加后Api.cshtml文件的代码如下
*/


@using System.Web.Http
@using WebApiTestClient.Areas.HelpPage.Models
@model HelpPageApiModel

@{
    var description = Model.ApiDescription;
    ViewBag.Title = description.HttpMethod.Method + " " + description.RelativePath;
}

<link type="text/css" href="~/Areas/HelpPage/HelpPage.css" rel="stylesheet" />
<div id="body" class="help-page">
    <section class="featured">
        <div class="content-wrapper">
            <p>
                @Html.ActionLink("Help Page Home", "Index")
            </p>
        </div>
    </section>
    <section class="content-wrapper main-content clear-fix">
        @Html.DisplayForModel()
    </section>
</div>

@Html.DisplayForModel("TestClientDialogs")
@section Scripts{
    <link href="~/Areas/HelpPage/HelpPage.css" rel="stylesheet" />
    @Html.DisplayForModel("TestClientReferences")
}

本文转载自:http://blog.csdn.net/smartsmile2012/article/details/52936011

深圳大道
粉丝 3
博文 877
码字总数 0
作品 0
深圳
架构师
私信 提问
加载中

评论(1)

keep_running2
keep_running2
汗。。直接贴代码,至少也应该添点文字说明啊
ASP.NET WebApi 基于分布式Session方式实现Token签名认证(发布版)

一、课程介绍 明人不说暗话,跟着阿笨一起学玩WebApi!开发提供数据的WebApi服务,最重要的是数据的安全性。那么对于我们来说,如何确保数据的安全将会是需要思考的问题。在ASP.NETWebService...

跟着阿笨一起玩NET
2018/09/05
71
0
使用Swagger 搭建高可读性ASP.Net WebApi文档

一、前言 在最近一个商城项目中,使用WebApi搭建API项目。但开发过程中,前后端工程师对于沟通接口的使用,是非常耗时的。之前也有用过Swagger构建WebApi文档,但是API文档的可读性并不高。尤...

沉淀的风
2018/08/19
0
0
使用Identity Server 4建立Authorization Server (2)

第一部分: http://www.cnblogs.com/cgzl/p/7780559.html 第一部分主要是建立了一个简单的Identity Server. 接下来继续: 建立Web Api项目 如图可以在同一个解决方案下建立一个web api项目: (...

solenovex
2017/11/05
0
0
IdnentiyServer-使用客户端凭据访问API

情景如下:一个客户端要访问一个api,不需要用户登录,但是又不想直接暴露api给外部使用,这时可以使用identityserver添加访问权限。 客户端通过clientid和secrect访问identitserver的Token...

ldybyz
2018/10/09
0
0
ASP.NET WebApi 基于JWT实现Token签名认证(发布版)

一、前言 明人不说暗话,跟着阿笨一起玩WebApi!开发提供数据的WebApi服务,最重要的是数据的安全性。那么对于我们来说,如何确保数据的安全将会是需要思考的问题。在ASP.NET WebService服务中...

阿笨net
2018/09/07
0
0

没有更多内容

加载失败,请刷新页面

加载更多

数据库中间件MyCat

什么是MyCat? 查看官网的介绍是这样说的 一个彻底开源的,面向企业应用开发的大数据库集群 支持事务、ACID、可以替代MySQL的加强版数据库 一个可以视为MySQL集群的企业级数据库,用来替代昂贵...

沉浮_
今天
4
0
解决Mac下VSCode打开zsh乱码

1.乱码问题 iTerm2终端使用Zsh,并且配置Zsh主题,该主题主题需要安装字体来支持箭头效果,在iTerm2中设置这个字体,但是VSCode里这个箭头还是显示乱码。 iTerm2展示如下: VSCode展示如下: 2...

HelloDeveloper
今天
6
0
常用物流快递单号查询接口种类及对接方法

目前快递查询接口有两种方式可以对接,一是和顺丰、圆通、中通、天天、韵达、德邦这些快递公司一一对接接口,二是和快递鸟这样第三方集成接口一次性对接多家常用快递。第一种耗费时间长,但是...

程序的小猿
今天
4
0
Python机器学习之数据探索可视化库yellowbrick

背景介绍 从学sklearn时,除了算法的坎要过,还得学习matplotlib可视化,对我的实践应用而言,可视化更重要一些,然而matplotlib的易用性和美观性确实不敢恭维。陆续使用过plotly、seaborn,...

yeayee
今天
8
0
重读《学习JavaScript数据结构与算法-第三版》- 第5章 队列

定场诗 马瘦毛长蹄子肥,儿子偷爹不算贼,瞎大爷娶个瞎大奶奶,老两口过了多半辈,谁也没看见谁! 前言 本章为重读《学习JavaScript数据结构与算法-第三版》的系列文章,主要讲述队列数据结...

胡哥有话说
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部