1. 需要安装的nuget
2. 使用以下脚本生成aspnet相关的表(如果之前没有创建)
3. 添加连接字符串到webconfig
4. Startup.Auth.cs -> ConfigAuth 中添加:
5. 创建providers文件夹在根目录,添加以下两个类:
至于生成的Controllers/ManageController.cs 和Controllers/AccountController.cs里面的代码是否要用,对于SPA(single page application)来说不需要,token就够了。
6. 使用postman来调用token并刷新token
<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