zoukankan      html  css  js  c++  java
  • Asp.Net MVC 4 Web API 中的安全认证-使用OAuth

    image

    各种语言实现的oauth认证: http://oauth.net/code/

    上一篇文章介绍了如何使用基本的http认证来实现asp.net web api的跨平台安全认证。 这里说明一个如何使用oauth实现的认证。oauth大家可能不陌生。那么这里需要注意的是我们使用的是.net平台一个比较好的开源oauth库。 DOTNETOPENAUTH。

    就像上图所示,我们需要一个ISSSUE Server来给我们一个token,然后再去资源服务器请求资源,也就是Web API Server。

    image

    首先在oAuthIssuer服务端我们需要实现一个DotNetOpenAuth的接口:IAuthorizationServer

    image

    对接口的实现:

    复制代码
    public class OAuth2Issuer : IAuthorizationServer
        {
            private readonly IssuerConfiguration _configuration;
    
            public OAuth2Issuer(IssuerConfiguration configuration)
            {
                if (configuration == null) throw new ArgumentNullException("configuration");
                _configuration = configuration;
            }
    
            public RSACryptoServiceProvider AccessTokenSigningKey
            {
                get
                {
                    return (RSACryptoServiceProvider)_configuration.SigningCertificate.PrivateKey;
                }
            }
    
            public DotNetOpenAuth.Messaging.Bindings.ICryptoKeyStore CryptoKeyStore
            {
                get { throw new NotImplementedException(); }
            }
    
            public TimeSpan GetAccessTokenLifetime(DotNetOpenAuth.OAuth2.Messages.IAccessTokenRequest accessTokenRequestMessage)
            {
                return _configuration.TokenLifetime;
            }
    
            public IClientDescription GetClient(string clientIdentifier)
            {
                const string secretPassword = "test1243";
                return new ClientDescription(secretPassword, new Uri("http://localhost/"), ClientType.Confidential);
            }
    
            public RSACryptoServiceProvider GetResourceServerEncryptionKey(DotNetOpenAuth.OAuth2.Messages.IAccessTokenRequest accessTokenRequestMessage)
            {
                return (RSACryptoServiceProvider)_configuration.EncryptionCertificate.PublicKey.Key;
    
            }
    
            public bool IsAuthorizationValid(DotNetOpenAuth.OAuth2.ChannelElements.IAuthorizationDescription authorization)
            {
                
                //claims added to the token
                authorization.Scope.Add("adminstrator");
                authorization.Scope.Add("poweruser");
                
                return true;
            }
    
            public bool IsResourceOwnerCredentialValid(string userName, string password)
            {
                return true;
            }
    
            public DotNetOpenAuth.Messaging.Bindings.INonceStore VerificationCodeNonceStore
            {
                get
                {
                    throw new NotImplementedException();
                }
            }
        }
    复制代码

    在 Web API Server端,我们需要使用Http Message Handler来获取httprequest信息;并进行是否有授权认证。

    复制代码
     public class OAuth2Handler : DelegatingHandler
        {
            private readonly ResourceServerConfiguration _configuration;
    
            public OAuth2Handler(ResourceServerConfiguration configuration)
            {
                if (configuration == null) throw new ArgumentNullException("configuration");
                _configuration = configuration;
            }
    
            protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
            {
                HttpContextBase httpContext;
                string userName;
                HashSet<string> scope;
    
                if (!request.TryGetHttpContext(out httpContext))
                    throw new InvalidOperationException("HttpContext must not be null.");
    
                var resourceServer = new ResourceServer(new StandardAccessTokenAnalyzer(
                                                            (RSACryptoServiceProvider)_configuration.IssuerSigningCertificate.PublicKey.Key,
                                                            (RSACryptoServiceProvider)_configuration.EncryptionVerificationCertificate.PrivateKey));
    
                var error = resourceServer.VerifyAccess(httpContext.Request, out userName, out scope);
    
                if (error != null)
                    return Task<HttpResponseMessage>.Factory.StartNew(error.ToHttpResponseMessage);
                
                var identity = new ClaimsIdentity(scope.Select(s => new Claim(s, s)));
                if (!string.IsNullOrEmpty(userName))
                    identity.Claims.Add(new Claim(ClaimTypes.Name, userName));
                
                httpContext.User = ClaimsPrincipal.CreateFromIdentity(identity);
                Thread.CurrentPrincipal = httpContext.User;
    
                return base.SendAsync(request, cancellationToken);
            }
    
        }
    复制代码

    这里的ResourceServerConfiguration 我们是使用加密证书的。

    image

    客户端调用代码:

    image

    调用API获取数据之前需要从IssueServer获取Token。

    GetAccessToken:

    image

    看一下Token信息:

    {"access_token":"gAAAAIoUBVBrZ5jAxe5XeTgnJ8mGwwKsCReknueg4gLGlDQ77lR1yPfxt0yNfWLCBT7hxnHjRjuEwDTJ3J1YAnqML4MIgQg8A2cz2bs0EnxvCMfKnayKEesRM-lxLTFbWMpSxe2Xvjm61IbaXjrMkYDRMnV4Do8-7132tiOLIv02WOGlJAEAAIAAAACJ8F3SsE6cTI1XsioW_xOxHeESDzG16y01Gxm3HikYFUC3XIdekpPw0yMB4tavPmUj-kRyC1halbUX7JKf-Dihm6Ou5mexe9lcYTr9or_kH7WcDN5ZCryUK3OaecvwwjQVr5o9XD2ZyZSNDCNhVRFc5ypvP85zZCBW1KJkP3OTCV4AkMN-ROvgI8jxutYdsLLN-YbB7Ot5iypzWWbW0QxiwOzMEqG9nVtPwnIWOUMOvW5KbiELELhgjap60mwHzGrHG4TtA4jrNy8S9zjixO_q-FrgpAuC06CkSH-R4w9yPCLLDc9m3UoAnknFjd4PUbWLxCvlBpEK2sg03ENa0EOKzc2O5fEic9P-BiYt6afMwTgLkJlGBBjmCBpGZMkfLTw","token_type":"bearer","expires_in":"300","scope":"http://localhost/ adminstrator poweruser"}

    image

    客户端调用:

    image

     代码:

    http://pan.baidu.com/s/1ntkMbCt

  • 相关阅读:
    kafka 启动停止
    kafka消息长度限制
    python给回调函数传参数
    Promise封装setTimeout
    Twisted 基础
    kafka-eagle
    go安装
    python asyncio
    ajv参数验证
    sequlizejs学习笔记整理
  • 原文地址:https://www.cnblogs.com/Alex80/p/4923820.html
Copyright © 2011-2022 走看看