博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
基于OWIN WebAPI 使用OAUTH2授权服务【授权码模式(Authorization Code)】
阅读量:4325 次
发布时间:2019-06-06

本文共 7686 字,大约阅读时间需要 25 分钟。

之前已经简单实现了OAUTH2的
,但是基于JAVA的,今天花了点时间调试了OWIN的实现,基本就把基于OWIN的OAUHT2的四种模式实现完了。官方推荐的.NET 包有

现已经不更新了,新的版本是已经是asp.net core 1.0的,实现OAUTH2好的选择可以考虑使用新版对应asp.net core 1.0版本为IdentityServer4。

Startup

public partial class Startup    {        private readonly ConcurrentDictionary
_authenticationCodes = new ConcurrentDictionary
(StringComparer.Ordinal); public void ConfigureAuth(IAppBuilder app) { app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = Paths.AuthenticationType, AuthenticationMode = AuthenticationMode.Passive, LoginPath = new PathString(Paths.LoginPath), LogoutPath = new PathString(Paths.LogoutPath), }); app.UseOAuthBearerTokens(new OAuthAuthorizationServerOptions { AuthorizeEndpointPath = new PathString(Paths.AuthorizePath), TokenEndpointPath = new PathString(Paths.TokenPath), AccessTokenExpireTimeSpan = TimeSpan.FromHours(2), Provider = new OAuthAuthorizationServerProvider { OnValidateClientRedirectUri = ValidateClientRedirectUri, OnValidateClientAuthentication = ValidateClientAuthentication, OnGrantResourceOwnerCredentials = GrantResourceOwnerCredentials, OnGrantClientCredentials = GrantClientCredetails }, //Provider = new ApplicationOAuthProvider(), AuthorizationCodeProvider = new AuthenticationTokenProvider { OnCreate = CreateAuthenticationCode, OnReceive = ReceiveAuthenticationCode, }, RefreshTokenProvider = new AuthenticationTokenProvider { OnCreate = CreateRefreshToken, OnReceive = ReceiveRefreshToken, }, ApplicationCanDisplayErrors = true,#if DEBUG //HTTPS is allowed only AllowInsecureHttp = false AllowInsecureHttp = true,#endif }); } private void CreateAuthenticationCode(AuthenticationTokenCreateContext context) { context.SetToken(Guid.NewGuid().ToString("n") + Guid.NewGuid().ToString("n")); _authenticationCodes[context.Token] = context.SerializeTicket(); } private void ReceiveAuthenticationCode(AuthenticationTokenReceiveContext context) { string value; if (_authenticationCodes.TryRemove(context.Token, out value)) { context.DeserializeTicket(value); } } private Task GrantClientCredetails(OAuthGrantClientCredentialsContext context) { var identity = new ClaimsIdentity(new GenericIdentity(context.ClientId, OAuthDefaults.AuthenticationType), context.Scope.Select(x => new Claim("urn:oauth:scope", x))); context.Validated(identity); return Task.FromResult(0); } private Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) { var identity = new ClaimsIdentity(new GenericIdentity(context.UserName, OAuthDefaults.AuthenticationType), context.Scope.Select(x => new Claim("urn:oauth:scope", x))); context.Validated(identity); 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)) { context.Validated(); } return Task.FromResult(0); } private Task ValidateClientRedirectUri(OAuthValidateClientRedirectUriContext context) { if (context.ClientId == Clients.Client1.Id) { context.Validated(); //context.Validated(Clients.Client1.RedirectUrl); } else if (context.ClientId == Clients.Client2.Id) { context.Validated(Clients.Client2.RedirectUrl); } return Task.FromResult(0); } private void CreateRefreshToken(AuthenticationTokenCreateContext context) { context.SetToken(context.SerializeTicket()); } private void ReceiveRefreshToken(AuthenticationTokenReceiveContext context) { context.DeserializeTicket(context.Token); } }

OAuthController

///         /// 授权码模式授权        ///         /// 
public ActionResult Authorize() { var authentication = HttpContext.GetOwinContext().Authentication; var ticket = authentication.AuthenticateAsync(Paths.AuthenticationType).Result; var identity = ticket != null ? ticket.Identity : null; if (identity == null) { authentication.Challenge(Paths.AuthenticationType); return new HttpUnauthorizedResult(); } var scopes = (Request.QueryString.Get("scope") ?? "").Split(' '); if (Request.HttpMethod == "POST") { if (!string.IsNullOrEmpty(Request.Form.Get("submit.Grant"))) { identity = new ClaimsIdentity(identity.Claims, "Bearer", identity.NameClaimType, identity.RoleClaimType); foreach (var scope in scopes) { identity.AddClaim(new Claim("urn:oauth:scope", scope)); } authentication.SignIn(identity); } if (!string.IsNullOrEmpty(Request.Form.Get("submit.Login"))) { authentication.SignOut("Application"); authentication.Challenge("Application"); return new HttpUnauthorizedResult(); } } return View(); }

AccountController

///         /// 用户登录        ///         /// 
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(); }

调试

获得授权码

GET /oauth/authorize?client_id=irving&redirect_uri=

%20notes&response_type=code HTTP/1.1

client_id=irving&redirect_uri=

页面重定向

HTTP/1.1 302 Found
Location: /oauth_callback?code=SplxlOBeZQQYbYS6WxSbIA&state=xyz

获得令牌
POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&code=929dc42905a24e79bdf028f7043769acddd90056ca8141708b3834ec174e8083&state=LYUVwcuaGuKeRTjxhdFzhQ&redirect_uri=http://localhost:38500/oauth_callback

源码:

注意事项

资源服务器识别认证服务器颁发的令牌, 需要配置相同的machinekey

REFER:

转载于:https://www.cnblogs.com/Irving/p/5220578.html

你可能感兴趣的文章
安装php扩展
查看>>
百度移动搜索主要有如下几类结果构成
查看>>
Python爬虫面试题170道:2019版【1】
查看>>
JavaBean规范
查看>>
第四阶段 15_Linux tomcat安装与配置
查看>>
NAS 创建大文件
查看>>
学习笔记-模块之xml文件处理
查看>>
接口测试用例
查看>>
面试:用 Java 实现一个 Singleton 模式
查看>>
Sybase IQ导出文件的几种方式
查看>>
案例:手动输入一个字符串,打散放进一个列表,小写字母反序 大写字母保持不变...
查看>>
PCRE demo【转】
查看>>
矩阵的SVD分解
查看>>
性能优化之数据库优化
查看>>
linux 系统下 tar 的压缩与解压缩命令
查看>>
阿里负载均衡,配置中间证书问题(在starcom申请免费DV ssl)
查看>>
转:How to force a wordbreaker to be used in Sharepoint Search
查看>>
MySQL存储过程定时任务
查看>>
Python中and(逻辑与)计算法则
查看>>
POJ 3267 The Cow Lexicon(动态规划)
查看>>