---恢復內容開始---瀏覽器
咱們簡單的描述怎麼經過owin和asp.net mvc建立一個受權服務器,首先建立一個空的MVC網站名爲AuthorizationServer而且安裝以下包:安全
在項目的根目錄建立一個名爲Startup的類:服務器
using Microsoft.Owin; using Owin; [assembly: OwinStartup(typeof(AuthorizationServer.Startup))] namespace AuthorizationServer { public partial class Startup { public void Configuration(IAppBuilder app) { ConfigureAuth(app); } } }
建立一個App_Start文件夾,選中App_Start添加類文件Startup.Auth.cscookie
public void ConfigureAuth(IAppBuilder app) { // 啓用登陸應用使用Cookie app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = "Application", AuthenticationMode = AuthenticationMode.Passive, LoginPath = new PathString(Paths.LoginPath), LogoutPath = new PathString(Paths.LogoutPath), }); // 啓用外部登陸使用Cookie app.SetDefaultSignInAsAuthenticationType("External"); app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = "External", AuthenticationMode = AuthenticationMode.Passive, CookieName = CookieAuthenticationDefaults.CookiePrefix + "External", ExpireTimeSpan = TimeSpan.FromMinutes(5), }); // 啓用google身份驗證 app.UseGoogleAuthentication(); // 配置受權服務 app.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions { AuthorizeEndpointPath = new PathString(Paths.AuthorizePath), TokenEndpointPath = new PathString(Paths.TokenPath), ApplicationCanDisplayErrors = true, #if DEBUG AllowInsecureHttp = true, #endif // 受權服務提供者控制受權服務的生命週期 Provider = new OAuthAuthorizationServerProvider { OnValidateClientRedirectUri = ValidateClientRedirectUri, OnValidateClientAuthentication = ValidateClientAuthentication, OnGrantResourceOwnerCredentials = GrantResourceOwnerCredentials, OnGrantClientCredentials = GrantClientCredetails }, // 受權碼提供者用來建立和接受受權碼 AuthorizationCodeProvider = new AuthenticationTokenProvider { OnCreate = CreateAuthenticationCode, OnReceive = ReceiveAuthenticationCode, }, // 刷新令牌提供這用來建立和接受令牌 RefreshTokenProvider = new AuthenticationTokenProvider { OnCreate = CreateRefreshToken, OnReceive = ReceiveRefreshToken, } }); }
上面的代碼啓用了應用/外部登錄使用Cookie而且可使用谷歌身份驗證,由受權服務器自己管理帳戶。架構
UseCookieAuthentication擴展方法是用來配置受權服務的,配置選項是:mvc
AuthorizeEndpointPath:客戶端應用程序登陸受權的請求地址,它必須之前導斜槓開始,例如:「/Authorize」app
TokenEndpointPath:客戶端應用程序直接得到訪問令牌的請求地址,它也一樣是之前導斜槓開始,例如:「/Token」asp.net
ApplicationCanDisplayErrors:若是Web應用程序想要在/Authorize地址爲客戶端驗證生成一個自定義的錯誤頁那麼設置爲true,瀏覽器不重定向到客戶端應用。例如當client_id或者redirect_uri是錯誤的,/Authorize可能但願看到「oauth.Error」、「oauth.ErrorDescription」和「oauth.ErrorUri」屬性被添加到Owin環境中。ide
AllowInsecureHttp:若是設置爲true,表明受權和令牌地址容許不安全的Http協議。網站
Provider:配置受權服務中間件處理認證和受權的事件。
AuthorizationCodeProvider:產生一個一次性使用的驗證碼給客戶端應用程序,OnCreate建立受權碼,OnReceive收到受權碼。
RefreshTokenProvider:產生一個刷新Token在須要的時候用來得到新的訪問Token。
Oauth不關心在哪兒或怎麼去管理你的帳號信息,它是有Asp.Net Indentity來負責的,在本教程咱們將簡化帳戶管理的代碼只確保用戶可使用Owin cookie中間件登陸,以下在AccountControl中的簡單代碼:
public class AccountController : Controller { public ActionResult Login() { var authentication = HttpContext.GetOwinContext().Authentication; if (Request.HttpMethod == "POST") { var isPersistent = !string.IsNullOrEmpty(Request.Form.Get("isPersistent")); if (!string.IsNullOrEmpty(Request.Form.Get("submit.Signin"))) { authentication.SignIn( new AuthenticationProperties { IsPersistent = isPersistent }, new ClaimsIdentity(new[] { new Claim( ClaimsIdentity.DefaultNameClaimType, Request.Form["username"]) }, "Application")); } } return View(); } public ActionResult Logout() { return View(); } public ActionResult External() { var authentication = HttpContext.GetOwinContext().Authentication; if (Request.HttpMethod == "POST") { foreach (var key in Request.Form.AllKeys) { if (key.StartsWith("submit.External.") && !string.IsNullOrEmpty(Request.Form.Get(key))) { var authType = key.Substring("submit.External.".Length); authentication.Challenge(authType); return new HttpUnauthorizedResult(); } } } var identity = authentication.AuthenticateAsync("External").Result.Identity; if (identity != null) { authentication.SignOut("External"); authentication.SignIn( new AuthenticationProperties { IsPersistent = true }, new ClaimsIdentity(identity.Claims, "Application", identity.NameClaimType, identity.RoleClaimType)); return Redirect(Request.QueryString["ReturnUrl"]); } return View(); } }
private Task ValidateClientRedirectUri(OAuthValidateClientRedirectUriContext context) { if (context.ClientId == Clients.Client1.Id) { context.Validated(Clients.Client1.RedirectUrl); } else if (context.ClientId == Clients.Client2.Id) { context.Validated(Clients.Client2.RedirectUrl); } return Task.FromResult(0); } private Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context) { string clientId; string clientSecret; if (context.TryGetBasicCredentials(out clientId, out clientSecret) || context.TryGetFormCredentials(out clientId, out clientSecret)) { if (clientId == Clients.Client1.Id && clientSecret == Clients.Client1.Secret) { context.Validated(); } else if (clientId == Clients.Client2.Id && clientSecret == Clients.Client2.Secret) { context.Validated(); } } return Task.FromResult(0); }
private Task ValidateClientRedirectUri(OAuthValidateClientRedirectUriContext context) { if (context.ClientId == Clients.Client1.Id) { context.Validated(Clients.Client1.RedirectUrl); } else if (context.ClientId == Clients.Client2.Id) { context.Validated(Clients.Client2.RedirectUrl); } return Task.FromResult(0); } private Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context) { string clientId; string clientSecret; if (context.TryGetBasicCredentials(out clientId, out clientSecret) || context.TryGetFormCredentials(out clientId, out clientSecret)) { if (clientId == Clients.Client1.Id && clientSecret == Clients.Client1.Secret) { context.Validated(); } else if (clientId == Clients.Client2.Id && clientSecret == Clients.Client2.Secret) { context.Validated(); } } return Task.FromResult(0); }
ValidateClientRedirectUri用於驗證被註冊的跳轉Url。ValidateClientAuthentication 驗證從Basic架構的請求頭或Form表單提交過來的客戶端憑證。