2015-06-18 38 views
10

Xin chào vì vậy tôi đã cố gắng đạt được WS-Fed SSO trên ứng dụng web MVC6 của tôi, tôi đã đọc một chút về xác thực và tất cả để xác định yêu cầu. Tôi phải sử dụng WsFederationAuth để không có giao thức oauth cũng như saml nào có hiệu quả đối với tôi.WS-Federation đăng nhập Asp.NET 5 MVC 6 ADFS

Edit: Sau @Pinpoint gợi ý tôi cố gắng sử dụng owin middleware để đạt được các kết nối, nhưng tôi sẽ sử dụng DNX451 khuôn khổ đầy đủ chứ không phải DNXCore nhưng nó là cái gì trong khi chờ đợi ws-fed được hỗ trợ bởi vNext.

Pinpointadapter extension:

public static class AppBuilderExtensions 
    { 
#if !DNXCORE50 
     public static IApplicationBuilder UseOwinAppBuilder(this IApplicationBuilder app, 
      Action<IAppBuilder> configuration) 
     { 
      if (app == null) 
      { 
       throw new ArgumentNullException(nameof(app)); 
      } 

      if (configuration == null) 
      { 
       throw new ArgumentNullException(nameof(configuration)); 
      } 


      return app.UseOwin(setup => setup(next => 
      { 
       var builder = new AppBuilder(); 
       var lifetime = (IApplicationLifetime) app.ApplicationServices.GetService(typeof (IApplicationLifetime)); 

       var properties = new AppProperties(builder.Properties); 
       properties.AppName = app.ApplicationServices.GetApplicationUniqueIdentifier(); 
       properties.OnAppDisposing = lifetime.ApplicationStopping; 
       properties.DefaultApp = next; 

       configuration(builder); 

       return builder.Build<Func<IDictionary<string, object>, Task>>(); 
      })); 
     } 
#endif 
    } 

Và trong startup.cs:

#if !DNXCORE50 
      app.UseOwinAppBuilder(owin => 
      { 
       owin.UseWsFederationAuthentication(new WsFederationAuthenticationOptions 
       { 
        MetadataAddress = 
         "https://mysite.accesscontrol.windows.net/FederationMetadata/2007-06/FederationMetadata.xml", 
        Wtrealm = "http://localhost:62569/", 
        SignInAsAuthenticationType = WsFederationAuthenticationDefaults.AuthenticationType, 
        AuthenticationType = "adfs", 
        SecurityTokenHandlers = new SecurityTokenHandlerCollection 
        { 
         new EncryptedSecurityTokenHandler 
         { 
          Configuration = new SecurityTokenHandlerConfiguration 
          { 
           IssuerTokenResolver = new X509CertificateStoreTokenResolver(StoreName.My, 
            StoreLocation.LocalMachine) 
          } 
         }, 
         new Saml2SecurityTokenHandler 
         { 
          CertificateValidator = X509CertificateValidator.None, 

         } 
        } 
       }); 
      }); 
#endif 

tôi có thể cảm thấy tôi đang tiến gần hơn đến một giải pháp nhưng nó vẫn chưa thực hiện. Tôi gặp khó khăn trong việc xử lý các dấu hiệu (sau khi xác thực chống lại ADFS)

tôi nhận được lỗi này với afaiu token:

SecurityTokenValidationException: IDX10201: Không có các SecurityTokenHandlers thể đọc 'thẻ bảo mật':

