『壹』 asp.net webapi 個人身份驗證 token
重寫AuthorizeAttribute,對你想要禁用的token拋出UnAuthorized
『貳』 .net webAPI+NHibernate,調用get方法查詢資料庫的時候總是報錯,"無效操作。連接被關閉。"
//Service.CreateSession();
很明顯一些關鍵方法被屏蔽掉了,這里是創建session的,而且另外一個觸發方法有事務提交的地方也被屏蔽了,建議你能打個斷點調試下一切就明了了
『叄』 WEBapi如何 去除 ASP.NET_SessionId 這個返回的Cookies啊
「被其他人截獲到這個cookies豈不是可以做很多事了?」我認為未必,因為cookies是返回客戶端的信息記錄,其他人返回的是其他人的信息記錄,不可能返回你的信息記錄的。而且Session函數是僅僅返回你的客戶端信息的,其他人不可能得到你的信息。
『肆』 登錄系統時出現one or more errors occurred,怎麼解決
one or more errors occurred(發生一個或多個錯誤)
1、建議開機檢測硬體結束後,引導硬碟時,按住F8不放,在出現高級菜單時松開F8鍵,選擇最近一次正確配置(高級)。
2、如果還是不行,插入 windows 安裝盤(光碟、U盤均可)並重新啟動計算機。
3、選擇語言設置,然後單擊「下一步」。
4、單擊「修復計算機」。
5、如果修復安裝後還是不行,請用原版系統安裝盤全新安裝。
『伍』 visual studio 2008可以開發web api嗎
usingSystem;usingSystem.Data;usingSystem.Configuration;usingSystem.Collections;usingSystem.Web;usingSystem.Web.Security;usingSystem.Web.UI;usingSystem.Web.UI.WebControls;usingSystem.Web.UI.WebControls.WebParts;usingSystem.Web.UI.HtmlControls;usingSystem.Data.SqlClient;publicpartialclassLogin:System.Web.UI.Page{protectedvoidPage_Load(objectsender,EventArgse){}protectedboolcheckText()//檢驗用戶名輸入字元,防止SQL注入{char[]a=txtNum.Text.ToCharArray();for(inti=0;ialert('驗證碼錯誤');location='Login.aspx'");//如果驗證碼錯誤,則將頁面定位到登錄界面}else{if(this.checkText()){if(this.ddlstatus.SelectedValue=="學生")//如果是學生登錄,則調用BaseClass中的CheckStudent方法進行檢驗{//將用戶輸入的密碼加密後與資料庫中的值進行比較stringuser=txtNum.Text.Trim();stringpwd=BaseClass.md5(txtPwd.Text.Trim());if(BaseClass.CheckStudent(user,pwd))//如果通過驗證,從資料庫中查詢出相關記錄值保存,並將頁面跳轉到學生主界面{SqlConnectionconn=BaseClass.DBCon();conn.Open();SqlCommandcmd=newSqlCommand("select*fromStudentwhereStudentNum='"+txtNum.Text.Trim()+"'",conn);SqlDataReaderread=cmd.ExecuteReader();read.Read();//讀取相關值顯示考生姓名和性別stringstuName=read["StudentName"].ToString();conn.Close();//存儲考生姓名和性別Session["name"]=stuName;Session["ID"]=txtNum.Text.Trim();//Response.Write("");Response.Redirect("student/StudentChose.aspx");}else//如果沒有通過驗證,彈出提示後定位到登錄界面{Response.Write("");}}if(this.ddlstatus.SelectedValue=="教師")//如果是教師登錄,則調用BaseClass中的CheckTeacher方法進行檢驗{//將用戶輸入的密碼加密後與資料庫中的值進行比較stringuser=txtNum.Text.Trim();stringpwd=BaseClass.md5(txtPwd.Text.Trim());if(BaseClass.CheckTeacher(user,pwd))//如果通過驗證,保存相關記錄值後將頁面跳轉到教師管理主界面{Session["Teacher"]=txtNum.Text;Response.Redirect("Teacher/TeacherManage.aspx");}else//如果沒有通過驗證,彈出提示後定位到登錄界面{Response.Write("");}}}}}catch(Exceptionex){MessageBox.Show("不好意思,系統出錯了,原因可能是:"+ex.Message);}}protectedvoidimgExit_Click(objectsender,ImageClickEventArgse){Response.Write("");}protectedvoidlkbtnAdminLogin_Click(objectsender,EventArgse){Response.Redirect("Admin/AdminLogin.aspx");//如果是管理員,則進入管理員登錄界面}}
『陸』 vue-resource 怎麼解決跨域問題
上一篇我們介紹了如何使用vue resource處理請求,結合服務端的REST API,就能夠很容易地構建一個增刪查改應用。
這個應用始終遺留了一個問題,Web App在訪問REST API時,沒有經過任何認證,這使得服務端的REST API是不安全的,只要有人知道api地址,就可以調用API對服務端的資源進行修改和刪除。
今天我們就來探討一下如何結合Web API來限制資源的訪問。
本文的主要內容如下:
介紹傳統的Web應用和基於REST服務的Web應用
介紹OAuth認證流程和密碼模式
創建一個基於ASP. Identity的Web API應用程序
基於$.ajax實現OAuth的注冊、登錄、注銷和API調用
基於vue-resource實現OAuth的注冊、登錄、注銷和API調用
本文的最終示例是結合上一篇的CURD,本文的登錄、注冊、注銷和API調用功能實現的。
35
本文9個示例的源碼已放到GitHub,如果您覺得本篇內容不錯,請點個贊,或在GitHub上加個星星!
Page Demo GitHub Source
基於$.ajax的示例如下:
注冊示例 登錄和注銷示例 登錄獲取token並調用API示例 注冊、登錄、注銷、調用API綜合示例
基於vue-resource的示例如下:
注冊示例 登錄和注銷示例 登錄獲取token並調用API示例 注冊、登錄、注銷、調用API綜合示例
OAuth介紹
傳統的Web應用
在傳統的Web應用程序中,前後端是放在一個站點下的,我們可以通過會話(Session)來保存用戶的信息。
例如:一個簡單的ASP. MVC應用程序,用戶登錄成功後,我們將用戶的ID記錄在Session中,假設為Session["UserID"]。
前端發送ajax請求時,如果這個請求要求已登錄的用戶才能訪問,我們只需在後台Controller中驗證Session["UserID"]是否為空,就可以判斷用戶是否已經登錄了。
這也是傳統的Web應用能夠逃避面向無連接的方法。
基於REST服務的Web應用
當今很多應用,客戶端和服務端是分離的,服務端是基於REST風格構建的一套Service,客戶端是第三方的Web應用,客戶端通過跨域的ajax請求獲取REST服務的資源。
然而REST Service通常是被設計為無狀態的(Stateless),這意味著我們不能依賴於Session來保存用戶信息,也不能使用Session["UserID"]這種方式確定用戶身份。
解決這個問題的方法是什麼呢?常規的方法是使用OAuth 2.0。
對於用戶相關的OpenAPI,為了保護用戶數據的安全和隱私,第三方Web應用訪問用戶數據前都需要顯式的向用戶徵求授權。
相比於OAuth 1.0,OAuth 2.0的認證流程更加簡單。
專用名詞介紹
在了解OAuth 2.0之前,我們先了解幾個名詞:
Resource:資源,和REST中的資源概念一致,有些資源是訪問受保護的
Resource Server:存放資源的伺服器
Resource Owner:資源所有者,本文中又稱為用戶(user)
User Agent:用戶代理,即瀏覽器
Client: 訪問資源的客戶端,也就是應用程序
Authorization Server:認證伺服器,用於給Client提供訪問令牌的伺服器
Access Token:訪問資源的令牌,由Authorization Server器授予,Client訪問Resource時,需提供Access Token
Bearer Token:Bearer Token是Access Token的一種,另一種是Mac Token。
Bearer Token的使用格式為:Bearer XXXXXXXX
Token的類型請參考:s://tools.ietf/html/draft-ietf-oauth-v2-15#section-7.1
有時候認證伺服器和資源伺服器可以是一台伺服器,本文中的Web API示例正是這種運用場景。
OAuth認證流程
在知道這幾個詞以後,我們用這幾個名詞來編個故事。
簡化版本
這個故事的簡化版本是:用戶(Resource Owner)訪問資源(Resource)。
image
具體版本
簡化版的故事只有一個結果,下面是這個故事的具體版本:
用戶通過瀏覽器打開客戶端後,客戶端要求用戶給予授權。
客戶端可以直接將授權請求發給用戶(如圖所示),或者發送給一個中間媒介,比如認證伺服器。
用戶同意給予客戶端授權,客戶端收到用戶的授權。
授權模式(Grant Type)取決於客戶端使用的模式,以及認證伺服器所支持的模式。
客戶端提供身份信息,然後向認證伺服器發送請求,申請訪問令牌
認證伺服器驗證客戶端提供的身份信息,如果驗證通過,則向客戶端發放令牌
客戶端使用訪問令牌,向資源伺服器請求受保護的資源
資源伺服器驗證訪問令牌,如果有效,則向客戶端開放資源
image
以上幾個步驟,(B)是較為關鍵的一個,即用戶怎麼樣才能給客戶端授權。有了這個授權以後,客戶端就可以獲取令牌,進而通過臨牌獲取資源。這也是OAuth 2.0的運行流程,詳情請參考:s://tools.ietf/html/draft-ietf-oauth-v2-15#section-1.2
客戶端的授權模式
客戶端必須得到用戶的授權(authorization grant),才能獲得令牌(access token)。
OAuth 2.0定義了四種授權方式:
授權碼模式(authorization code)
簡化模式(implicit)
密碼模式(resource owner password credentials)
客戶端模式(client credentials)
本文的示例是基於密碼模式的,我就只簡單介紹這種模式,其他3我就不介紹了,大家有興趣可以看阮大的文章:
://http://www.yingtaow.com/sitemap.html?blog/2014/05/oauth_2_0.html
密碼模式
密碼模式(Resource Owner Password Credentials Grant)中,用戶向客戶端提供自己的用戶名和密碼。客戶端使用這些信息,向服務端申請授權。
在這種模式中,用戶必須把自己的密碼給客戶端,但是客戶端不得儲存密碼。這通常用在用戶對客戶端高度信任的情況下,比如客戶端是操作系統的一部分,或者由一個著名公司出品。
image
密碼嘛事的執行步驟如下:
(A)用戶向客戶端提供用戶名和密碼。
(B)客戶端將用戶名和密碼發給認證伺服器,向後者請求令牌。
(C)認證伺服器確認無誤後,向客戶端提供訪問令牌。
(B)步驟中,客戶端發出的請求,包含以下參數:
grant_type:表示授權類型,此處的值固定為"password",必選項。
username:表示用戶名,必選項。
password:表示用戶的密碼,必選項。
scope:表示許可權范圍,可選項。
注意:在後面的客戶端示例中,除了提供username和password,grant_type也是必須指定為"password",否則無法獲取服務端的授權。
服務端環境准備
如果您是前端開發人員,並且未接觸過ASP. Web API,可以跳過此段落。
image
Authentication選擇Indivial User Accounts
image
創建這個Web API工程時,VS會自動引入Owin和Asp.Identity相關的庫。
image
修改ValuesController,除了IEnumerable<string> Get()操作外,其他操作都刪除,並為該操作應用[Authorize]特性,這表示客戶端必須通過身份驗證後才能調用該操作。
public class ValuesController : ApiController
{
// GET: api/Values
[Authorize]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
}
添加Model, Controller
image
image
image
初始化資料庫
image
執行以下3個命令
image
image
執行以下SQL語句:
顯示代碼
CustomersController類有5個Action,除了2個GET請求外,其他3個請求分別是POST, PUT和DELETE。
為這3個請求添加[Authorize]特性,這3個請求必須通過身份驗證才能訪問。
隱藏代碼
public class CustomersController : ApiController
{
private ApplicationDbContext db = new ApplicationDbContext();
// GET: api/Customers
public IQueryable<Customer> GetCustomers()
{
return db.Customers;
}
// GET: api/Customers/5
[ResponseType(typeof(Customer))]
public async Task<IActionResult> GetCustomer(int id)
{
Customer customer = await db.Customers.FindAsync(id);
if (customer == null)
{
return NotFound();
}
return Ok(customer);
}
// PUT: api/Customers/5
[Authorize]
[ResponseType(typeof(void))]
public async Task<IActionResult> PutCustomer(int id, Customer customer)
{
// ...
}
// POST: api/Customers
[Authorize]
[ResponseType(typeof(Customer))]
public async Task<IActionResult> PostCustomer(Customer customer)
{
// ...
}
// DELETE: api/Customers/5
[ResponseType(typeof(Customer))]
[Authorize]
public async Task<IActionResult> DeleteCustomer(int id)
{
// ...
}
}
讓Web API以CamelCase輸出JSON
在Global.asax文件中添加以下幾行代碼:
var formatters = GlobalConfiguration.Configuration.Formatters;
var jsonFormatter = formatters.JsonFormatter;
var settings = jsonFormatter.SerializerSettings;
settings.Formatting = Formatting.Indented;
settings.ContractResolver = new ();
啟用CORS
在Nuget Package Manager Console輸入以下命令:
Install-Package Microsoft.Asp.WebApi.Cors
在WebApiConfig中啟用CORS:
public static class WebApiConfig
{
public static void Register(Configuration config)
{
var cors = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(cors);
// ...
}
}
類說明
在執行上述步驟時,VS已經幫我們生成好了一些類
image
IdentityModels.cs:包含ApplicationDbContext類和ApplicationUser類,無需再創建DbContext類
public class ApplicationUser : IdentityUser
{
// ...
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
// ...
}
Startup.Auth.cs:用於配置OAuth的一些屬性。
public partial class Startup
{
public static OAuthOptions { get; private set; }
public static string PublicClientId { get; private set; }
// For more information on configuring authentication, please visit ://go.microsoft./fwlink/?LinkId=301864
public void ConfigureAuth(IAppBuilder app)
{
// ..
// Configure the application for OAuth based flow
PublicClientId = "self";
OAuthOptions = new
{
TokenEndpointPath = new PathString("/Token"),
Provider = new ApplicationOAuthProvider(PublicClientId),
AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
// In proction mode set AllowInsecure = false
AllowInsecure = true
};
// Enable the application to use bearer tokens to authenticate users
app.UseOAuthBearerTokens(OAuthOptions);
// ..
}
}
這些OAuth配置項,我們只用關注其中的兩項:
TokenEndpointPath:表示客戶端發送驗證請求的地址,例如:Web API的站點為www.example.,驗證請求的地址則為www.example./token。
UseOAuthBearerTokens:使用Bearer類型的token_type(令牌類型)。
ApplicationOAuthProvider.cs:默認的OAuthProvider實現,GrantResourceOwnerCredentials方法用於驗證用戶身份信息,並返回access_token(訪問令牌)。
public override async Task GrantResourceOwnerCredentials( context)
{
// ...
}
通俗地講,客戶端輸入用戶名、密碼,點擊登錄後,會發起請求到www.example./token。
token這個請求在服務端執行的驗證方法是什麼呢?正是GrantResourceOwnerCredentials方法。
客戶端發起驗證請求時,必然是跨域的,token這個請求不屬於任何ApiController的Action,而在WebApiConfig.cs中啟用全局的CORS,只對ApiController有效,對token請求是不起作用的。
所以還需要在GrantResourceOwnerCredentials方法中添加一行代碼:
public override async Task GrantResourceOwnerCredentials( context)
{
context.Response.Headers.Add("Access-Control-Allow-Origin", new []{"*"});
// ...
}
IdentityConfig.cs:配置用戶名和密碼的復雜度,主要用於用戶注冊時。例如:不允許用戶名為純字母和數字的組合,密碼長度至少為6位…。
隱藏代碼
public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
{
var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));
// Configure validation logic for usernames
manager.UserValidator = new UserValidator<ApplicationUser>(manager)
{
= false,
RequireUniqueEmail = true
};
// Configure validation logic for passwords
manager.PasswordValidator = new PasswordValidator
{
RequiredLength = 6,
RequireNonLetterOrDigit = true,
RequireDigit = true,
RequireLowercase = true,
RequireUppercase = true,
};
// ...
return manager;
}
使用Postman測試GET和POST請求
測試GET請求
image
GET請求測試成功,可以獲取到JSON數據。
測試POST請求
image
POST請求測試不通過,提示:驗證不通過,請求被拒絕。
基於$.ajax實現注冊、登錄、注銷和API調用
服務端的環境已經准備好了,現在我們就逐個實現用戶注冊、登錄,以及API調用功能吧。
注冊
頁面的HTML代碼如下:
<div id="app">
<div class="container">
<span id="message">{{ msg }}</span>
</div>
<div class="container">
<div class="form-group">
<label>電子郵箱</label>
<input type="text" v-model="registerModel.email" />
</div>
<div class="form-group">
<label>密碼</label>
<input type="text" v-model="registerModel.password" />
</div>
<div class="form-group">
<label>確認密碼</label>
<input type="text" v-model="registerModel.confirmPassword" />
</div>
<div class="form-group">
<label></label>
<button @click="register">注冊</button>
</div>
</div>
</div>
創建Vue實例,然後基於$.ajax發送用戶注冊請求:
var demo = new Vue({
el: '#app',
data: {
registerUrl: '://localhost:10648/api/Account/Register',
registerModel: {
email: '',
password: '',
confirmPassword: ''
},
msg: ''
},
methods: {
register: function() {
var vm = this
vm.msg = ''
$.ajax({
url: vm.registerUrl,
type: 'POST',
dataType: 'json',
data: vm.registerModel,
success: function() {
vm.msg = '注冊成功!'
},
error: vm.requestError
})
},
requestError: function(xhr, errorType, error) {
『柒』 c# webapi Session
沒使用過,
既然你的程序被設計為 webapi,或者SOA架構,你應該拋棄這種設計,讓第三方庫 緩存 或者 本地緩存 做為驗證保存。如果是設計為分布式,你需要一個中央緩存管理這些信息,
『捌』 ashx什麼時候執行 processrequest
ASP.NET中HttpApplication中ProcessRequest方法中執行的事件順序
1.BeginRequest 開始處理請求
2.AuthenticateRequest 授權驗證請求,獲取用戶授權信息
3.PostAuthenticateRequest 獲取成功
4.AunthorizeRequest 授權,一般來檢查用戶是否獲得許可權
5.PostAuthorizeRequest 獲得授權
6.ResolveRequestCache 獲取頁面緩存結果(如果沒有則執行)
7.PostResolveRequestCache 已獲取緩存
8.PostMapRequestHandler 創建頁面對象
9.AcquireRequestState 獲取Session -- 先判斷當前頁面對象是否實現了IRequiresSessionState介面,如果實現了,則從瀏覽器發來的請求報文頭中獲得SessionId,並到伺服器的 Session池中獲得對應的Session對象,最後賦值給 HttpContext的Session屬性。
10.PostAcquireRequestState 獲得Session
11.PreRequestHandlerExecute 准備執行頁面對象
×執行頁面對象的ProcessRequest方法(1.ashx,1.aspx),如果請求的是1.aspx,則會運行頁面生命周期
12.PostRequestHandlerExecute 執行完頁面對象了
13.ReleaseRequestState 釋放請求狀態
14.PostReleaseRequestState 已釋放請求狀態
15.UpdateReuqestCache 更新緩存
16.PostUpdateRequestCache 已更新緩存
17.LogRequest 日誌記錄
18.PostLogRequest 已完成日誌
19.EndRequest 完成
可以再Global.asax中添加以Application_為前綴+事件名 的方法運行測試!例如:
[csharp] view plain
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
public void Application_BeginRequest(object sender, EventArgs e)
{
HttpApplication obj = sender as HttpApplication;
obj.Context.Response.Write("1 Application_BeginRequest<br/>");
}
public void Application_ResolveRequestCache(object sender, EventArgs e)
{
HttpApplication obj = sender as HttpApplication;
obj.Context.Response.Write("6 Application_ResolveRequestCache<br/>");
}
public void Application_PostResolveRequestCache(object sender, EventArgs e)
{
HttpApplication obj = sender as HttpApplication;
obj.Context.Response.Write("7 Application_PostResolveRequestCache<br/>");
}
public void Application_PreRequestHandlerExecute(object sender, EventArgs e)
{
HttpApplication obj = sender as HttpApplication;
obj.Context.Response.Write("11 Application_PreRequestHandlerExecute<br/>");
}
}
以下附上MVC整體請求流程圖,來自傳智播客黑馬培訓班
ASP.net WebForm整體請求流程圖,來自傳智播客黑馬培訓班