Asp.Net MVC webAPI Token based authentication

1. 需要安装的nuget
<package id="Microsoft.AspNet.Identity.Core" version="2.2.1" targetFramework="net452" />
  <package id="Microsoft.AspNet.Identity.EntityFramework" version="2.2.1" targetFramework="net452" />
  <package id="Microsoft.AspNet.Identity.Owin" version="2.2.1" targetFramework="net452" />


2. 使用以下脚本生成aspnet相关的表(如果之前没有创建)
USE [your_db]
GO
/****** Object:  Table [dbo].[AspNetRoles]    Script Date: 7/5/2017 5:43:33 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[AspNetRoles](
	[Id] [nvarchar](128) NOT NULL,
	[Name] [nvarchar](256) NOT NULL,
	[MinPasswordLen] [int] NULL
) ON [PRIMARY]


GO
/****** Object:  Table [dbo].[AspNetUserClaims]    Script Date: 7/5/2017 5:43:33 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[AspNetUserClaims](
	[Id] [int] NOT NULL,
	[UserId] [nvarchar](128) NOT NULL,
	[ClaimType] [nvarchar](max) NULL,
	[ClaimValue] [nvarchar](max) NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]


GO
/****** Object:  Table [dbo].[AspNetUserLogins]    Script Date: 7/5/2017 5:43:33 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[AspNetUserLogins](
	[LoginProvider] [nvarchar](128) NULL,
	[ProviderKey] [nvarchar](128) NULL,
	[UserId] [nvarchar](128) NULL
) ON [PRIMARY]


GO
/****** Object:  Table [dbo].[AspNetUserRoles]    Script Date: 7/5/2017 5:43:33 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[AspNetUserRoles](
	[UserId] [nvarchar](128) NOT NULL,
	[RoleId] [nvarchar](128) NOT NULL
) ON [PRIMARY]


GO
/****** Object:  Table [dbo].[AspNetUsers]    Script Date: 7/5/2017 5:43:33 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[AspNetUsers](
	[Id] [nvarchar](128) NOT NULL,
	[Email] [nvarchar](256) NULL,
	[EmailConfirmed] [bit] NOT NULL,
	[PasswordHash] [nvarchar](max) NULL,
	[SecurityStamp] [nvarchar](max) NULL,
	[PhoneNumber] [nvarchar](max) NULL,
	[PhoneNumberConfirmed] [bit] NOT NULL,
	[TwoFactorEnabled] [bit] NOT NULL,
	[LockoutEndDateUtc] [datetime] NULL,
	[LockoutEnabled] [bit] NOT NULL,
	[AccessFailedCount] [int] NOT NULL,
	[UserName] [nvarchar](256) NOT NULL,
 CONSTRAINT [PK_dbo.AspNetUsers1] PRIMARY KEY CLUSTERED 
(
	[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]


GO




3. 添加连接字符串到webconfig
<connectionStrings>
<add name="DefaultConnection" connectionString="Server=xxxx;Database=your_db;User Id=user;Password=xxxx;" providerName="System.Data.SqlClient" />
</connectionStrings>


4. Startup.Auth.cs -> ConfigAuth 中添加:

...
// Configure the application for OAuth based flow
            PublicClientId = "self";
            OAuthOptions = new OAuthAuthorizationServerOptions
            {
                TokenEndpointPath = new PathString("/Token"),
                Provider = new ApplicationOAuthProvider(PublicClientId),
                AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
                AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(10.0),//TimeSpan.FromDays(14),
                RefreshTokenProvider = new ApplicationRefreshTokenProvider(),
                // In production mode set AllowInsecureHttp = false
                AllowInsecureHttp = true
            };


            // Enable the application to use bearer tokens to authenticate users
            app.UseOAuthBearerTokens(OAuthOptions);


...

5. 创建providers文件夹在根目录,添加以下两个类:
public class ApplicationOAuthProvider : OAuthAuthorizationServerProvider
    {
        private readonly string _publicClientId;
        private ILog _log = LogManager.GetLogger(typeof(ApplicationOAuthProvider));
        public ApplicationOAuthProvider(string publicClientId)
        {
            if (publicClientId == null)
            {
                throw new ArgumentNullException("publicClientId");
            }


            _publicClientId = publicClientId;
        }


        public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
        {
            try
            {
                ApplicationUser user = null;
                // _log.Debug("Get Token step 1");


                var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();
                //_log.Debug("Get Token step 2");
                try
                {
                    user = await userManager.FindByNameAsync(context.UserName);
                    if (user != null)
                    {
                        var result = new PasswordHasher().VerifyHashedPassword(user.PasswordHash, context.Password);
                        if (result != PasswordVerificationResult.Success)
                        {
                            context.SetError("invalid_grant", "Password already expired. Please change it.");
                            //TODO add audit history record code goes here
                            return;
                        }
                    }
                }
                catch (Exception ex)
                {


                }


                //  check username/password here
                // ...






                ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager);


                AuthenticationProperties properties = CreateProperties(user.UserName);
                AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties);
                context.Validated(ticket);
            }
            catch (Exception ex)
            {
                _log.Error(ex);
            }
        }


        public override Task TokenEndpoint(OAuthTokenEndpointContext context)
        {
            foreach (KeyValuePair<string, string> property in context.Properties.Dictionary)
            {
                context.AdditionalResponseParameters.Add(property.Key, property.Value);
            }


            return Task.FromResult<object>(null);
        }


        public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
        {
            // Resource owner password credentials does not provide a client ID.
            if (context.ClientId == null)
            {
                context.Validated();
            }


            return Task.FromResult<object>(null);
        }


        public override Task ValidateClientRedirectUri(OAuthValidateClientRedirectUriContext context)
        {
            if (context.ClientId == _publicClientId)
            {
                Uri expectedRootUri = new Uri(context.Request.Uri, "/");


                if (expectedRootUri.AbsoluteUri == context.RedirectUri)
                {
                    context.Validated();
                }
            }


            return Task.FromResult<object>(null);
        }


        public static AuthenticationProperties CreateProperties(string userName)
        {
            IDictionary<string, string> data = new Dictionary<string, string>
            {
                { "userName", userName }
            };
            return new AuthenticationProperties(data);
        }
    }




public class ApplicationRefreshTokenProvider : AuthenticationTokenProvider
    {
        public override void Create(AuthenticationTokenCreateContext context)
        {
            // Expiration time in seconds
            int expire = 10 * 60;
            context.Ticket.Properties.ExpiresUtc = new DateTimeOffset(DateTime.Now.AddSeconds(expire));
            context.SetToken(context.SerializeTicket());
        }


        public override void Receive(AuthenticationTokenReceiveContext context)
        {
            context.DeserializeTicket(context.Token);
        }
    }


至于生成的Controllers/ManageController.cs 和Controllers/AccountController.cs里面的代码是否要用,对于SPA(single page application)来说不需要,token就够了。

6. 使用postman来调用token并刷新token
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值