Session的使用
public static class Sample01
{
public static void Start()
{
Host.CreateDefaultBuilder()
.ConfigureWebHostDefaults(builder => builder
.ConfigureServices(collection => collection
.AddDistributedMemoryCache()
.AddSession())
.Configure(app => app
.UseSession()
.Run(ProcessAsync)))
.Build()
.Run();
static async Task ProcessAsync(HttpContext context)
{
var session = context.Session;
await session.LoadAsync();
string sessionStartTime;
if (session.TryGetValue("SessionStartTime", out var value))
{
sessionStartTime = Encoding.UTF8.GetString(value);
}
else
{
sessionStartTime = DateTime.Now.ToString(CultureInfo.InvariantCulture);
session.SetString("SessionStartTime", sessionStartTime);
}
context.Response.ContentType = "text/html";
await context.Response.WriteAsync($"<html><body><ul><li>Session ID:{session.Id}</li>");
await context.Response.WriteAsync($"<li>Session Start Time:{sessionStartTime}</li>");
await context.Response.WriteAsync($"<li>Current Time:{DateTime.Now}</li></ul></table></body></html>");
}
}
}
public static class Sample02
{
public static void Start()
{
Host.CreateDefaultBuilder()
.ConfigureWebHostDefaults(builder => builder
.ConfigureServices(collection => collection
.AddDistributedMemoryCache()
.AddSession())
.Configure(app => app
.UseSession()
.Run(ProcessAsync)))
.Build()
.Run();
static async Task ProcessAsync(HttpContext context)
{
var session = context.Session;
await session.LoadAsync();
string sessionStartTime;
if (session.TryGetValue("SessionStartTime", out var value))
{
sessionStartTime = Encoding.UTF8.GetString(value);
}
else
{
sessionStartTime = DateTime.Now.ToString(CultureInfo.InvariantCulture);
session.SetString("SessionStartTime", sessionStartTime);
}
var field = typeof(DistributedSession).GetTypeInfo().GetField("_sessionKey", BindingFlags.Instance | BindingFlags.NonPublic);
var sessionKey = field?.GetValue(session);
context.Response.ContentType = "text/html";
await context.Response.WriteAsync($"<html><body><ul><li>Session ID:{session.Id}</li>");
await context.Response.WriteAsync($"<li>Session Key:{sessionKey}</li>");
await context.Response.WriteAsync($"<li>Session Start Time:{sessionStartTime}</li>");
await context.Response.WriteAsync($"<li>Current Time:{DateTime.Now}</li></ul></table></body></html>");
}
}
}
Cookie的使用
class Program
{
private static readonly Dictionary<string, string> Accounts = new Dictionary<string, string>
{
{"Admin", "123"}, {"UserA", "123"}, {"UserB", "123"}
};
public static void Main(string[] args)
{
Host.CreateDefaultBuilder()
.ConfigureWebHostDefaults(builder => builder
.ConfigureServices(collection => collection
.AddRouting()
.AddAuthentication(options =>
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie())
.Configure(app => app
.UseAuthentication()
.UseRouting()
.UseEndpoints(endpoints =>
{
endpoints.Map("/", RenderHomePageAsync);
endpoints.Map("Account/Login", SignInAsync);
endpoints.Map("Account/Logout", SignOutAsync);
})))
.Build()
.Run();
}
public static async Task RenderHomePageAsync(HttpContext context)
{
if (context?.User?.Identity?.IsAuthenticated == true)
{
await context.Response.WriteAsync(
@"<html>
<head><title>Index</title></head>
<body>" +
$"<h3>Welcome {context.User.Identity.Name}</h3>" +
@"<a href='/Account/Logout'>Sign Out</a>
</body>
</html>");
}
else
{
await context.ChallengeAsync();
}
}
public static async Task SignInAsync(HttpContext context)
{
if (string.CompareOrdinal(context.Request.Method, "GET") == 0)
{
await RenderLoginPageAsync(context, null, null, null);
}
else
{
var userName = context.Request.Form["username"];
var password = context.Request.Form["password"];
if (Accounts.TryGetValue(userName, out var pwd) && pwd == password)
{
var identity = new GenericIdentity(userName, "Passord");
var principal = new ClaimsPrincipal(identity);
await context.SignInAsync(principal);
}
else
{
await RenderLoginPageAsync(context, userName, password, "Invalid user name or password!");
}
}
}
private static Task RenderLoginPageAsync(HttpContext context, string userName, string password,
string errorMessage)
{
context.Response.ContentType = "text/html";
return context.Response.WriteAsync(
@"<html>
<head><title>Login</title></head>
<body>
<form method='post'>" +
$"<input type='text' name='username' placeholder='User name' value = '{userName}' /> " +
$"<input type='password' name='password' placeholder='Password' value = '{password}' /> " +
@"<input type='submit' value='Sign In' />
</form>" +
$"<p style='color:red'>{errorMessage}</p>" +
@"</body>
</html>");
}
public static async Task SignOutAsync(HttpContext context)
{
await context.SignOutAsync();
context.Response.Redirect("/");
}
}
class Program
{
static void Main(string[] args)
{
Host.CreateDefaultBuilder()
.ConfigureWebHostDefaults(builder => builder
.ConfigureServices(collection => collection
.AddDbContext<UserDbContext>(options => options
.UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=AuthorizationDemo;Trusted_Connection=True;MultipleActiveResultSets=true")
)
.AddRouting()
.AddAuthorization()
.AddAuthentication(options => options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme).AddCookie())
.Configure(app => app
.UseAuthentication()
.UseRouting()
.UseEndpoints(endpoints =>
{
endpoints.Map("/", RenderHomePageAsync);
endpoints.Map("Account/Login", SignInAsync);
endpoints.Map("Account/Logout", SignOutAsync);
endpoints.Map("Account/AccessDenied", DenyAccessAsync);
})))
.Build()
.Run();
}
public static async Task RenderHomePageAsync(HttpContext context)
{
if (context?.User?.Identity?.IsAuthenticated == true)
{
var requirement = new RolesAuthorizationRequirement(new [] { "ADMIN" });
var authorizationService = context.RequestServices.GetRequiredService<IAuthorizationService>();
var result = await authorizationService.AuthorizeAsync(context.User, null, new IAuthorizationRequirement[] { requirement });
if (result.Succeeded)
{
await context.Response.WriteAsync(
@"<html>
<head><title>Index</title></head>
<body>" +
$"<h3>{context.User.Identity.Name}, you are authorized.</h3>" +
@"<a href='Account/Logout'>Sign Out</a>
</body>
</html>");
}
else
{
await context.ForbidAsync();
}
}
else
{
await context.ChallengeAsync();
}
}
public static async Task SignInAsync(HttpContext context)
{
if (string.Compare(context.Request.Method, "GET") == 0)
{
await RenderLoginPageAsync(context, null, null, null);
}
else
{
string userName = context.Request.Form["username"];
string password = context.Request.Form["password"];
var dbContext = context.RequestServices.GetRequiredService<UserDbContext>();
var user = await dbContext.Users.Include(it => it.Roles).SingleOrDefaultAsync(it => it.UserName == userName.ToUpper());
if (user?.Password == password)
{
var identity = new GenericIdentity(userName, CookieAuthenticationDefaults.AuthenticationScheme);
foreach (var role in user.Roles)
{
identity.AddClaim(new Claim(ClaimTypes.Role, role.NormalizedRoleName));
}
var principal = new ClaimsPrincipal(identity);
await context.SignInAsync(principal);
}
else
{
await RenderLoginPageAsync(context, userName, password, "Invalid user name or password!");
}
}
}
private static Task RenderLoginPageAsync(HttpContext context, string userName, string password, string errorMessage)
{
context.Response.ContentType = "text/html";
return context.Response.WriteAsync(
@"<html>
<head><title>Login</title></head>
<body>
<form method='post'>" +
$"<input type='text' name='username' placeholder='User name' value = '{userName}' /> " +
$"<input type='password' name='password' placeholder='Password' value = '{password}' /> " +
@"<input type='submit' value='Sign In' />
</form>" +
$"<p style='color:red'>{errorMessage}</p>" +
@"</body>
</html>");
}
public static async Task SignOutAsync(HttpContext context)
{
await context.SignOutAsync();
await context.ChallengeAsync(new AuthenticationProperties { RedirectUri = "/" });
}
public static Task DenyAccessAsync(HttpContext context)
{
return context.Response.WriteAsync(
@"<html>
<head><title>Index</title></head>
<body>" +
$"<h3>{context.User.Identity.Name}, your access is denied.</h3>" +
@"<a href='/Account/Logout'>Sign Out</a>
</body>
</html>");
}
}
CookieAuthentication
class Program
{
static void Main(string[] args)
{
Host.CreateDefaultBuilder()
.ConfigureWebHostDefaults(builder => builder
.ConfigureServices(collection => collection
.AddDbContext<UserDbContext>(options => options
.UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=AuthorizationDemo;Trusted_Connection=True;MultipleActiveResultSets=true")
)
.AddRouting()
.AddAuthorization(options => {
var requirement = new RolesAuthorizationRequirement(new [] { "ADMIN" });
var policy = new AuthorizationPolicy(new IAuthorizationRequirement[] { requirement }, new string[0]);
options.AddPolicy("HomePage", policy);
})
.AddAuthentication(options => options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme).AddCookie())
.Configure(app => app
.UseAuthentication()
.UseRouting()
.UseEndpoints(endpoints =>
{
endpoints.Map("/", RenderHomePageAsync);
endpoints.Map("Account/Login", SignInAsync);
endpoints.Map("Account/Logout", SignOutAsync);
endpoints.Map("Account/AccessDenied", DenyAccessAsync);
})))
.Build()
.Run();
}
public static async Task RenderHomePageAsync(HttpContext context)
{
if (context?.User?.Identity?.IsAuthenticated == true)
{
var authorizationService = context.RequestServices.GetRequiredService<IAuthorizationService>();
var result = await authorizationService.AuthorizeAsync(context.User, "HomePage");
if (result.Succeeded)
{
await context.Response.WriteAsync(
@"<html>
<head><title>Index</title></head>
<body>" +
$"<h3>{context.User.Identity.Name}, you are authorized.</h3>" +
@"<a href='Account/Logout'>Sign Out</a>
</body>
</html>");
}
else
{
await context.ForbidAsync();
}
}
else
{
await context.ChallengeAsync();
}
}
public static async Task SignInAsync(HttpContext context)
{
if (string.Compare(context.Request.Method, "GET") == 0)
{
await RenderLoginPageAsync(context, null, null, null);
}
else
{
string userName = context.Request.Form["username"];
string password = context.Request.Form["password"];
var dbContext = context.RequestServices.GetRequiredService<UserDbContext>();
var user = await dbContext.Users.Include(it => it.Roles).SingleOrDefaultAsync(it => it.UserName == userName.ToUpper());
if (user?.Password == password)
{
var identity = new GenericIdentity(userName, CookieAuthenticationDefaults.AuthenticationScheme);
foreach (var role in user.Roles)
{
identity.AddClaim(new Claim(ClaimTypes.Role, role.NormalizedRoleName));
}
var principal = new ClaimsPrincipal(identity);
await context.SignInAsync(principal);
}
else
{
await RenderLoginPageAsync(context, userName, password, "Invalid user name or password!");
}
}
}
private static Task RenderLoginPageAsync(HttpContext context, string userName, string password, string errorMessage)
{
context.Response.ContentType = "text/html";
return context.Response.WriteAsync(
@"<html>
<head><title>Login</title></head>
<body>
<form method='post'>" +
$"<input type='text' name='username' placeholder='User name' value = '{userName}' /> " +
$"<input type='password' name='password' placeholder='Password' value = '{password}' /> " +
@"<input type='submit' value='Sign In' />
</form>" +
$"<p style='color:red'>{errorMessage}</p>" +
@"</body>
</html>");
}
public static async Task SignOutAsync(HttpContext context)
{
await context.SignOutAsync();
await context.ChallengeAsync(new AuthenticationProperties { RedirectUri = "/" });
}
public static Task DenyAccessAsync(HttpContext context)
{
return context.Response.WriteAsync(
@"<html>
<head><title>Index</title></head>
<body>" +
$"<h3>{context.User.Identity.Name}, your access is denied.</h3>" +
@"<a href='/Account/Logout'>Sign Out</a>
</body>
</html>");
}
}
权限认证交互示例
public class Program
{
public static void Main()
{
Host.CreateDefaultBuilder()
.ConfigureWebHostDefaults(builder => builder
.UseUrls("http://*:443")
.Configure(app => app.Run(ProcessAsync)))
.Build()
.Run();
static async Task ProcessAsync(HttpContext httpContext)
{
httpContext.Response.ContentType = "text/html";
var html =
@"<html>
<body>
<ul id='contacts'></ul>
<script src='http://code.jquery.com/jquery-3.3.1.min.js'></script>
<script>
$(function()
{
var url = 'http://www.one.com:8080/contacts';
$.getJSON(url, null, function(contacts) {
$.each(contacts, function(index, contact)
{
var html = '<li><ul>';
html += '<li>Name: ' + contact.Name + '</li>';
html += '<li>Phone No:' + contact.PhoneNo + '</li>';
html += '<li>Email Address: ' + contact.EmailAddress + '</li>';
html += '</ul>';
$('#contacts').append($(html));
});
});
});
</script >
</body>
</html>";
await httpContext.Response.WriteAsync(html);
}
}
}
public class Program
{
public static void Main()
{
Host.CreateDefaultBuilder()
.ConfigureWebHostDefaults(builder => builder
.UseUrls("http://*:8080")
.Configure(app => app
.UsePathBase("/contacts")
.Run(ProcessAsync)))
.Build()
.Run();
static Task ProcessAsync(HttpContext httpContext)
{
var response = httpContext.Response;
response.ContentType = "application/json";
var contacts = new Contact[]
{
new Contact("张三", "123", "zhangsan@qq.com"),
new Contact("李四","456", "lisi@qq.com"),
new Contact("王五", "789", "wangwu@qq.com")
};
return response.WriteAsync(JsonConvert.SerializeObject(contacts));
}
}
}