<Assertion ID="_851fc402-2e9c-4ff8-a743-7d65612255b9" IssueInstant="2015-06-22T16:16:03.852Z" Version="2.0" xmlns="urn:oasis:names:tc:SAML:2.0:assertion"> 
    <Issuer>https://mysite.accesscontrol.windows.net/</Issuer> 
    <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> 
     <ds:SignedInfo> 
      <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /> 
      <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" /> 
      <ds:Reference URI="#_851fc402-2e9c-4ff8-a743-7d65612255b9"> 
       <ds:Transforms> 
        <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /> 
        <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /> 
       </ds:Transforms> 
       <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" /> 
       <ds:DigestValue>xZdzOnNIG5Ia***********t0feMWIZMLnY=</ds:DigestValue> 
      </ds:Reference> 
     </ds:SignedInfo> 
     <ds:SignatureValue>KmuScnZBdxyaAJrfLgB9AYheUdR*****************************Xs4o8R+eMCPdWNsDjhLu500UlCgitYerjpLTTyRRdwvFo8T7LlsXO2yjv3dx83Yn+GthE+FswNRH07yIHF5wo5+/TAwiVzg+9SDbK+Nj84PdLMxwIfALAebf4/ECdpqkWvt2ligzFoQckEgZMRepOcAVfBxfELyJSUDAjnpfJCrlCQip0nykC+5R37X00flIlB563p48veeLIt0JaUdG4bwtQ8OCMg1KeD5gYix9p4E3TQ7QovN0HDoWTurLK/0H01IS73fIe6/k6DBA==</ds:SignatureValue> 
     <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"> 
      <X509Data> 
       <X509Certificate>MIIDSjCCAjagAwIBAgIQrcBhMtovuJ**********************MDExLzAtBgNVBAMTJm1hcmdvY29uc2VpbC5hY2Nlc3Njb250cm9sLndpbmRvd3MubmV0MB4XDTE1MDYxNjA4MTYzOFoXDTIwMDUzMTIyMDAwMFowMTEvMC0GA1UEAxMmbWFyZ29jb25zZWlsLmFjY2Vzc2NvbnRyb2wud2luZG93cy5uZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCpeZseXX1IYTABUOPr7nfIAXc7cXAI0k+vR3qEbvy0UxEhYAkAocQR2qUTPQ8D1v4lPp59tnHKBGJ0eHt9DYm/SyKkfHsWfqsysZx5NHXSJIhy/SgHwpd8b2q1NKxqBRLrdJKyAua+WWza4p/HMFjEVoN/upZtngSqxUKO/oYqy6m7smkz8vwjzpJR8tyqN881XBQzvryiF/i3ZPFQqlCT9263TMcAGPpym9uvxHzFPPx3u8IDz3AQydyHeViaJhiXGic0VEcm6LMn3JLOYqAzJnv8z89NdpsL4ynv1ekytt/8yyza3CnsU1E4tFDj1HU3785aFZ1xm6wr1MUK9VOTAgMBAAGjZjBkMGIGA1UdAQRbMFmAEN1alzwM3lJSHdh4LFl7uxmhMzAxMS8wLQYDVQQDEyZtYXJnb2NvbnNlaWwuYWNjZXNzY29udHJvbC53aW5kb3dzLm5ldIIQrcBhMtovuJ9MilbEjMjS7TAJBgUrDgMCHQUAA4IBAQAsQ5jNKvS2fLtqs9oB6DGTXdI5nAli5UyvZUQlnfnMvgYjJKrZu79iMe9iu88cmtwZVifG14SRbVdTjUOzngIWAJ5KAQk5t//wSkwgAS+U6AFYI/mee9NLEvOEhrRbpGUP0oL504OZ9zTDeXmGu2FybRB2TvdTKLaeVsBvwqgP33QFkcuPK50fCGC1l3SecIeyWL5fsiw/2+GuTKHjCaeRqnYBgDTINptc9PGayLPBTjs4UPzbccmaYyuanmTAMZGU0iRoGJYet2uAasT52QvWZqD0NUZbWyR1N8CBf5EIW2S/TrpoOBYNgZQU5n9PRJjTBhESHXjfa8RipC8RXU9o</X509Certificate> 
      </X509Data> 
     </KeyInfo> 
    </ds:Signature> 
    <Subject> 
     <NameID>***********</NameID> 
     <SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer" /> 
    </Subject> 
    <Conditions NotBefore="2015-06-22T16:16:03.836Z" NotOnOrAfter="2015-06-22T17:16:03.836Z"> 
     <AudienceRestriction> 
      <Audience>http://localhost:62569/</Audience> 
     </AudienceRestriction> 
    </Conditions> 
    <AttributeStatement> 
     <Attribute Name="http://schemas.microsoft.com/identity/claims/tenantid"> 
      <AttributeValue>********************</AttributeValue> 
     </Attribute> 
     <Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"> 
      <AttributeValue>************</AttributeValue> 
     </Attribute> 
     <Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname"> 
      <AttributeValue>G****l</AttributeValue> 
     </Attribute> 
     <Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname"> 
      <AttributeValue>L****s</AttributeValue> 
     </Attribute> 
     <Attribute Name="http://schemas.microsoft.com/identity/claims/identityprovider"> 
      <AttributeValue>https://sts.windows.net/7102feaa-34af-4756-85ce-b0f69766d78d/</AttributeValue> 
     </Attribute> 
     <Attribute Name="http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider"> 
      <AttributeValue>https://sts.windows.net/7102feaa-34af-4756-85ce-b0f69766d78d/</AttributeValue> 
     </Attribute> 
    </AttributeStatement> 
    <AuthnStatement AuthnInstant="2015-06-22T14:26:14.020Z"> 
     <AuthnContext> 
      <AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</AuthnContextClassRef> 
     </AuthnContext> 
    </AuthnStatement> 
</Assertion> 

Trả lời

3

Như bạn đã tìm ra, các middleware WS-Federation chưa được chuyển đến ASP.NET 5, nhưng đừng hoảng sợ, nó chắc chắn sẽ là: https://twitter.com/blowdart/status/610526268908535808Trong thời gian chờ đợi, bạn có thể sử dụng phần mềm trung gian OWIN/Katana 3 WS-Federation trong ứng dụng ASP.NET 5 với bộ chuyển đổi nhỏ IAppBuilder/IApplicationBuilder (như thế này: https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/blob/vNext/samples/Mvc/Mvc.Server/Extensions/AppBuilderExtensions.cs#L50), nhưng tất nhiên, nó sẽ không tương thích với dnxcore50.

Nếu bạn có phiên bản ADFS gần đây, bạn cũng có thể xem xét chuyển sang OAuth2.

+1

Trong trường hợp này, sẽ ADFS là nhà cung cấp danh tính? –

+0

Đúng, mặc dù "nhà cung cấp danh tính" thay vì một thuật ngữ OpenID Connect, không được ADFS hỗ trợ (không giống như đối tác đám mây của nó: AAD). "máy chủ ủy quyền" sẽ là tên chính xác trong trường hợp này. – Pinpoint

+0

Cảm ơn LOT cho @Pinpoint này, tôi sẽ xem xét thứ hai đó (tôi là một thực tập viên rất năng động nhưng có giới hạn cho động lực của tôi: D). Tôi chắc chắn muốn sử dụng OAuth2, nhưng ông chủ của tôi không muốn thực hiện bất kỳ thay đổi nào trên phần ADFS, tôi phải thích nghi mọi thứ với phần hiện có, do đó sử dụng liên kết ws. Tôi đã cố gắng nói với anh ta rằng IMO ws-fed là công nghệ cũ và khi anh ta nhấn mạnh vào việc sử dụng .NET5 và tất cả những thứ mới để không hợp lý khi dính vào một công nghệ cũ chỉ cho một khía cạnh của dự án. Nhưng anh ấy chỉ nói với tôi rằng tôi đã lười biếng và chỉ muốn làm một cách giải quyết ... – Lomithrani

1

Tôi đã tìm hiểu cách nhận được yêu cầu từ yêu cầu http quay lại từ ADFS bằng cách sử dụng các lớp ASP.NET trước theo cách không chạm vào web.config.

Hy vọng rằng mã này rất hữu ích với ai đó:

using Microsoft.AspNet.Http; 
using Microsoft.Extensions.Configuration; 
using System; 
using System.Collections.Specialized; 
using System.IdentityModel.Configuration; 
using System.IdentityModel.Protocols.WSTrust; 
using System.IdentityModel.Selectors; 
using System.IdentityModel.Services; 
using System.IdentityModel.Tokens; 
using System.IO; 
using System.Security.Claims; 
using System.Security.Cryptography.X509Certificates; 
using System.ServiceModel.Security; 
using System.Text; 
using System.Xml; 

public class FederationHelper 
{ 
    public ClaimsIdentity GetClaimsIdentityFromResponse(IConfigurationRoot configurationRoot, HttpContext context) 
    { 
     var absoluteUri = string.Concat(
        context.Request.Scheme, 
        "://", 
        context.Request.Host.ToUriComponent(), 
        context.Request.PathBase.ToUriComponent(), 
        context.Request.Path.ToUriComponent(), 
        context.Request.QueryString.ToUriComponent()); 

     var values = new NameValueCollection(); 

     foreach (var item in context.Request.Query) 
     { 
      values.Add(item.Key, item.Value); 
     } 

     foreach (var item in context.Request.Form) 
     { 
      values.Add(item.Key, item.Value); 
     } 

     var federation = new FederationSettings 
     { 
      AudienceUri = "http://contoso", 
      Endpoint = "http://sts/ls", 
      IssuerName = "http://sts/trust", 
      IssuerThumbprint = "[thumbprint]", 
      Realm = "https://myapp" 
     }; 

     var identityConfiguration = new IdentityConfiguration(false); 
     identityConfiguration.AudienceRestriction.AllowedAudienceUris.Add(new Uri(federation.AudienceUri)); 

     var issuers = new ConfigurationBasedIssuerNameRegistry(); 
     issuers.ConfiguredTrustedIssuers.Add(federation.IssuerThumbprint, federation.IssuerName); 
     identityConfiguration.IssuerNameRegistry = issuers; 

     var tokenHandler = new SamlSecurityTokenHandler(); 

     tokenHandler.Configuration = new SecurityTokenHandlerConfiguration(); 
     tokenHandler.Configuration.AudienceRestriction.AudienceMode = AudienceUriMode.Always; 
     tokenHandler.Configuration.AudienceRestriction.AllowedAudienceUris.Add(new Uri(federation.AudienceUri)); 
     tokenHandler.Configuration.IssuerNameRegistry = identityConfiguration.IssuerNameRegistry; 
     tokenHandler.Configuration.CertificateValidationMode = X509CertificateValidationMode.None; 
     tokenHandler.Configuration.RevocationMode = X509RevocationMode.NoCheck; 
     tokenHandler.Configuration.CertificateValidator = X509CertificateValidator.None; 

     var message = (SignInResponseMessage)WSFederationMessage.CreateFromNameValueCollection(new Uri(absoluteUri), values); 
     var token = CreateSecurityToken(tokenHandler, identityConfiguration, message); 
     var claims = tokenHandler.ValidateToken(token); 

     return claims[0]; 
    } 

    public SecurityToken CreateSecurityToken(SamlSecurityTokenHandler handler, IdentityConfiguration configuration, SignInResponseMessage message) 
    { 
     var quotas = new XmlDictionaryReaderQuotas(); 

     using (var reader = XmlDictionaryReader.CreateTextReader(Encoding.UTF8.GetBytes(message.Result), quotas)) 
     { 
      var serializer = new WSFederationSerializer(reader); 
      var context = new WSTrustSerializationContext(configuration.SecurityTokenHandlerCollectionManager); 

      var xml = serializer.CreateResponse(message, context).RequestedSecurityToken.SecurityTokenXml.OuterXml; 

      return ReadToken(handler, xml, quotas); 
     } 
    } 

    SecurityToken ReadToken(SamlSecurityTokenHandler handler, string xml, XmlDictionaryReaderQuotas quotas) 
    { 
     using (var reader = new StringReader(xml)) 
     { 
      using (var xmlReader = XmlReader.Create(reader)) 
      { 
       xmlReader.MoveToContent(); 

       return handler.ReadToken(xmlReader); 
      } 
     } 
    } 
} 
+0

Trông rất giống với những gì tôi đã làm cuối cùng từ những gì tôi nhớ @fiat bạn nên kiểm tra – Lomithrani

Các vấn đề liên quan